Commit 950317e
authored
* Fix write_geotiff_gpu NaN-to-sentinel substitution (#1599)
The GPU writer (write_geotiff_gpu / to_geotiff with gpu=True) emitted
raw NaN bytes for missing pixels even when nodata=<finite> was
supplied, while the CPU writer substituted NaN with the sentinel
before encoding. xrspatial-only round-trips were unaffected because
the reader masks both NaN and the sentinel, but external readers that
mask only on the GDAL_NODATA tag (rasterio, GDAL, QGIS) treated NaN
pixels as valid data. rasterio reported 100% valid pixels on a GPU
file with 25 NaN inputs vs the CPU file's 25-invalid count.
Mirror the CPU writer's NaN-to-sentinel rewrite on the CuPy array
before compression. Gate on float dtype and finite nodata. Copy
defensively before mutating so a caller-owned CuPy buffer is not
modified, matching the CPU writer's arr.copy() at the equivalent step.
Add test_gpu_writer_nan_sentinel_1599.py: 7 regression tests covering
sentinel substitution, CPU/GPU byte equivalence, caller buffer
preservation, no-NaN no-op, NaN sentinel skip, rasterio-visible mask
parity, and 3D multiband substitution.
Discovered during the 2026-05-11 geotiff accuracy sweep.
* Address PR #1600 review: clarify NaN-copy comment, pin codec in reader test
- Update the in-code comment around the GPU NaN-to-sentinel rewrite to
reflect the actual unconditional-copy behavior. The previous comment
implied a caller-owned/fresh-buffer split that the code did not
enforce; spell out instead why we copy in every case rather than
tracking provenance through the upstream branch tree.
- Pin compression='deflate' on both the CPU and GPU writers in the
external-reader (rasterio) regression test. The default codec is
ZSTD, and some rasterio/GDAL builds in the wild ship without ZSTD
support, which would have failed the round-trip for environment
reasons unrelated to the nodata mask under test.
1 parent bfc0be7 commit 950317e
3 files changed
Lines changed: 241 additions & 1 deletion
File tree
- .claude
- xrspatial/geotiff
- tests
0 commit comments