Skip to content

Guard sink_d8() against unbounded memory allocations (#1356)#1361

Merged
brendancol merged 1 commit into
mainfrom
issue-1356
Apr 29, 2026
Merged

Guard sink_d8() against unbounded memory allocations (#1356)#1361
brendancol merged 1 commit into
mainfrom
issue-1356

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Closes #1356.

sink_d8() ran the BFS connected-component kernel on the eager numpy and cupy backends with no check on the input size. Large in-memory rasters could exhaust host or device memory.

This PR mirrors the pattern from #1319 and the rest of the hydro guard series.

Bytes per pixel

  • numpy: 24 B/px (labels float64 + queue_r int64 + queue_c int64)
  • cupy: 8 B/px (labels float64)

The caller-provided flow_dir is not double-counted.

Changes

  • New _BYTES_PER_PIXEL, _GPU_BYTES_PER_PIXEL, _available_memory_bytes, _available_gpu_memory_bytes, _check_memory, _check_gpu_memory helpers in sink_d8.py.
  • sink_d8() calls the matching _check_* helper on the numpy and cupy branches before dispatching. Dask branches skip the guard.
  • 5 new tests in TestMemoryGuard: numpy raises, normal input passes, dask skips the guard, error message points at dask, byte-per-pixel constants are pinned.

Test plan

  • pytest xrspatial/hydro/tests/test_sink_d8.py -- 21 passed
  • pytest xrspatial/hydro/tests/ (excluding the two known dask cleanup flakes) -- 642 passed

The numpy and cupy paths allocate H*W working buffers (labels and BFS
queues on CPU, labels grid on GPU) before any sanity check on the input
size. Passing a sufficiently large in-memory raster can OOM the host
or device.

Add per-module _BYTES_PER_PIXEL (24) and _GPU_BYTES_PER_PIXEL (8)
constants and _check_memory / _check_gpu_memory helpers that raise
MemoryError when the projected working set exceeds 50% of available
RAM / free GPU memory. Wire the guards into the eager numpy and cupy
branches of sink_d8(); dask paths skip the guard since per-tile
allocations are bounded.

Mirrors the pattern from #1318/#1319 and the rest of the hydro guard
series.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label Apr 29, 2026
@brendancol brendancol merged commit 9fd8df8 into main Apr 29, 2026
10 checks passed
@brendancol brendancol deleted the issue-1356 branch May 5, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sink_d8: no memory guard on H*W working arrays

1 participant