Follow-up to #3093 / PR #3111.
The macos-3.14 CI abort on PR #3111 came from launching numba parallel=True kernels concurrently from multiple host threads: numba's default workqueue threading layer is not threadsafe and terminates the process. PR #3111 serialized the launches in _projections.py (try_numba_transform, transform_points) behind a module lock.
_vertical.py has the same pattern and was left out of that PR to keep it focused:
_interp_geoid_batch and _interp_geoid_2d are @njit(parallel=True).
_apply_vertical_shift_dask wraps _apply_vertical_shift_numpy in map_blocks, so dask's threaded scheduler can run two blocks at once, each launching _interp_geoid_2d concurrently.
geoid_height / geoid_height_raster are public and can be called from user threads directly.
Nothing in the test suite currently triggers this (the vertical-shift dask tests appear to run with few enough concurrent blocks to dodge the race), but it is the same abort waiting to happen. Same fix shape as PR #3111: a module-level lock around the kernel launches, plus a subprocess regression test with NUMBA_THREADING_LAYER=workqueue forced.
Follow-up to #3093 / PR #3111.
The macos-3.14 CI abort on PR #3111 came from launching numba
parallel=Truekernels concurrently from multiple host threads: numba's default workqueue threading layer is not threadsafe and terminates the process. PR #3111 serialized the launches in_projections.py(try_numba_transform,transform_points) behind a module lock._vertical.pyhas the same pattern and was left out of that PR to keep it focused:_interp_geoid_batchand_interp_geoid_2dare@njit(parallel=True)._apply_vertical_shift_daskwraps_apply_vertical_shift_numpyinmap_blocks, so dask's threaded scheduler can run two blocks at once, each launching_interp_geoid_2dconcurrently.geoid_height/geoid_height_rasterare public and can be called from user threads directly.Nothing in the test suite currently triggers this (the vertical-shift dask tests appear to run with few enough concurrent blocks to dodge the race), but it is the same abort waiting to happen. Same fix shape as PR #3111: a module-level lock around the kernel launches, plus a subprocess regression test with
NUMBA_THREADING_LAYER=workqueueforced.