Skip to content

feat: cuda12/cuda13 extras that install CuPy and cuCIM with the CUDA runtime - #60

Merged
alxndrkalinin merged 8 commits into
mainfrom
feat/cuda-extras
Oct 7, 2026
Merged

alxndrkalinin merged 8 commits into
mainfrom
feat/cuda-extras

Conversation

@alxndrkalinin

@alxndrkalinin alxndrkalinin commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

GPU users currently have to pick the right cupy-cudaXXx and cucim-cuXX wheels and install a matching CUDA Toolkit by hand. This PR adds two extras so the choice is one word:

pip install 'cubic[cuda12]'  # cupy-cuda12x[ctk] + cucim-cu12
pip install 'cubic[cuda13]'  # cupy-cuda13x[ctk] + cucim-cu13
  • CuPy's [ctk] extra pulls the CUDA runtime, NVRTC, cuBLAS, cuFFT etc. from PyPI, so only the NVIDIA driver is needed.
  • The two extras are declared conflicting under [tool.uv] conflicts, so uv lock resolves them in separate forks. Because they cannot be installed together, uv sync --all-extras now errors ("Extras cuda12 and cuda13 are incompatible with the declared conflicts"); name extras explicitly instead. CI uses --extra dev / --extra examples and is unaffected. Neither extra is part of all.
  • CuPy is floored at 14, the first release with [ctk]. Without the floor, a numpy<2 environment resolved cupy-cuda12x 13.6.0, which only warns about the missing extra and installs no CUDA libraries.
  • Linux only: cuCIM publishes manylinux wheels only. CUDA 13 needs a Turing or newer GPU (compute capability ≥ 7.5), so Maxwell, Pascal and Volta GPUs need cuda12 even on a CUDA 13 driver. The README says both.
  • On Python 3.10 the lock resolves cucim-cu1x 26.2.1, the last release with cp310 wheels; on 3.11+ it resolves 26.8.0.
  • The CPU-fallback warning and the cuCIM-missing ImportErrors share one install hint naming the extras (the latter pointed to "the GPU extras", which did not exist). The warning now quotes the original import error, since CuPy also raises ImportError when it is installed but cannot load its CUDA libraries.
  • README: replaces the stale "CUDA>=11.x" requirement (CuPy 14 ships wheels for CUDA 12 and 13 only) and documents the extras, plus conda as the auto-detecting alternative.

Why not auto-detect

Checked 2026-10-06:

  • pip install cupy is still a source build: cupy 14.2.0 on PyPI is an sdist only.
  • uv's --torch-backend=auto detects the driver but covers PyTorch packages only, and only in uv pip (astral-sh/uv#16522 is open).
  • PEP 817 wheel variants are a draft, supported by an experimental uv build, and CuPy does not publish variants.
  • conda does auto-detect, which the README now mentions.

Lockfile

uv.lock only gains packages. A name/version diff of the old and new lock shows no existing package version removed or changed. The CPU CI (uv sync --extra dev) does not install any of them.

Testing

On a GPU node (RTX A6000, driver 580.126.20, no nvcc and no LD_LIBRARY_PATH/CUDA_PATH/CUDA_HOME), each extra was installed from the lock into a fresh Python 3.12 env with uv sync --frozen --extra <cudaXX> --extra dev. For each env, a RawKernel was compiled and run, and the GPU-relevant tests were run (tests/test_cuda.py, test_scipy_proxy.py, test_skimage_proxy.py, tests/segmentation, tests/metrics):

extra CuPy / cuCIM CUDA runtime / NVRTC pytest
cuda12 14.2.0 / 26.08.00 12.9 / 12.8 610 passed, 38 skipped
cuda13 14.2.0 / 26.08.00 13.2 / 13.4 610 passed, 38 skipped

