Describe the bug
bump() has a memory guard on the locs/heights bump arrays (added in #1206), but the output raster itself is allocated with no check. _finish_bump at xrspatial/bump.py:45 calls np.zeros((height, width)) where height and width come from user parameters or agg.shape.
A caller can trigger a huge allocation:
from xrspatial import bump
bump(width=1_000_000, height=1_000_000)
With the default count = min(w*h//10, 10_000_000) = 10_000_000, the bump-count guard sees only 10M * 16 = 160 MB and passes. Then _finish_bump tries to allocate np.zeros((1_000_000, 1_000_000)) which is ~8 TB of float64 and OOMs the host.
Expected behavior
The memory budget check should also account for the output raster bytes (8 * height * width for float64) and raise MemoryError before any allocation happens when the required memory is larger than roughly half of available memory.
Additional context
Only the numpy and cupy backends are affected. The dask paths (_bump_dask_numpy, _bump_dask_cupy) build the output lazily via da.from_delayed and da.zeros on per-chunk tiles, so they never materialize the full raster. See #1206 for the earlier bump-count guard.
Describe the bug
bump()has a memory guard on thelocs/heightsbump arrays (added in #1206), but the output raster itself is allocated with no check._finish_bumpatxrspatial/bump.py:45callsnp.zeros((height, width))whereheightandwidthcome from user parameters oragg.shape.A caller can trigger a huge allocation:
With the default
count = min(w*h//10, 10_000_000) = 10_000_000, the bump-count guard sees only10M * 16 = 160 MBand passes. Then_finish_bumptries to allocatenp.zeros((1_000_000, 1_000_000))which is ~8 TB of float64 and OOMs the host.Expected behavior
The memory budget check should also account for the output raster bytes (
8 * height * widthfor float64) and raiseMemoryErrorbefore any allocation happens when the required memory is larger than roughly half of available memory.Additional context
Only the numpy and cupy backends are affected. The dask paths (
_bump_dask_numpy,_bump_dask_cupy) build the output lazily viada.from_delayedandda.zeroson per-chunk tiles, so they never materialize the full raster. See #1206 for the earlier bump-count guard.