Warn on non-atomic custom GPU merge over overlap - #3061
Merged
Conversation
brendancol
commented
Jun 9, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Warn on non-atomic custom GPU merge over overlap
Blockers
None.
Suggestions
None blocking. One thing worth weighing (see nits).
Nits (optional)
xrspatial/rasterize.py(~line 3181): the warning fires before thecupy is NoneImportError guard at ~line 3413. A caller with no CuPy who passes a callable merge plususe_cuda=Truegets the UserWarning first, then the ImportError. The ordering is harmless since the warning is true either way, but if you'd rather a missing-dependency caller only see the hard error, move the warn after the cupy check. Not a blocker.test_rasterize_gpu_callable_warn_3057.py(_overlap_warnings): the bareexcept Exception: passis intentional and documented (no GPU in CI), but it would also swallow a real regression where rasterize raised before the warn line. Thelen(matched) == 1assert still catches the "warning never fired" case, so coverage holds. Flagging only so it stays a conscious choice.
What looks good
- Warning sits in the single callable-merge branch, so it covers both cupy and dask+cupy without duplicated logic.
- The docstring warning names the deterministic built-in merges, so the user gets an actionable alternative.
- Tests check both directions: callable+GPU warns; CPU callable and built-in GPU merge stay silent. They run without a GPU by recording warnings manually.
- No behavior change to the existing GPU callable path; the existing rasterize suite stays green.
Checklist
- Algorithm matches reference: n/a (doc + warning only)
- All implemented backends consistent: unchanged
- NaN handling correct: unchanged
- Edge cases covered by tests: yes (CPU vs GPU, callable vs string)
- Dask chunk boundaries handled: unchanged; chunks path has a warning test
- No premature materialization: n/a
- Benchmark exists or not needed: not needed (no perf change)
- README feature matrix updated: not needed (no new function, no backend change)
- Docstrings present and accurate: yes
brendancol
commented
Jun 9, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
Follow-up review (after fixes)
Both nits from the first pass are addressed.
Resolved
- Warning now fires inside the
else(callable) branch after thecupy is NoneImportError check (xrspatial/rasterize.py~line 3420). A caller with no CuPy now gets only the ImportError, not a UserWarning they can't act on. Still covers both the cupy and dask+cupy paths sincegpu_merge_nameis resolved there for both. - The two GPU warning tests are gated with
@skip_no_cupy, matching the new ordering. The CPU "does not warn" test completes without a GPU, so it no longer relies on the broadexceptto pass. The remainingexcept Exceptiononly swallows the device-less kernel-launch error, and the exact-count asserts still fail loudly if the warning never fires.
Remaining
None. No blockers, no open suggestions.
Verification
- New file
test_rasterize_gpu_callable_warn_3057.py: 4 passed. test_rasterize.py: 215 passed, 2 skipped.- flake8 clean on both changed files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3057
The GPU backends only use CUDA atomics for the six built-in merges. A custom callable
mergefalls into the non-atomic read-modify-write path in_apply_merge_gpu, so overlapping geometries race and the overlap pixels are nondeterministic. The public docstring said nothing about this... warning::to themergedocstring explaining that a custom GPU merge is nondeterministic over overlap, and that the built-in string merges stay deterministic because they use atomics.UserWarningwhen a callablemergeis combined withuse_cuda=True(covers bothcupyanddask+cupy). The warning fires up front, before the geometry burn and the CuPy check.No behavior change for existing results; the GPU callable path is unchanged.
Backends
Test plan
test_rasterize_gpu_callable_warn_3057.py: warning fires for callable +use_cuda=Trueand for thechunks(dask+cupy) variant; no warning for a CPU callable merge or for a built-in GPU merge. They record warnings manually so they pass without a GPU.test_rasterize.pysuite still passes (215 passed, 2 skipped).