None of the skips is "GPU not available". All are optional packages missing from these envs (torch, torchmetrics, itk, cellpose). The GPU run used 65d19c8. The later commits add the CuPy floor (same resolved versions: cupy 14.2.0) and change only messages, the README and a new warning test.

🤖 Generated with Claude Code

https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT

Summary by Sourcery

Provide streamlined CUDA 12 and CUDA 13 installation options with bundled runtime dependencies and clearer GPU setup guidance.

New Features:

  • Add Linux CUDA 12 and CUDA 13 extras that install compatible CuPy, cuCIM, and CUDA runtime dependencies.

Bug Fixes:

  • Improve GPU import failures and cuCIM errors by preserving the cause and providing actionable installation guidance.

Enhancements:

  • Document CUDA extra selection, driver requirements, GPU compatibility, and conda as an alternative installation path.
  • Prevent the mutually exclusive CUDA extras from being resolved together.

Documentation:

  • Update installation and dependency documentation to replace the outdated CUDA requirement and explain the new GPU setup.

Tests:

  • Add coverage for GPU initialization warnings when CuPy cannot be imported.

alxndrkalinin and others added 3 commits October 6, 2026 16:45
pip and uv still cannot pick a CuPy build for the installed driver, so
GPU users had to find the right cupy-cudaXXx and cucim-cuXX wheels and a
matching CUDA Toolkit themselves. The extras pull both packages for one
CUDA major version, with CuPy's [ctk] extra supplying the CUDA runtime
and NVRTC from PyPI, so only the driver is needed. They are declared
conflicting for uv and kept out of `all`. The README replaces the stale
"CUDA>=11.x" requirement; CuPy 14 ships wheels for CUDA 12 and 13 only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
The CPU-fallback warning gave no install hint, and the cuCIM ImportError
pointed to "the GPU extras", which did not exist until now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
[tool.uv] conflicts is read by uv alone; pip installs both extras when
asked. Also drops the closing CPU-fallback sentence, which repeated the
[optional] marker in the dependency list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
@sourcery-ai

sourcery-ai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds CUDA 12 and CUDA 13 extras that install matching CuPy/cuCIM packages together with CUDA runtime libraries, uses uv conflict metadata to keep the alternatives separate, updates the lockfile, and documents the driver-only GPU setup with clearer missing-dependency guidance.

Flow diagram for selecting CUDA extras

flowchart TD
    Start[Choose highest CUDA major version supported by nvidia-smi] --> CUDA12{CUDA 12.x?}
    CUDA12 -->|Yes| Install12["Install cubic[cuda12]"]
    CUDA12 -->|No| CUDA13{CUDA 13.x?}
    CUDA13 -->|Yes| Install13["Install cubic[cuda13]"]
    CUDA13 -->|No| Alternative[Use conda for CUDA-aware dependency selection]
    Install12 --> Driver[Only NVIDIA driver required]
    Install13 --> Driver
    Install12 --> GPU[CuPy and cuCIM GPU support]
    Install13 --> GPU
Loading

File-Level Changes

Change Details Files
Add mutually exclusive CUDA 12 and CUDA 13 installation extras that bundle CuPy, cuCIM, and CUDA runtime dependencies.
  • Declare cuda12 and cuda13 extras using the corresponding CuPy [ctk] runtime packages and cuCIM wheels.
  • Configure uv to resolve the CUDA extras in separate conflict forks while keeping them out of all.
  • Extend the lockfile with platform/Python-compatible CUDA dependency resolutions without changing existing package versions.
pyproject.toml
uv.lock
Document the new GPU installation model and its driver/toolkit requirements.
  • Replace the broad CUDA Toolkit requirement with NVIDIA driver support for CUDA 12 or 13.
  • Document pip commands, the one-extra limitation, runtime libraries supplied from PyPI, and conda as an auto-detecting alternative.
README.md
Improve runtime guidance when optional GPU dependencies are unavailable.
  • Point CPU fallback warnings to the new CUDA extras.
  • Replace the nonexistent generic GPU-extras reference in cuCIM errors with explicit installation commands.
