Skip to content

Commit 3f3c861

Browse files
Jammy2211claude
andcommitted
fix: run the type-1 finufft transform on one thread so its products are reproducible
A multithreaded type-1 spread sums thread subgrids in a non-deterministic order, so two identical precision-operator / dirty-image builds differed in the last bits (13 bitwise-equality tests failed with OMP threads > 1; CI py3.13 red). These are one-off precomputations; one thread is ~0.9 s for 5.5M visibilities, still ~10x faster than nufftax, and the likelihood never uses this transform. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013C7Zd6ibK9J4V8CFEUzrJU
1 parent 157e210 commit 3f3c861

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

‎autoarray/operators/nufft_cpu.py‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,13 @@ def nufft2d1(
154154
on the centred mode grid (mode 0 at index `N // 2`), returned with shape
155155
`(..., n_modes[1], n_modes[0])` -- `nufftax`'s orientation, not `finufft`'s.
156156
157-
Runs `finufft.nufft2d1`, whose thread count is left to `finufft`: it uses OpenMP and honours
158-
`OMP_NUM_THREADS`, so pinning `OMP_NUM_THREADS=1` per process (e.g. one thread per Nautilus
159-
worker) pins this transform too. The one exception is a process forked from one that already
160-
ran finufft, which is pinned to one thread because libgomp deadlocks otherwise (see
161-
`_threads_kwargs`). Falls back to `nufftax` (with a one-time warning) when
162-
`finufft` is not importable.
157+
Runs `finufft.nufft2d1` on **one thread**. A multithreaded type-1 spread adds each thread's
158+
subgrid into the output in a non-deterministic order, so two identical calls can differ in
159+
the last bits; the products built from this transform (the dirty image and the NUFFT
160+
precision operator) are one-off precomputations that must be bitwise reproducible, and one
161+
thread is still ~10x faster than `nufftax` on the CPU (~0.9 s for 5.5M visibilities). It also
162+
keeps this transform out of the libgomp fork deadlock `_threads_kwargs` guards against.
163+
Falls back to `nufftax` (with a one-time warning) when `finufft` is not importable.
163164
164165
Parameters
165166
----------
@@ -191,7 +192,7 @@ def nufft2d1(
191192
tuple(int(n) for n in n_modes),
192193
eps=float(eps),
193194
isign=int(isign),
194-
**_threads_kwargs(),
195+
nthreads=1,
195196
)
196197

197198
return np.swapaxes(f, -1, -2)

0 commit comments

Comments
 (0)