Propagate NaN center cell in planar slope#2773
Merged
Merged
Conversation
The planar _cpu and _gpu kernels read the 8 neighbours but not the center cell, so a NaN hole surrounded by valid cells returned a finite slope. Add a center-cell NaN check to both paths and pin it with cross-backend regression tests.
brendancol
commented
Jun 1, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Propagate NaN center cell in planar slope
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
None.
Nits (optional improvements)
xrspatial/slope.py:116-- the CPU path checks the center withnp.isnanand the GPU path usesmath.isnan. Each is the right call for its kernel, so nothing to change here. Just flagging it so the split doesn't trip up a future reader.
What looks good
- The fix lives in the two shared kernels (
_cpu,_gpu), so all four planar backends pick up the behaviour without touching the dispatch wiring. numpy and cupy were verified locally on a real GPU; the dask paths run the same kernels throughmap_overlap. continue(CPU) andreturn nan(GPU) both land on a NaN thatoutis already pre-filled with, so the center stays NaN and its neighbours go NaN on their own (they read the hole as one of their 8 inputs). Same result the geodesic method already gives.- Tests hit all four backends and check numpy-vs-backend parity with
equal_nan=True, plus a direct assertion on the center cell. The regression comment names the issue. - Scope is tight. Geodesic paths and boundary handling are left alone.
Checklist
- Algorithm matches reference: n/a (NoData propagation, not an algorithm change)
- All implemented backends produce consistent results: yes
- NaN handling is correct: yes
- Edge cases covered by tests: yes (center NaN with valid neighbours, all four backends)
- Dask chunk boundaries handled correctly: yes (depth=1 unchanged, kernel handles the NaN)
- No premature materialization or unnecessary copies: yes
- Benchmark exists or not needed: not needed (no perf change)
- README feature matrix updated: n/a (no new function, no backend change)
- Docstrings present and accurate: yes (public docstring unchanged and still valid)
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 #2761
What
_cpuand_gpuslope kernels read the 8 surrounding cells but never the center, so a NaN hole with valid neighbours returned a finite slope (a flat 5x5 raster with only the center NaN gave 0.0 at the center).Backend coverage
The check lives in the shared
_cpu(@ngjit) and_gpu(cuda device) kernels, so it covers all four planar paths: numpy, cupy, dask+numpy, dask+cupy.Test plan
test_center_nan_propagates_numpy- NaN center stays NaNequal_nan=Truetest_slope.pysuite still green (65 passed locally, GPU included)