flood_depth() and curve_number_runoff() document a "2D float64 grid" return value. Their numpy and cupy backends force float64 via np.asarray(..., dtype=np.float64) / cp.asarray(..., dtype=cp.float64). The dask and dask+cupy backends skip that cast and run directly on the input dtype, so a float32 input produces a float32 result. The output dtype then depends on which backend is active.
Repro:
import numpy as np, xarray as xr, dask.array as da
from xrspatial.flood import flood_depth
arr = np.array([[0., 1.], [2., 3.]], dtype=np.float32)
mk = lambda d: xr.DataArray(d, dims=('y', 'x'))
print(flood_depth(mk(arr), 5.0).dtype) # float64
print(flood_depth(mk(da.from_array(arr)), 5.0).dtype) # float32
Same divergence in curve_number_runoff(). travel_time() and flood_depth_vegetation() stay float64 on every backend only because their _TAN_MIN clamp is an np.float64 scalar that forces promotion, so they are not affected.
Fix: cast the input to float64 inside _flood_depth_dask and _cn_runoff_dask so the dask backends match the numpy/cupy backends and the documented float64 contract.
Found by the metadata-propagation sweep.
flood_depth()andcurve_number_runoff()document a "2D float64 grid" return value. Their numpy and cupy backends force float64 vianp.asarray(..., dtype=np.float64)/cp.asarray(..., dtype=cp.float64). The dask and dask+cupy backends skip that cast and run directly on the input dtype, so a float32 input produces a float32 result. The output dtype then depends on which backend is active.Repro:
Same divergence in
curve_number_runoff().travel_time()andflood_depth_vegetation()stay float64 on every backend only because their_TAN_MINclamp is annp.float64scalar that forces promotion, so they are not affected.Fix: cast the input to float64 inside
_flood_depth_daskand_cn_runoff_daskso the dask backends match the numpy/cupy backends and the documented float64 contract.Found by the metadata-propagation sweep.