Skip to content

Fix read_geotiff_gpu byteswap on big-endian multi-byte TIFFs#1515

Open
brendancol wants to merge 1 commit intoxarray-contrib:mainfrom
brendancol:fix-1508-gpu-byteswap
Open

Fix read_geotiff_gpu byteswap on big-endian multi-byte TIFFs#1515
brendancol wants to merge 1 commit intoxarray-contrib:mainfrom
brendancol:fix-1508-gpu-byteswap

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Closes #1508.

cupy.ndarray (13.x) has no .byteswap() method, so any big-endian multi-byte TIFF was hitting AttributeError inside the GPU decode pipeline. The outer try/except in read_geotiff_gpu ate the error and quietly fell back to CPU, so users got correct results but lost the GPU fast path on BE data.

This swaps both arr.byteswap() calls in _gpu_decode.py for a small helper that views the array as the swapped-order dtype and copies. Works on both.

What changed

  • _gpu_decode.py: added _xp_byteswap(arr) helper, called at the two BE byteswap sites.
  • tests/test_gpu_byteswap_1508.py: new GPU regression test. Reads a BE TIFF (uint16, int16, uint32, int32, plus uncompressed uint16) via read_geotiff_gpu, asserts the result is a CuPy DataArray (not a NumPy fallback from a swallowed crash), and matches the CPU read.

Out of scope

The outer try/except Exception in read_geotiff_gpu that turns GPU errors into silent CPU fallback is itself worth revisiting; that's how this bug went undetected. Not touching it here. Filing as a follow-up.

GPU predictor=2 on BE data is also broken, but in a separate way: the predictor kernel decodes the byte stream as native LE before the byteswap. That's a kernel-level issue, not a byteswap one. Also a follow-up.

Test plan

  • pytest xrspatial/geotiff/tests/test_gpu_byteswap_1508.py -q -> 5 passed
  • pytest xrspatial/geotiff/tests/ -q -> 695 passed, 4 skipped (3 pre-existing matplotlib palette failures unrelated)

cupy.ndarray (13.x) does not expose .byteswap(), so any BE multi-byte
TIFF hit AttributeError inside the GPU decode pipeline. The dispatcher
in read_geotiff_gpu caught it and silently fell back to CPU, so output
stayed correct but the GPU path was effectively dead for BE data.

Replace both arr.byteswap() calls with a small helper that views the
array as the swapped-order dtype and copies, which works on numpy and
cupy arrays alike.

Closes xarray-contrib#1508
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GPU read of big-endian multi-byte TIFFs crashes on cupy.ndarray.byteswap()

1 participant