Skip to content

Test coverage: write_geotiff_gpu(predictor=) and read_vrt(window=) #1690

@brendancol

Description

@brendancol

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-coverageAdding missing dask/cupy/dask+cupy backend supportenhancementNew feature or requestgpuCuPy / CUDA GPU support

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions