geotiff: GPU writer + dispatcher coverage for CRS fail-closed (#1929)#1956
Merged
brendancol merged 2 commits intoMay 15, 2026
Conversation
8c363b9 to
4a52fa8
Compare
Contributor
Author
PR Review: geotiff: GPU writer + dispatcher coverage for CRS fail-closed (#1929)Blockers (must fix before merge)
Suggestions (should fix, not blocking)
Nits (optional improvements)
What looks good
Checklist
|
brendancol
added a commit
to brendancol/xarray-spatial
that referenced
this pull request
May 15, 2026
review) - TestKwargDefaultParity now also checks _write_vrt_tiled, the third writer that consumes allow_unparseable_crs and routes through _validate_crs_fallback. - TestToGeotiffGpuDispatcherFailClosed installs a spy on the module-level write_geotiff_gpu symbol so each dispatcher test confirms the GPU path executed rather than silently falling back to the CPU writer on ImportError. - TestErrorMessageParity replaces the brittle full-string equality with a subset check over the recovery hints both backends share via _validate_crs_fallback.
brendancol
added a commit
to brendancol/xarray-spatial
that referenced
this pull request
May 15, 2026
review) - TestKwargDefaultParity now also checks _write_vrt_tiled, the third writer that consumes allow_unparseable_crs and routes through _validate_crs_fallback. - TestToGeotiffGpuDispatcherFailClosed installs a spy on the module-level write_geotiff_gpu symbol so each dispatcher test confirms the GPU path executed rather than silently falling back to the CPU writer on ImportError. - TestErrorMessageParity replaces the brittle full-string equality with a subset check over the recovery hints both backends share via _validate_crs_fallback.
d1ff2c7 to
03c4cbd
Compare
Contributor
Author
PR Review: geotiff: GPU writer + dispatcher coverage for CRS fail-closed (#1929) (re-review after rebase)Scope after rebase onto Blockers
Suggestions
Nits
What looks good
Checklist
|
…-contrib#1929) xarray-contrib#1929 added _validate_crs_fallback and wired allow_unparseable_crs into to_geotiff, write_geotiff_gpu, and the to_geotiff(gpu=True) dispatcher. The existing test_crs_fail_closed_1929 only exercises the eager CPU writer; the GPU writer's _validate_crs_fallback call at _writers/gpu.py:507 and the dispatcher thread-through at _writers/eager.py:447 had no targeted tests. A regression dropping the GPU validator or the dispatcher kwarg forward would let write_geotiff_gpu(crs="EPSG:4326") on a host without pyproj silently emit a garbage GTCitationGeoKey that non-libgeotiff readers cannot interpret. Adds 13 tests, all passing on a CUDA host: - write_geotiff_gpu(crs=garbage) raises ValueError (via kwarg + attr) - allow_unparseable_crs=True opt-in restores citation-only write - error message points to all four recovery options - EPSG int + WKT-shaped + no-CRS happy paths still work - to_geotiff(gpu=True) auto-dispatches on cupy data and threads through - to_geotiff(gpu=True, allow_unparseable_crs=True) forwards opt-in - GPU vs CPU error message parity - structural pin: allow_unparseable_crs default is False on both writers Mutation against the GPU validator at _writers/gpu.py:507 flipped 6 tests red; mutation against the dispatcher forward at _writers/eager.py:447 flipped the two opt-in dispatcher tests red.
review) - TestKwargDefaultParity now also checks _write_vrt_tiled, the third writer that consumes allow_unparseable_crs and routes through _validate_crs_fallback. - TestToGeotiffGpuDispatcherFailClosed installs a spy on the module-level write_geotiff_gpu symbol so each dispatcher test confirms the GPU path executed rather than silently falling back to the CPU writer on ImportError. - TestErrorMessageParity replaces the brittle full-string equality with a subset check over the recovery hints both backends share via _validate_crs_fallback.
Contributor
Author
|
Rebased onto current main at |
03c4cbd to
7aca800
Compare
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
Closes a Cat 1 HIGH backend-parity gap for issue #1929 (CRS fail-closed).
test_crs_fail_closed_1929.pyonly exercises the eager CPU writer; the GPU writer's call to_validate_crs_fallbackat_writers/gpu.py:507and theto_geotiff(gpu=True)dispatcher thread-through at_writers/eager.py:447had no targeted tests.A regression dropping either call would let
write_geotiff_gpu(crs=\"EPSG:4326\")on a host without pyproj, or any other unparseable CRS string, silently emit a garbageGTCitationGeoKeythat non-libgeotiff readers cannot interpret.13 new tests, all passing on a CUDA host:
write_geotiff_gpu(crs=garbage)raises ValueError (via kwarg + attr)allow_unparseable_crs=Trueopt-in restores citation-only writeto_geotiff(gpu=True)auto-dispatches on cupy data and threads throughto_geotiff(gpu=True, allow_unparseable_crs=True)forwards opt-inallow_unparseable_crsdefault is False on both writersMutation against the GPU validator at
_writers/gpu.py:507flipped 6 tests red. Mutation against the dispatcher forward at_writers/eager.py:447flipped the two opt-in dispatcher tests red.This is a deep-sweep test-coverage PR. No source files were modified.
Test plan
pytest xrspatial/geotiff/tests/test_crs_fail_closed_gpu_1929.py(13 passed)pytest xrspatial/geotiff/tests/test_crs_fail_closed_gpu_1929.py xrspatial/geotiff/tests/test_crs_fail_closed_1929.py(47 passed)_writers/gpu.py:507-> 6 tests failallow_unparseable_crsforward at_writers/eager.py:447-> 2 opt-in tests fail