Guard gpu_rtx hillshade and viewshed against unbounded GPU allocations (#1308)#1310
Merged
brendancol merged 3 commits intomainfrom Apr 29, 2026
Merged
Guard gpu_rtx hillshade and viewshed against unbounded GPU allocations (#1308)#1310brendancol merged 3 commits intomainfrom
brendancol merged 3 commits intomainfrom
Conversation
#1308) hillshade_rtx and viewshed_gpu were allocating cupy device buffers sized by raster shape with no upfront memory check. A 30000x30000 raster asked for 90-108 GB of VRAM (around 100-120 B/pixel) before cupy gave up with an internal allocator error that didn't name the input shape, so users had no clean way to know what to turn down. Adds gpu_rtx/_memory.py with _available_gpu_memory_bytes() and _check_gpu_memory(func_name, h, w), same shape as cost_distance (#1262) and sky_view_factor (#1299). Single 120 B/pixel budget covers both entry points (worst case is viewshed_gpu). Wired in after the cupy.ndarray type check and before create_triangulation. Guard skips silently when cupy.cuda.runtime.memGetInfo() isn't available. Tests in xrspatial/tests/test_gpu_rtx_memory.py: 5 helper-unit tests that don't need RTX, 4 end-to-end tests through hillshade()/viewshed() gated on has_rtx(). The existing 81 hillshade/viewshed tests still pass.
Contributor
Author
|
@copilot resolve the merge conflicts in this pull request |
Contributor
Author
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: brendancol <433221+brendancol@users.noreply.github.com>
Contributor
Contributor
This was referenced Apr 30, 2026
brendancol
added a commit
that referenced
this pull request
Apr 30, 2026
…1381) create_triangulation() computed scale = max(H, W) / cupy.amax(raster.data) without checking that the max was positive and finite. An all-zero raster gave scale = inf and an all-NaN raster gave scale = nan, both of which propagated into vertex z-coordinates and produced garbage geometry that the OptiX raytracer would silently render. Add a guard that raises ValueError when maxH is non-finite or non-positive, before any hash or device-buffer work. This is the deferred Cat 3 finding from the gpu_rtx security audit (#1308 / PR #1310). Tests cover the all-zero, all-NaN, all-negative, and single-positive-pixel cases plus the error-message format.
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.
Summary
hillshade_rtxandviewshed_gpuallocated cupy device buffers sized by raster shape with no memory check. A 30000x30000 raster asked for 90-108 GB of VRAM (100-120 B/pixel) before cupy surfaced an opaque allocator error.gpu_rtx/_memory.pywith_available_gpu_memory_bytes()and_check_gpu_memory(func_name, h, w), same shape as cost_distance: missing memory guard on CuPy backend #1262 / sky_view_factor(): numpy and cupy backends have no memory guard #1299. 120 B/pixel budget covers both entry points (worst case isviewshed_gpu). Wired in at the top ofhillshade_rtxandviewshed_gpu.xrspatial/tests/test_gpu_rtx_memory.py: 5 helper-unit tests that don't need RTX, 4 end-to-end throughhillshade()/viewshed()gated onhas_rtx().Closes #1308.
Test plan
pytest xrspatial/tests/test_gpu_rtx_memory.py -v(9 passed)pytest xrspatial/tests/test_hillshade.py xrspatial/tests/test_viewshed.py(81 passed, no regressions)_available_gpu_memory_bytesMemoryErrorraised end-to-end fromhillshade(shadows=True)andviewshed()when free VRAM is patched to a tiny value