Add xfail'd GPU and dask+GPU pack=True round-trip tests (#3114)#3127
Merged
Conversation
unpack=True reads work on gpu and dask+gpu since #3075, but nothing in the suite packed a GPU-read array back with to_geotiff(pack=True). Both legs crash today (#3112), so the new tests run behind requires_gpu and xfail(strict=True) against that issue; they flip to failures the moment the _pack fillna crash is fixed. Also fixes the test module docstring, which still said GPU rejects mask_and_scale. Sweep state CSV updated for the geotiff module.
brendancol
commented
Jun 9, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Add xfail'd GPU and dask+GPU pack=True round-trip tests (#3114)
Blockers (must fix before merge)
- None.
Suggestions (should fix, not blocking)
-
xrspatial/geotiff/tests/write/test_pack_3064.py:160-- the barexfail(strict=True)absorbs any failure, not just the #3112 crash. The assert at line 173 (mask_and_scale_dtype == "uint8") runs before the pack call, so a GPU read-side regression that drops the attr would xfail silently and look like the known bug. Pin the expected failure withraises=(AttributeError, TypeError)so an unrelated assertion failure surfaces as a real failure instead.
Nits (optional improvements)
- The two failure modes in #3112 may be version-dependent (the eager leg matches the known cupy 13.6 / xarray 2025.12
where/astypeincompatibility). If a GPU CI host carries different pins wherefillnaworks,strict=Trueturns an accidental pass into a CI failure. That failure would be informative (it means the env, not the code, decided the outcome), so keeping strict seems right -- but watch the first GPU CI run.
What looks good
- The tests were executed on a CUDA host and observed to fail for the exact #3112 crash before the xfail was applied; 13 passed, 2 xfailed.
- Parametrization, tmp-file naming (
*_3114),requires_gpugating, and the_write_int_tifffixture reuse all match the surrounding file. - The stale module docstring (claiming GPU rejects
mask_and_scale) is corrected in the same place the new coverage lands. - Test-only: no source changes, the fix stays with #3112.
Checklist
- Algorithm matches reference (round-trip parity asserted against the CPU eager path)
- All implemented backends produce consistent results (gpu/dask+gpu pinned as xfail on #3112)
- NaN handling is correct (sentinel -> NaN -> sentinel round-trip asserted with equal_nan)
- Edge cases covered (scale/offset + sentinel in one fixture)
- Dask chunk boundaries handled (chunks=2 leg)
- No premature materialization (np.asarray only on results under test)
- Benchmark not needed (test-only PR)
- README feature matrix unchanged (no API change)
- Docstrings accurate after the stale-claim fix
Review follow-up: a bare strict xfail would absorb any failure, including a GPU read-side regression in the mask_and_scale_dtype attr assert that runs before the pack call. raises=(AttributeError, TypeError) keeps unrelated failures visible.
brendancol
commented
Jun 9, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
Follow-up review after 5751a11:
- The one suggestion is addressed: the xfail now carries
raises=(AttributeError, TypeError)with a comment mapping each exception to its backend leg, so an unrelated assertion failure (e.g. the attr check before the pack call) surfaces instead of hiding under the known #3112 crash. - Re-ran the file on the CUDA host: 13 passed, 2 xfailed.
- The nit (strict xfail vs possible GPU CI dependency pins) stands as a watch item for the first GPU CI run, not a change request.
No remaining findings.
Contributor
Author
|
@copilot resolve the merge conflicts in this pull request |
…age-geotiff-2026-06-09 # Conflicts: # .claude/sweep-test-coverage-state.csv
Contributor
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.
test_pack_round_trip_gputotests/write/test_pack_3064.py, parametrized over eager GPU and dask+GPU reads:open_geotiff(unpack=True, gpu=True[, chunks=2])followed byto_geotiff(pack=True), asserting the uint8 source ints round-trip and the repacked file unpacks to the same values as the CPU path._pack'sfillnabreaks on cupy-backed arrays), so the tests run behindrequires_gpuwithxfail(strict=True, raises=(AttributeError, TypeError))against that issue — pinning to the known exception types so unrelated assertion failures surface as real failures instead of hiding under the known crash. When the crash is fixed they flip to hard failures and the marker comes off.mask_and_scale; that has been stale since Rename open_geotiff mask_and_scale to unpack and add GPU / dask+GPU support #3075.Test-only change; the source fix stays with #3112.
Backend coverage: numpy and dask+numpy were already tested; this adds the cupy and dask+cupy legs (currently xfail).
Proposed Changes
test_pack_round_trip_gpuparametrized over eager GPU and dask+GPU backends, gated byrequires_gpuwithxfail(strict=True, raises=(AttributeError, TypeError))pinned to the to_geotiff(pack=True) crashes on cupy and dask+cupy input #3112 crash.xfailtoraises=(AttributeError, TypeError)so unrelated failures (e.g. a GPU read-side regression dropping themask_and_scaleattr) surface as real failures rather than silently matching the known bug.mask_and_scale..claude/sweep-test-coverage-state.csvfor the geotiff module.origin/maininto branch, resolving conflict in.claude/sweep-test-coverage-state.csv(kept our updated geotiff row; took main's updated rasterize and reproject rows).Test plan:
pytest xrspatial/geotiff/tests/write/test_pack_3064.pyon a CUDA host: 13 passed, 2 xfailed