Gate remote sources in read_geotiff_gpu under stable_only (#2867)#2878
Merged
Conversation
read_geotiff_gpu accepted stable_only=True but never enforced it, so a direct GPU call could read an advanced-tier HTTP / fsspec source that open_geotiff and read_geotiff_dask reject. Call _validate_stable_only_remote before the cupy import, the CUDA preflight, and the remote CPU fallback, matching the other two readers, and fix the docstring that wrongly called stable_only a no-op on the GPU path. Extend test_stable_only_remote_2821 with GPU coverage: the rejection tests run on CPU-only hosts because the gate fires before the cupy import; the experimental-optin unlock test is gated behind cupy + CUDA.
brendancol
commented
Jun 2, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
PR Review: Gate remote sources in read_geotiff_gpu under stable_only (#2867)
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
None.
Nits (optional improvements)
- The unlock test (
test_gpu_direct_fsspec_source_allowed_with_experimental_optin) re-declares the_gpu_available/_HAS_GPUhelper that a few other geotiff test modules already define locally (read/test_basic.py,unit/test_predictor.py). There is no shared fixture for it, so the local copy matches the existing pattern in this package. Fine to leave as is.
What looks good
- The gate runs before the cupy import, the CUDA preflight, and the remote CPU fallback, so the rejection does not depend on GPU availability. That is what lets the two rejection tests run on CPU-only CI, which is the right call.
- The call signature matches how
open_geotiffandread_geotiff_daskinvoke_validate_stable_only_remote(same kwargs, same local-import style). - The gate sits ahead of the
chunks is not Nonebranch, so it covers both the eager and chunked GPU paths, not just one. - The docstring no longer claims
stable_onlyis a no-op. The wording now matches actual behavior and thegeotiff.rstnote that already said all three paths run the check. - Tests cover fsspec and http rejection plus the experimental-codecs unlock, mirroring the existing eager/dask cases.
Checklist
- Behavior matches the sibling readers (open_geotiff, read_geotiff_dask)
- Gate fires before any GPU/network work
- Covers eager and chunked GPU paths
- Edge cases covered by tests (fsspec, http, unlock)
- No premature materialization or unnecessary copies
- Benchmark not needed (validation-only change)
- README feature matrix not affected (no new function, no backend change)
- Docstring present and accurate
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.
Closes #2867
read_geotiff_gpu(..., stable_only=True)accepted the kwarg but never enforced it. For HTTP / fsspec sources the GPU path routes through the CPU fallback, so a direct GPU call could read an advanced-tier remote source thatopen_geotiffandread_geotiff_daskreject. The GPU docstring also calledstable_onlya no-op, which was wrong for remote sources._validate_stable_only_remote(...)inread_geotiff_gpubefore the cupy import, the CUDA preflight, and the remote CPU fallback, the same wayopen_geotiffandread_geotiff_daskcall it. Running it ahead of the import means the rejection is independent of GPU availability.stable_onlyis described as an enforced gate, not a no-op.Backend coverage: the gate lives in the shared
read_geotiff_gpuentry point, which serves the eager GPU (numpy/cupy) and chunked GPU (dask+cupy) reads. The other backends already had the gate.Test plan:
test_stable_only_remote_2821.py: fsspec and http sources rejected understable_only=True, plus an experimental-optin unlock test gated behind cupy + CUDA.pytest xrspatial/geotiff/tests/test_stable_only_remote_2821.pypasses (12 passed locally with a GPU present).