Replace the nested spatial global convolution in fast_psf_accumulator_resolve with a reusable double-precision FFTW linear convolution on the CPU PSF backend.
- Add the private src/fast_psf_fftw.{c,h} module: zero-padded R2C/C2R plans, cached kernel spectrum and planar scratch, exact 1/(Pwidth*Pheight) and 1/N^2 normalization, (R,R) crop, and additive HDR output.
- Keep the previous nested loops as fast_psf_accumulator_resolve_spatial_reference for tests/benchmarks only; it is not a runtime fallback.
- Cache the circular row spans on FastPsfAccumulator and report one-time plan, kernel transform, scratch, and per-frame stage timings.
- Require fftw3_omp for CPU builds; HIP and dummy builds do not link FFTW.
- Namespace test/helper binaries by spacetime and build tag, and reject make test / psf-capture for non-CPU backends.
- Add tests/test_fast_psf_fftw.c (FFTW versus spatial), tests/benchmark_fast_psf_fftw.c, an FFTW CLI smoke check, and the 2026-09-25 benchmark record.
193 lines
7.2 KiB
Markdown
193 lines
7.2 KiB
Markdown
# Build guide
|
||
|
||
Run these commands from the repository root. The build uses GNU Make and
|
||
produces standalone executables under `build/Release/` or `build/Debug/`.
|
||
|
||
## Dependencies
|
||
|
||
The default CPU build needs:
|
||
|
||
- A C11 compiler and OpenMP runtime (for example, GCC with libgomp).
|
||
- GNU Make.
|
||
- libpng headers and library for PNG output.
|
||
- `pkg-config`, used to locate and link FFTW.
|
||
- FFTW 3 built with OpenMP, discovered through `pkg-config fftw3_omp`
|
||
(`sci-libs/fftw[openmp]` on Gentoo). This is required for the CPU fast-mode
|
||
fast convolution; HIP and dummy PSF builds do not link FFTW.
|
||
|
||
Optional dependencies are CFITSIO for HDR/FITS output, and HIP/ROCm with
|
||
`hipcc` and a compatible GPU for HIP PSF accumulation.
|
||
|
||
## CPU build
|
||
|
||
```sh
|
||
make -j
|
||
```
|
||
|
||
With no explicit `SPACETIME` setting, this builds both supported spacetimes:
|
||
|
||
| Executable | Spacetime |
|
||
| --- | --- |
|
||
| `build/Release/minkowski_sky` | Flat Minkowski spacetime |
|
||
| `build/Release/schwarzschild_sky` | Analytic Schwarzschild in ingoing Kerr–Schild coordinates |
|
||
|
||
To build only one:
|
||
|
||
```sh
|
||
make -j SPACETIME=minkowski backend
|
||
make -j SPACETIME=schwarzschild backend
|
||
```
|
||
|
||
Each executable contains one metric provider, selected at compile time.
|
||
`PSF_BACKEND=cpu` is the default. Release builds use `-O2 -DNDEBUG`; the
|
||
default compiler flags also include `-march=native`, targeting the build
|
||
machine's CPU. For a binary intended for other CPUs, override `CFLAGS`:
|
||
|
||
```sh
|
||
make -B -j CFLAGS='-std=c11 -pipe -Wall -Wextra -Wpedantic'
|
||
```
|
||
|
||
For a Debug build (`-O0 -g3`):
|
||
|
||
```sh
|
||
make -j BUILD_TYPE=Debug
|
||
```
|
||
|
||
Debug executables are placed in `build/Debug/`.
|
||
|
||
## Output formats
|
||
|
||
PNG is enabled by default. If libpng is unavailable, build with binary PPM
|
||
output instead and use a `.ppm` output filename:
|
||
|
||
```sh
|
||
make -B -j ENABLE_PNG=0
|
||
```
|
||
|
||
To enable the optional `--hdr-output` switch, install CFITSIO and `pkg-config`,
|
||
then build the desired spacetime with `ENABLE_HDR=1`:
|
||
|
||
```sh
|
||
make -j SPACETIME=schwarzschild ENABLE_HDR=1 backend
|
||
```
|
||
|
||
The executable keeps its usual name, `build/Release/schwarzschild_sky`.
|
||
`--hdr-output` writes a linear RGB FITS file alongside the ordinary
|
||
single-frame image; see [usage.md](usage.md#hdr-output). Use `ENABLE_HDR=0`
|
||
to rebuild without this feature.
|
||
|
||
## Optional HIP PSF acceleration
|
||
|
||
```sh
|
||
make -j PSF_BACKEND=hip SPACETIME=minkowski backend
|
||
make -j PSF_BACKEND=hip SPACETIME=schwarzschild backend
|
||
```
|
||
|
||
These produce `build/Release/minkowski_sky_hip` and
|
||
`build/Release/schwarzschild_sky_hip`, separately from the CPU executables.
|
||
`HIPCC` can override the default `hipcc` command. `ENABLE_HDR=1` can be combined
|
||
with either HIP build.
|
||
|
||
HIP accelerates cache-eligible PSF accumulation; ray tracing and catalog
|
||
mapping remain on the CPU. PSFs requiring direct evaluation retain the CPU
|
||
reference path with ordered HDR transfers. HIP initialization or execution
|
||
errors terminate the render instead of silently selecting the CPU backend.
|
||
|
||
HIP catalog mapping uses OpenMP producers (`OMP_NUM_THREADS`) with one private
|
||
16,384-event chunk per worker. A shared GPU sink owns one double HDR image and
|
||
PSF cache, plus two pinned upload slots protected by completion events. Each
|
||
PSF uses a group of 32 threads to visit adjacent pixels; weights, support and
|
||
HDR precision remain unchanged. CPU direct fallbacks exclude other submissions
|
||
through the complete download/evaluate/upload boundary.
|
||
|
||
Every batch contributes to the final HIP timings. Long submissions print
|
||
progress about every five seconds (completed counts cover reclaimed slots).
|
||
The producer summary reports **summed worker wall time** in generation and
|
||
submission/fallback, including lock/device waits in the latter; these overlapping
|
||
times must not be added to GPU timings or interpreted as process CPU time.
|
||
The two upload slots bound staging memory and allow CPU production ahead of GPU
|
||
completion; copies and kernels still execute in order on one stream.
|
||
|
||
### Diagnostic dummy PSF backend
|
||
|
||
To inspect production chunk geometry without starting HIP or allocating an HDR
|
||
framebuffer, build the diagnostic-only dummy backend:
|
||
|
||
```sh
|
||
make -j1 PSF_BACKEND=dummy SPACETIME=schwarzschild ENABLE_HDR=1 backend
|
||
OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE \
|
||
./build/Release/schwarzschild_sky_dummy --lens-map-input MAP.grlens \
|
||
--all-sky-catalog CATALOG_DIR --output PROTECTED_OR_UNUSED.png [normal PSF options]
|
||
```
|
||
|
||
The dummy executable requires an imported lens map and the PSF cache; it rejects
|
||
`--psf-direct`. It runs the real OpenMP triangle scheduling, catalog query,
|
||
inverse mapping, redshift/color/flux preparation, and cache/direct/min-Y
|
||
classification, but records chunk statistics instead of accumulating pixels.
|
||
`--output` and `--hdr-output` are accepted only for command parity: neither PNG
|
||
nor FITS is created or modified. Reports separate full 16,384-event chunks from
|
||
the final partial chunk of each worker and include event-producing triangle
|
||
counts, occupied 32-pixel center tiles, bounding-box diagonals, and successive
|
||
triangle-centroid jumps. This is a scheduling diagnostic, not a rendering or
|
||
backend-performance benchmark.
|
||
|
||
With both Minkowski binaries built using `ENABLE_HDR=1`,
|
||
`python3 tests/test_hip_renderer.py build/Release/minkowski_sky build/Release/minkowski_sky_hip`
|
||
runs small CPU/HIP fallback and min-Y comparisons sequentially. Each renderer
|
||
subprocess has a 30-second timeout.
|
||
|
||
For a bounded production-cache benchmark, build and then run **one process at
|
||
a time**, with a timeout:
|
||
|
||
```sh
|
||
make PSF_BACKEND=hip SPACETIME=minkowski hip-psf-bench
|
||
./build/Release/benchmark_hip_psf --help
|
||
OMP_NUM_THREADS=16 timeout --kill-after=5s 45s ./build/Release/benchmark_hip_psf 4096 16
|
||
```
|
||
|
||
Arguments are event count (default 4096, maximum 65536) and screen spread in
|
||
pixels (default 16, maximum 3840). The benchmark runs a serial CPU HDR reference
|
||
before HIP and checks double values. See the [bounded investigation and original
|
||
logs](benchmarks/hip_psf_2026-09-07.md); its speedups do not establish a full-sky
|
||
render time.
|
||
|
||
## Rebuilding and checks
|
||
|
||
Build type, spacetime, HDR, and PSF backend configurations have separate object
|
||
paths. Changes to flags such as `ENABLE_PNG`, `CC`, or `CFLAGS` require a forced
|
||
rebuild with `make -B` and the intended settings. `make clean` removes the
|
||
entire `build/` directory; keep rendered images and other retained output
|
||
under `output/`.
|
||
|
||
Inspect the available runtime options:
|
||
|
||
```sh
|
||
./build/Release/minkowski_sky --help
|
||
./build/Release/schwarzschild_sky --help
|
||
```
|
||
|
||
Run CPU regression checks:
|
||
|
||
```sh
|
||
make test
|
||
```
|
||
|
||
The CPU suite includes both coordinate-camera builders, CLI validation,
|
||
small PNG renders, and single-frame/movie lens-map agreement. The reference
|
||
image checks require Python 3 and CFITSIO. The original Schwarzschild HDR
|
||
fixture is retained with a float32 relative tolerance of `2^-23` (zero absolute
|
||
tolerance): replacing the specialized static tetrad with metric-based
|
||
orthonormalization changes four components by one ULP. The Minkowski fixture
|
||
still requires exact equality.
|
||
|
||
The HIP regression requires an actual compatible GPU. The Make target builds
|
||
the test executable; run it separately:
|
||
|
||
```sh
|
||
make PSF_BACKEND=hip SPACETIME=minkowski hip-psf-test
|
||
./build/Release/obj/minkowski/standard_sink1_hip/test_hip_psf
|
||
```
|
||
|
||
For rendering with real stellar data, continue with [README.md](README.md#prepare-the-stellar-catalog)
|
||
and the [rendering guide](usage.md).
|