Skip to content

Add memory guard to emerging_hotspots public API (#1274)#1276

Open
brendancol wants to merge 1 commit intomainfrom
issue-1274
Open

Add memory guard to emerging_hotspots public API (#1274)#1276
brendancol wants to merge 1 commit intomainfrom
issue-1274

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

  • Adds _available_memory_bytes() and _check_memory(n_times, ny, nx) helpers to xrspatial/emerging_hotspots.py and calls them from the public API so the numpy and cupy backends raise MemoryError before allocating when the projected (T, H, W) cube would exceed 50% of available RAM
  • Skips the guard for dask-backed inputs because their map_blocks and map_overlap paths process per-chunk and do not materialise the full cube
  • 12 bytes per cube cell budget covers the float32 input copy, gi_zscore float32, and gi_bin int8, plus the small H*W temporaries (convolved scratch, category, trend_z, trend_p)

Why

Pre-fix, the public API only validated ndim and shape[0] >= 2. A (100, 20000, 20000) input ran straight into about 480 GB of allocations on the numpy path with no warning. Same pattern as #1231, #1229, #1240, #1236, #1241, #1263, and #1264.

Found during the emerging_hotspots security sweep (/sweep-security).

Test plan

  • All 30 existing emerging_hotspots tests pass
  • 5 new tests in TestMemoryGuard cover: numpy guard trips, numpy guard passes when budget is ample, cupy guard trips, dask guard is skipped, error message surfaces shape and projected GB
  • .claude/sweep-security-state.json updated with the emerging_hotspots entry recording the fix and a deferred MEDIUM finding (public API does not call _validate_raster())

Closes #1274

The numpy and cupy backends each materialise three full (T, H, W) cubes
(float32 input copy, gi_zscore float32, gi_bin int8) plus small H*W
temporaries with no memory check. A (100, 20000, 20000) input projected
to about 480 GB.

Add _available_memory_bytes() and _check_memory() helpers and call the
guard from the public API for non-dask inputs. Dask paths process
per-chunk via map_blocks/map_overlap and do not need the cube guard.

Same pattern as #1231, #1240, #1263, #1264.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label Apr 25, 2026
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.

emerging_hotspots: missing memory guard on numpy and cupy backends

1 participant