cubic/cuda.py
cubic/segmentation/segment_utils.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The installation documentation omits that the cuCIM-based extras are Linux-only.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Adds CUDA 12/13 installation extras with bundled runtime dependencies and clearer GPU setup guidance.

Changes:

  • Adds mutually exclusive cuda12 and cuda13 extras.
  • Updates lockfile dependencies and GPU-related messages.
  • Documents CUDA installation options.
File Description
pyproject.toml Defines CUDA extras and uv conflicts.
uv.lock Locks CuPy, cuCIM, and CUDA runtime packages.
README.md Documents GPU installation.
cubic/​cuda.py Improves CPU-fallback guidance.
cubic/​segmentation/​segment_utils.py Updates missing-cuCIM errors.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread README.md Resolved

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="pyproject.toml" line_range="68" />
<code_context>
+# driver is needed. Not part of `all`, since the two are mutually exclusive.
+cuda12 = [
+    "cupy-cuda12x[ctk]",
+    "cucim-cu12",
+]
+cuda13 = [
</code_context>
<issue_to_address>
**Windows GPU installs fail**

When a Windows user installs either CUDA extra, the `cucim-cu12` and `cucim-cu13` distributions have no compatible Windows wheels, so pip or uv cannot resolve the extra and the documented GPU install fails.

Provide Windows-compatible cuCIM distributions or make the Windows limitation explicit and adjust the extras so installation does not fail.

Also at `pyproject.toml:72`, `README.md:32-37`.
</issue_to_address>

### Comment 2
<location path="pyproject.toml" line_range="84" />
<code_context>

+[tool.uv]
+conflicts = [
+    [{ extra = "cuda12" }, { extra = "cuda13" }],
+]
+
</code_context>
<issue_to_address>
**All-extras sync is rejected**

When a user runs `uv sync --all-extras`, uv selects both CUDA extras, and `[tool.uv].conflicts` rejects the sync, so the environment is not created.

Change the extras and uv configuration so `uv sync --all-extras` can resolve both CUDA variants.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and the new extras install large third-party CuPy, cuCIM, and CUDA runtime dependency trees, so an incorrect resolution can leave incompatible packages or CUDA libraries in a user's environment after the PR is reverted. This is bounded and repairable by uninstalling the extras or recreating the environment; no application data or irreversible external action is changed.

Blocking findings: pyproject.toml:68, pyproject.toml:84


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread pyproject.toml Resolved
Comment thread pyproject.toml Resolved
alxndrkalinin and others added 5 commits October 6, 2026 17:03
Without a floor, an environment pinned to numpy<2 resolved
cupy-cuda12x 13.6.0, which has no [ctk] extra: pip and uv only warn
and install no CUDA libraries, so the first kernel compile fails. With
the floor the resolution fails up front instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
…ssages

The CPU-fallback warning and both cuCIM ImportErrors spelled out the
extras separately; the earlier "GPU extras" wording went stale that way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
CuPy raises ImportError when it is installed but cannot load its CUDA
libraries, and cuCIM when a dependency is missing, so "not installed"
was wrong in those cases and the install hint useless. The warning now
quotes the original error; the test forces a failed cupy import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
CUDA 13 dropped Maxwell, Pascal and Volta (compute capability < 7.5),
so a V100 on a 580 driver reports CUDA 13 yet needs cuda12. cuCIM
publishes Linux wheels only, and an existing cupy-cuda* package in the
environment clashes with the one an extra installs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
`.[all]` was labelled "install everything" but leaves out the GPU
extras, which cannot be combined.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hEQ1TZJUbmhYKcC14RYHT
@alxndrkalinin
alxndrkalinin merged commit fabb8a3 into main Oct 7, 2026
9 checks passed
@alxndrkalinin
alxndrkalinin deleted the feat/cuda-extras branch October 7, 2026 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants