Skip to content

geotiff: extract GPU helpers to _backends/_gpu_helpers.py (#1884)#1894

Merged
brendancol merged 1 commit into
mainfrom
issue-1884
May 15, 2026
Merged

geotiff: extract GPU helpers to _backends/_gpu_helpers.py (#1884)#1894
brendancol merged 1 commit into
mainfrom
issue-1884

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Step 6 of #1813's multi-PR refactor of xrspatial/geotiff/__init__.py. Pure code motion; no public API change. First PR to create the _backends/ subpackage.

Created xrspatial/geotiff/_backends/__init__.py (empty placeholder) and moved into _backends/_gpu_helpers.py:

  • _is_gpu_data — cupy-backed array / DataArray detection.
  • _apply_nodata_mask_gpu — cupy mirror of the CPU sentinel→NaN mask, with the same out-of-range / fractional / non-finite skips as _resolve_masked_fill in _reader.py.
  • _gpu_decode_single_band_tiles — two-stage GPU decode (GDS, then CPU-extracted bytes) for the PlanarConfiguration=2 path.
  • _apply_orientation_gpu — cupy mirror of the CPU orientation flip for all eight TIFF Orientation values.
  • _apply_orientation_geo_infoGeoTransform update after an orientation flip, with the geotiff: orientation 5-8 on georeferenced TIFFs returns wrong coords behind a warning #1765 refusal for georeferenced orientations 5–8.
  • _gpu_apply_window_band — post-decode window + band slice on device.

Every helper lazy-imports cupy at call time so the module imports cleanly on numpy-only environments. __init__.py re-imports the six helpers from _backends._gpu_helpers so existing callers (read_geotiff_gpu, to_geotiff's GPU branch, write_geotiff_gpu) keep identical signatures.

The leading-underscore module name (_gpu_helpers.py) is intentional: it keeps _backends/gpu.py free for the read_geotiff_gpu entry-point body in step 7.

Diff stats

  • __init__.py: 4271 → 3969 (-302 lines).
  • New _backends/__init__.py: 8 lines.
  • New _backends/_gpu_helpers.py: 335 lines.

Test plan

Closes #1884. Refs #1813.

Step 6 of #1813's multi-PR refactor of __init__.py. Pure code motion;
no public API change. First PR to create the _backends/ subpackage.

Created xrspatial/geotiff/_backends/__init__.py (empty placeholder)
and moved into _backends/_gpu_helpers.py:

- _is_gpu_data: cupy-backed array / DataArray detection.
- _apply_nodata_mask_gpu: cupy mirror of the CPU sentinel-to-NaN mask
  (handles float and integer arrays, with the same out-of-range /
  fractional / non-finite skips as _resolve_masked_fill in
  _reader.py).
- _gpu_decode_single_band_tiles: two-stage GPU decode (GDS then
  CPU-extracted bytes) for the PlanarConfiguration=2 path.
- _apply_orientation_gpu: cupy mirror of the CPU orientation-flip
  helper for the eight TIFF Orientation tag values.
- _apply_orientation_geo_info: GeoTransform update after an
  orientation flip, with the #1765 refusal for georeferenced
  orientations 5-8.
- _gpu_apply_window_band: post-decode window + band slice on device.

Every helper lazy-imports cupy at call time so the module imports
cleanly on numpy-only environments. __init__.py re-imports the
helpers from _backends._gpu_helpers so existing callers
(read_geotiff_gpu, to_geotiff's GPU branch, write_geotiff_gpu) keep
their identical signatures.

Leading-underscore module name (_gpu_helpers.py) keeps _backends/gpu.py
free for the read_geotiff_gpu entry-point body in step 7.

Net __init__.py change: 4271 -> 3969 lines (-302). _gpu_helpers.py is
335 lines.

Verification: pixel-parity matrix from #1889 (192 cells, all GPU
cells included), runtime identity (9), GPU byteswap (#1508), overview
nodata inheritance (#1739) -- 230/230 pass.

Refs #1813.
Copilot AI review requested due to automatic review settings May 15, 2026 03:32
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the GeoTIFF GPU backend internals by extracting six GPU-only helper functions out of xrspatial/geotiff/__init__.py into a new private _backends/ subpackage, keeping the public API and existing import paths stable via re-exports.

Changes:

  • Added xrspatial/geotiff/_backends/_gpu_helpers.py containing the GPU helper implementations (lazy CuPy imports preserved).
  • Added _backends/__init__.py to establish the new internal subpackage.
  • Updated xrspatial/geotiff/__init__.py to import/re-export the helpers from the new module and removed the inlined implementations.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
xrspatial/geotiff/_backends/_gpu_helpers.py New internal module hosting the extracted GPU helper implementations with lazy CuPy imports.
xrspatial/geotiff/_backends/__init__.py Introduces the internal _backends subpackage (docstring-only placeholder).
xrspatial/geotiff/__init__.py Re-exports the moved GPU helpers and deletes the previous in-file definitions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@brendancol brendancol merged commit 0ad97ff into main May 15, 2026
15 of 16 checks passed
@brendancol brendancol deleted the issue-1884 branch May 15, 2026 04:40
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.

geotiff: extract GPU helpers into _backends/_gpu_helpers.py (#1813 step 6)

2 participants