geotiff: gds chunked gpu path bool-band reject + LERC masked_fill (#1896)#1900
Merged
Conversation
Mirror two parity gaps from the eager GPU path into the GDS chunked GPU read path: - Reject band=True/np.bool_(True) up front in _read_geotiff_gpu_chunked_gds before the numeric range check. Without it, isinstance(True, int) causes True < n_bands_out to silently select band 1. - Resolve masked_fill once for LERC files and forward it through _decode_window_gpu_direct to both gpu_decode_tiles_from_file and gpu_decode_tiles. Without it, LERC files with a per-pixel valid mask read back at LERC's zero fill instead of the nodata sentinel on the chunked path.
Pin the two regressions the fix in 54ab604 closes: - _read_geotiff_gpu_chunked_gds rejects band=True, band=False, and band=np.bool_(True) while still accepting a plain int band. - _decode_window_gpu_direct forwards masked_fill so a LERC file with a per-pixel valid mask round-trips through the chunked path with the same NaN-on-invalid-pixel behaviour as the eager GPU path (both for NaN and sentinel nodata).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR closes parity gaps in the GeoTIFF GPU backend’s GDS chunked read path so it matches the eager GPU path behavior for (1) invalid band inputs and (2) LERC valid-mask handling.
Changes:
- Reject
bandwhen it isbool/np.bool_in_read_geotiff_gpu_chunked_gds(matching other backends). - Resolve and forward LERC
masked_fillthrough_decode_window_gpu_directinto both GPU tile decode entry points. - Add regression tests covering bool-band rejection and LERC mask parity between eager and GDS chunked paths.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
xrspatial/geotiff/_backends/gpu.py |
Threads masked_fill into GDS chunk decode and adds explicit bool/np.bool_ rejection for band. |
xrspatial/geotiff/tests/test_gds_chunked_gpu_parity_1896.py |
New regression tests for bool-band rejection and LERC masked-fill parity (eager vs GDS chunked). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+163
to
+171
| lerc = pytest.importorskip("lerc") | ||
|
|
||
| from xrspatial.geotiff._compression import LERC_AVAILABLE # noqa: E402 | ||
|
|
||
|
|
||
| _lerc_gpu_only = pytest.mark.skipif( | ||
| not (_HAS_GPU and LERC_AVAILABLE), | ||
| reason="cupy + CUDA + lerc required", | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two parity gaps between the GDS chunked GPU read path and the eager GPU path in
xrspatial/geotiff/_backends/gpu.py._read_geotiff_gpu_chunked_gdsvalidatedbandwith a numeric range check only. Sinceisinstance(True, int)is True,band=TruepassedTrue < n_bands_outand silently picked band 1. Match the eager path (geotiff: non-VRT read paths accept band=True / band=False #1786) and the dask path by rejectingbool/np.bool_first._decode_window_gpu_directcalledgpu_decode_tiles_from_fileandgpu_decode_tileswithout forwardingmasked_fill. On a LERC file with a per-pixel valid mask, that left invalid pixels at LERC's zero fill instead of the nodata sentinel. Resolvemasked_fillonce forcompression == COMPRESSION_LERC(same as the eager path) and thread it through both kernels.Closes #1896.
Test plan
test_gds_chunked_band_{true,false,np_bool}_rejectedraisesValueError.test_gds_chunked_band_int_still_works--band=1selects band 1.test_gds_chunked_lerc_mask_matches_eager-- NaN nodata + per-pixel mask, chunked output equals eager output, NaN at masked positions.test_gds_chunked_lerc_mask_sentinel_nodata-- same with -9999 sentinel.Refs #1813, #1895, #1786.