Skip to content

Commit 1a856ac

Browse files
committed
Add memory guard for proximity line-sweep dask path (#1111)
When max_distance >= raster diagonal and the non-KDTree path is used (GREAT_CIRCLE metric or no scipy), the line-sweep rechunks to a single chunk. The existing memory guard already catches this for the GREAT_CIRCLE case. Add a pre-rechunk estimate (~35 bytes/pixel) to _process_dask for the general case, raising ValueError before the rechunk if working memory would exceed 80% of available RAM. The EUCLIDEAN/MANHATTAN + scipy path uses the memory-safe KDTree and already has its own guards.
1 parent b83ae43 commit 1a856ac

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

xrspatial/tests/test_proximity.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,30 @@ def _make_kdtree_raster(height=20, width=30, chunks=(10, 15)):
374374
return raster
375375

376376

377+
@pytest.mark.skipif(da is None, reason="dask is not installed")
378+
def test_proximity_dask_inf_distance_memory_guard():
379+
"""Line-sweep path with inf max_distance should raise when memory is tight."""
380+
from unittest.mock import patch
381+
from xrspatial.proximity import _available_memory_bytes
382+
383+
data = np.zeros((100, 100), dtype=np.float64)
384+
data[50, 50] = 1.0
385+
raster = xr.DataArray(
386+
da.from_array(data, chunks=(50, 50)),
387+
dims=['y', 'x'],
388+
coords={
389+
'x': np.linspace(-10, 10, 100),
390+
'y': np.linspace(-5, 5, 100),
391+
},
392+
)
393+
394+
# Force the non-KDTree path by using GREAT_CIRCLE metric
395+
# (KDTree only supports EUCLIDEAN/MANHATTAN), and mock tight memory.
396+
with patch('xrspatial.proximity._available_memory_bytes', return_value=1024):
397+
with pytest.raises(MemoryError, match="exceed available memory"):
398+
proximity(raster, target_values=[1], distance_metric="GREAT_CIRCLE")
399+
400+
377401
@pytest.mark.skipif(da is None, reason="dask is not installed")
378402
@pytest.mark.parametrize("metric", ["EUCLIDEAN", "MANHATTAN"])
379403
def test_proximity_dask_kdtree_matches_numpy(metric):

0 commit comments

Comments
 (0)