What's missing
Two kwargs in xrspatial.geotiff are wired up, documented, and entirely untested.
write_geotiff_gpu(predictor=...)
The GPU writer routes predictor= through normalize_predictor and gpu_compress_tiles into five CUDA encode kernels: _predictor_encode_kernel_u8/u16/u32/u64 for predictor=2, and _fp_predictor_encode_kernel for predictor=3 (the byte-swizzled FP predictor from TIFF Technical Note 3).
The CPU writer side has dense coverage -- test_predictor_fp_write_1313.py, test_predictor_multisample.py, test_predictor2_big_endian.py -- all good. The GPU side has nothing.
To check this wasn't paranoia I tried the obvious mutation: delete the _gpu_predictor2_encode / _fp_predictor_encode_kernel calls from gpu_compress_tiles. The output decodes to garbage. Nothing in the existing suite flagged it.
read_vrt(window=...)
The public read_vrt documents window: tuple or None. _vrt.read_vrt implements the full thing: clipping, dst/src overlap mapping, per-band nodata, and GeoTransform origin shift on both y/x coords and attrs['transform']. The only window-related VRT test is a signature-annotation pin in test_signature_annotations_1654.py.
Same mutation pattern: drop the window kwarg, read the full mosaic. Output has the wrong shape for any caller that asked for a window. Existing tests miss it.
What's added
23 tests in xrspatial/geotiff/tests/test_kwarg_behaviour_2026_05_12_v2.py.
GPU writer predictor (11):
predictor=True / predictor=2 on uint8: round-trip plus on-disk Predictor tag check
predictor=2 on 3-band uint8 RGB (the samples_per_pixel > 1 stride path)
predictor=False writes no Predictor tag -- pins against an accidental default flip
predictor=2 on uint16 and int32 (kernel dispatch across dtypes)
predictor=3 on float32 and float64 (FP predictor on bps=4 and bps=8)
predictor=3 with an int dtype raises ValueError (parity with the CPU writer)
- CPU vs GPU pixel-exact parity for
predictor=2 uint16 and predictor=3 float32
read_vrt(window=) (12):
- Window slices a sub-region of a single-source VRT
window=(0, 0, H, W) matches the no-window output
- Window past raster bounds clamps to the extent
- Window with negative offsets clamps to 0
- Window straddling a 2x1 mosaic seam (multi-source overlap mapping)
- Window starting past the seam (only the right source is read)
- Window shifts
attrs['transform'] origin
- Window shifts
y/x coords with the pixel-is-area half-pixel convention
- Window plus band selection on a multi-band VRT
- Window plus
chunks returns a dask-backed DataArray with the window-sized shape
- Window plus
gpu=True returns CuPy-backed with the window-sized shape
- Window plus
gpu=True plus chunks returns Dask+CuPy with a cupy _meta
All 23 pass on the GPU host. Mutation against the encode-kernel dispatch flips 7 of the predictor tests red. Mutation against the window-clip block flips the window tests red.
What's missing
Two kwargs in
xrspatial.geotiffare wired up, documented, and entirely untested.write_geotiff_gpu(predictor=...)The GPU writer routes
predictor=throughnormalize_predictorandgpu_compress_tilesinto five CUDA encode kernels:_predictor_encode_kernel_u8/u16/u32/u64for predictor=2, and_fp_predictor_encode_kernelfor predictor=3 (the byte-swizzled FP predictor from TIFF Technical Note 3).The CPU writer side has dense coverage --
test_predictor_fp_write_1313.py,test_predictor_multisample.py,test_predictor2_big_endian.py-- all good. The GPU side has nothing.To check this wasn't paranoia I tried the obvious mutation: delete the
_gpu_predictor2_encode/_fp_predictor_encode_kernelcalls fromgpu_compress_tiles. The output decodes to garbage. Nothing in the existing suite flagged it.read_vrt(window=...)The public
read_vrtdocumentswindow: tuple or None._vrt.read_vrtimplements the full thing: clipping, dst/src overlap mapping, per-band nodata, and GeoTransform origin shift on bothy/xcoords andattrs['transform']. The only window-related VRT test is a signature-annotation pin intest_signature_annotations_1654.py.Same mutation pattern: drop the window kwarg, read the full mosaic. Output has the wrong shape for any caller that asked for a window. Existing tests miss it.
What's added
23 tests in
xrspatial/geotiff/tests/test_kwarg_behaviour_2026_05_12_v2.py.GPU writer predictor (11):
predictor=True/predictor=2on uint8: round-trip plus on-disk Predictor tag checkpredictor=2on 3-band uint8 RGB (thesamples_per_pixel > 1stride path)predictor=Falsewrites no Predictor tag -- pins against an accidental default flippredictor=2on uint16 and int32 (kernel dispatch across dtypes)predictor=3on float32 and float64 (FP predictor on bps=4 and bps=8)predictor=3with an int dtype raisesValueError(parity with the CPU writer)predictor=2uint16 andpredictor=3float32read_vrt(window=)(12):window=(0, 0, H, W)matches the no-window outputattrs['transform']originy/xcoords with the pixel-is-area half-pixel conventionchunksreturns a dask-backed DataArray with the window-sized shapegpu=Truereturns CuPy-backed with the window-sized shapegpu=Truepluschunksreturns Dask+CuPy with a cupy_metaAll 23 pass on the GPU host. Mutation against the encode-kernel dispatch flips 7 of the predictor tests red. Mutation against the window-clip block flips the window tests red.