Skip to content

Commit f8e9787

Browse files
authored
Prep for Version 0.5.0 (#824)
* added dask cupy test for aspect func * added dask cupy test for slope func * fixed bug in dask+cupy args and added unit test * updated changelog
1 parent 8b01c59 commit f8e9787

File tree

7 files changed

+61
-13
lines changed

7 files changed

+61
-13
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
## Xarray-Spatial Changelog
22
-----------
33

4+
### Version 0.5.0 - 2025-12-15
5+
- Python 3.14 is now supported!
6+
- Fixed bug in curvature dask+cupy args and added unit test for curvature(#824)
7+
- Added dask cupy test for slope func (#824)
8+
- Added dask cupy test for aspect func (#824)
9+
- Added in dask-cupy convolve_2d test (#823)
10+
- Now ensures the hash value fits into an unsigned 64-bit integer for NumPy 2.0.0 (#805)
11+
- Added dask and pyarrow to setup.cfg test area (#822)
12+
- Allow Negative Target Height in Viewshed Analysis (viewshed.py) (#812)
13+
- Small Fixes while testing Cuda 13 (#818)
14+
- Support for certain Dask+Cupy (#815)
15+
- Update docstring for viewshed (#807)
16+
17+
418
### Version 0.4.0 - 2024-04-25
519
- Python 3.12 is now supported!
620
- Python 3.9 & 3.8 are no longer supported.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ In the GIS world, rasters are used for representing continuous phenomena (e.g. e
208208

209209
| Name | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
210210
|:----------:|:----------------------:|:--------------------:|:-------------------:|:------:|
211-
| [Aspect](xrspatial/aspect.py) | ✅️ | ✅️ | ✅️ | |
212-
| [Curvature](xrspatial/curvature.py) | ✅️ | | | ⚠️ |
211+
| [Aspect](xrspatial/aspect.py) | ✅️ | ✅️ | ✅️ | |
212+
| [Curvature](xrspatial/curvature.py) | ✅️ |⚠️✅️ |⚠️✅️ |️✅|
213213
| [Hillshade](xrspatial/hillshade.py) | ✅️ | ✅️ | | |
214-
| [Slope](xrspatial/slope.py) | ✅️ | ✅️ | ✅️ | ⚠️ |
214+
| [Slope](xrspatial/slope.py) | ✅️ | ✅️ | ✅️ | ⚠️✅️ |
215215
| [Terrain Generation](xrspatial/terrain.py) | ✅️ | ✅️ | ✅️ | |
216216
| [Viewshed](xrspatial/viewshed.py) | ✅️ | | | |
217217
| [Perlin Noise](xrspatial/perlin.py) | ✅️ | ✅️ | ✅️ | |

xrspatial/curvature.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ class cupy(object):
1515
from numba import cuda
1616

1717
# local modules
18-
from xrspatial.utils import (ArrayTypeFunctionMapping, cuda_args, get_dataarray_resolution, ngjit,
19-
not_implemented_func)
18+
from xrspatial.utils import (ArrayTypeFunctionMapping, cuda_args, get_dataarray_resolution, ngjit)
2019

2120

2221
@ngjit
@@ -84,10 +83,14 @@ def _run_cupy(data: cupy.ndarray,
8483

8584
return out
8685

86+
8787
def _run_dask_cupy(data: da.Array,
88-
cellsize: Union[int, float]) -> da.Array:
88+
cellsize: Union[int, float]) -> da.Array:
8989
data = data.astype(cupy.float32)
90-
_func = partial(_cpu, cellsize=cellsize)
90+
cellsize_arr = cupy.array([float(cellsize)], dtype='f4')
91+
92+
_func = partial(_run_cupy, cellsize=cellsize_arr)
93+
9194
out = data.map_overlap(_func,
9295
depth=(1, 1),
9396
boundary=cupy.nan,

xrspatial/tests/general_checks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ def assert_numpy_equals_cupy(numpy_agg, cupy_agg, func, nan_edges=True, atol=0,
123123
numpy_result.data, cupy_result.data.get(), equal_nan=True, atol=atol, rtol=rtol)
124124

125125

126-
def assert_numpy_equals_dask_cupy(numpy_agg, dask_cupy_agg, func, nan_edges=True):
126+
def assert_numpy_equals_dask_cupy(numpy_agg, dask_cupy_agg, func, nan_edges=True, atol=0, rtol=1e-7):
127127
numpy_result = func(numpy_agg)
128128
if nan_edges:
129129
assert_nan_edges_effect(numpy_result)
130130

131131
dask_cupy_result = func(dask_cupy_agg)
132132
general_output_checks(dask_cupy_agg, dask_cupy_result)
133133
np.testing.assert_allclose(
134-
numpy_result.data, dask_cupy_result.data.compute().get(), equal_nan=True
134+
numpy_result.data, dask_cupy_result.data.compute().get(), equal_nan=True, atol=atol, rtol=rtol
135135
)

xrspatial/tests/test_aspect.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import pytest
33

44
from xrspatial import aspect
5-
from xrspatial.tests.general_checks import (assert_nan_edges_effect, assert_numpy_equals_cupy,
5+
from xrspatial.tests.general_checks import (assert_nan_edges_effect,
6+
assert_numpy_equals_cupy,
7+
assert_numpy_equals_dask_cupy,
68
assert_numpy_equals_dask_numpy, create_test_raster,
79
cuda_and_cupy_available, general_output_checks)
810

@@ -75,3 +77,13 @@ def test_numpy_equals_cupy_random_data(random_data):
7577
numpy_agg = create_test_raster(random_data, backend='numpy')
7678
cupy_agg = create_test_raster(random_data, backend='cupy')
7779
assert_numpy_equals_cupy(numpy_agg, cupy_agg, aspect, atol=1e-6, rtol=1e-6)
80+
81+
82+
@cuda_and_cupy_available
83+
@pytest.mark.parametrize("size", [(2, 4), (10, 15)])
84+
@pytest.mark.parametrize(
85+
"dtype", [np.int32, np.int64, np.uint32, np.uint64, np.float32, np.float64])
86+
def test_numpy_equals_dask_cupy_random_data(random_data):
87+
numpy_agg = create_test_raster(random_data, backend='numpy')
88+
dask_cupy_agg = create_test_raster(random_data, backend='dask+cupy')
89+
assert_numpy_equals_dask_cupy(numpy_agg, dask_cupy_agg, aspect, atol=1e-6, rtol=1e-6)

xrspatial/tests/test_curvature.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from xrspatial import curvature
55
from xrspatial.tests.general_checks import (assert_numpy_equals_cupy,
6+
assert_numpy_equals_dask_cupy,
67
assert_numpy_equals_dask_numpy, create_test_raster,
78
cuda_and_cupy_available, general_output_checks)
89

@@ -87,9 +88,6 @@ def test_numpy_equals_cupy_random_data(random_data):
8788
numpy_agg = create_test_raster(random_data, backend='numpy')
8889
cupy_agg = create_test_raster(random_data, backend='cupy')
8990
assert_numpy_equals_cupy(numpy_agg, cupy_agg, curvature)
90-
# NOTE: Dask + GPU code paths don't currently work because of
91-
# dask casting cupy arrays to numpy arrays during
92-
# https://github.com/dask/dask/issues/4842
9391

9492

9593
@pytest.mark.parametrize("size", [(2, 4), (10, 15)])
@@ -99,3 +97,13 @@ def test_numpy_equals_dask_random_data(random_data):
9997
numpy_agg = create_test_raster(random_data, backend='numpy')
10098
dask_agg = create_test_raster(random_data, backend='dask')
10199
assert_numpy_equals_dask_numpy(numpy_agg, dask_agg, curvature)
100+
101+
102+
@cuda_and_cupy_available
103+
@pytest.mark.parametrize("size", [(2, 4), (10, 15)])
104+
@pytest.mark.parametrize(
105+
"dtype", [np.int32, np.int64, np.uint32, np.uint64, np.float32, np.float64])
106+
def test_numpy_equals_dask_cupy_random_data(random_data):
107+
numpy_agg = create_test_raster(random_data, backend='numpy')
108+
dask_cupy_agg = create_test_raster(random_data, backend='dask+cupy')
109+
assert_numpy_equals_dask_cupy(numpy_agg, dask_cupy_agg, curvature, atol=1e-6, rtol=1e-6)

xrspatial/tests/test_slope.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from xrspatial import slope
55
from xrspatial.tests.general_checks import (assert_nan_edges_effect, assert_numpy_equals_cupy,
6+
assert_numpy_equals_dask_cupy,
67
assert_numpy_equals_dask_numpy, create_test_raster,
78
cuda_and_cupy_available, general_output_checks)
89

@@ -63,3 +64,13 @@ def test_numpy_equals_cupy_qgis_data(elevation_raster):
6364
numpy_agg = input_data(elevation_raster, 'numpy')
6465
cupy_agg = input_data(elevation_raster, 'cupy')
6566
assert_numpy_equals_cupy(numpy_agg, cupy_agg, slope)
67+
68+
69+
@cuda_and_cupy_available
70+
@pytest.mark.parametrize("size", [(2, 4), (10, 15)])
71+
@pytest.mark.parametrize(
72+
"dtype", [np.int32, np.int64, np.uint32, np.uint64, np.float32, np.float64])
73+
def test_numpy_equals_dask_cupy_random_data(random_data):
74+
numpy_agg = create_test_raster(random_data, backend='numpy')
75+
dask_cupy_agg = create_test_raster(random_data, backend='dask+cupy')
76+
assert_numpy_equals_dask_cupy(numpy_agg, dask_cupy_agg, slope, atol=1e-6, rtol=1e-6)

0 commit comments

Comments
 (0)