💥 Support reading into CuPy arrays via cog3pio xarray backend#71
Draft
weiji14 wants to merge 15 commits into
Draft
💥 Support reading into CuPy arrays via cog3pio xarray backend#71weiji14 wants to merge 15 commits into
weiji14 wants to merge 15 commits into
Conversation
Get list of x and y coordinates for the TIFF image from Python-side.
Rough attempt to include CudaCogReader as the default reader inside Cog3pioBackendEntrypoint, via a `use_cuda` flag that defaults to True. Handle the reshaping of the cupy.ndarray from 1-D to 3-D based on info from .xy_coords method. Temporarily fallback to CPU-based reader in unit test to work on CI.
Allow setting the device_id to decode TIFFs on a specific CUDA GPU device (default is device_id=0). Also added a missing `import cog3pio` in test_xarray_backend.py
Trying to conform to DLPack standard a bit better, by having the device be set using a (device_type, device_id) tuple. Note that device_id is being passed into the CudaCogReader struct/class, rather than at xp.from_dlpack whose `device` parameter expects a library-specific device object. Considered supported library-specific device objects (e.g. cupy.cuda.Device, torch.device), but they have different attributes, so using this DLPack device tuple that should be more forward compatible. Updated test_xarray_backend_open_dataarray unit test to ensure both CPU and CUDA decode paths are tested.
weiji14
added a commit
that referenced
this pull request
Feb 17, 2026
dl_device will be handled in #71, copy another time.
weiji14
added a commit
that referenced
this pull request
Feb 17, 2026
* ➕ Add pyo3-stub-gen and pyo3-stub-gen-derive Stub file (*.pyi) generator for PyO3! Crates at https://crates.io/crates/pyo3-stub-gen and https://crates.io/crates/pyo3-stub-gen-derive * 🔨 Create python stub file generator script Xref https://github.com/Jij-Inc/pyo3-stub-gen/tree/0.19.0?tab=readme-ov-file#generate-a-stub-file. Also need to bump MSRV from 1.85.0 to 1.91.0 to fix complain about macro `gen_stub_pyclass` and `gen_stub_pymethods` having some "item is stable in a `const` context since `1.91.0`". * ⬆️ Bump MSRV from 1.85.0 to 1.91.0 To satisfy `gen_stub_pyclass` and `gen_stub_pymethods` macros. * 💚 Add missing pyo3 feature flag To fix `error[E0433]: failed to resolve: could not find `python` in the crate root`. * 👷 Add mypy stubtest CI check Validate that stub files match runtime behaviour. Xref https://github.com/Jij-Inc/pyo3-stub-gen/tree/0.19.0?tab=readme-ov-file#advanced-mypystubtest-integration and https://mypy.readthedocs.io/en/stable/stubtest.html#automatic-stub-testing-stubtest * 🏷️ Fix or ignore some type hint errors Mostly in the xarray_backend.py file. Also added unit test to check cog3pio.__doc__ attribute, and sneaked in a small addition to .release-plz.toml * 💚 Type hint returned DLPack tensor as types.PyCapsule Fix `error: Argument 1 to "from_dlpack" has incompatible type "CogReader"; expected "_SupportsDLPack[None]" [arg-type]` by properly setting return type from __dlpack__ method as types.CapsuleType. Also need to add stream parameter to satisfy numpy.from_dlpack, xref https://github.com/numpy/numpy/blob/v2.4.2/numpy/__init__.pyi#L1075-L1077 * 🏷️ Generate type stubs for CudaCogReader Finalize type hint generation for the cog3pio API surface. Needed to reorganize feature gates a bit to make `pyo3` flag mandatory for type stub generation, while `cuda` remains optional. Also fixed an incorrect intersphinx type hint in src/python/adapters.rs. * 📝 Parse 🏷️ under Documentation section in changelog * 🍻 Run stubtest with cuda feature enabled To fix `error: cog3pio.CudaCogReader is not present at runtime` * 🔇 Silence clippy error about unused variable: `kwargs` dl_device will be handled in #71, copy another time.
Was trying to be lazy by setting a default `device_id=0` value in the pyo3 signature instead of doing a proper Option<>, but this causes a lot of nasty `rust-lld: error: undefined symbol: Py` linker errors on pyo3, so removing that for now. Also making sure to set the both cuda AND pyo3 flags for the cudacog stub_info.
Only handle default case of `copy=None` for now (copy=True/False implementation is trickier based on https://data-apis.org/array-api/2025.12/design_topics/copies_views_and_mutation.html#copy-keyword-argument-behavior). This means kwargs is no longer needed in the CudaCogReader.__dlpack__ signature. Updated docstrings for the `copy` and `dl_device` params section, and also the raises error section.
Regenerate pyi stubs for the cuda related stuff, and fix or ignore some static type check errors (especially on the xarray backend entrypoint). Updated some unit tests to have `device_id=0` passed to CudaCogReader (needed for local testing rather than CI). Also fix some exotic arch (ppc64le/armv7/s390x) tests that seem to be pulling the top-level package docstring from the comment on top of #[pymodule] of the rust file instead of the __init__.py file.
Include some more instructions to deal with installing nvTIFF and patching the header file. Added some new 'CUDA' tabs on the quickstart page to teach reading into cupy arrays via CudaCogReader or xarray, mentioning that `device_id` or `device` needs to be set appropriately.
Take out async-tiff refactor since async-geotiff is out. Want to double-down more on hardware-accelerated decoding instead.
weiji14
marked this pull request as ready for review
March 3, 2026 10:38
weiji14
marked this pull request as draft
March 5, 2026 02:08
weiji14
added a commit
to xarray-contrib/cupy-xarray
that referenced
this pull request
Mar 5, 2026
Read TIFF data into xarray via cog3pio's experimental CudaCogReader struct that uses nvTIFF as its backend. Use cupy.from_dlpack to read the DLPack tensor, and reshape the 1-D array into a 3-D array (CHW form), setting the coordinates as appropriate. Added some API docs and basic unit tests. Cherry-picked from weiji14/cog3pio#71
9 tasks
Owner
Author
|
Thinking that the Cog3pioBackendEntrypoint code should just live in cupy-xarray, so opened xarray-contrib/cupy-xarray#70. Considering to eventually deprecate xarray as a dependency in this repo. |
3 tasks
Revert unneeded change from e4e94df
2 tasks
This was referenced Apr 7, 2026
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.
Proof of concept interface to read TIFF data into an
xarray.DataArrayvia Cog3pioBackendEntrypoint. Handles reshaping of the 1-D array returned fromCudaCogReaderinto a proper 3-D array of shape (Channels, Height, Width).Preview at https://cog3pio--71.org.readthedocs.build/en/71/api/#cog3pio.xarray_backend.Cog3pioBackendEntrypoint
Example usage:
TODO:
xy_coordsmethod onPyCudaCogReaderstruct (cherry-picked to ✨ Implement xy_coords method on PyCudaCogReader struct #82)xarray.open_dataarray(..., engine="cog3pio")to read TIFF data into CuPy-backed arrays in xarray.Notes:
use_cudaflag doesn't feel very ergonomic or future proof. Am thinking that there could be some way to conform better to the array API standard, by letting users to set adevicewhich is passed totheedit: no, device should be set when DLPack object is instantiated. This means users can control where the TIFF data is decoded, be it CPU or a CUDA GPU (with a specific GPU id?)from_dlpack()method somehowReferences:
Closes #26