Skip to content

Build CUDA-enabled Python wheels on Linux and Windows - #274

Merged
zfergus merged 6 commits into
mainfrom
ci/cuda-wheels
Oct 15, 2026
Merged

zfergus merged 6 commits into
mainfrom
ci/cuda-wheels

Conversation

@zfergus

@zfergus zfergus commented Oct 14, 2026

Copy link
Copy Markdown
Member

Description

Builds the ipctk wheels with CUDA on Linux x86_64 and Windows, and adds a runtime check for whether the GPU code can run. macOS wheels stay CPU-only.

  • Toolkit: CUDA 12.8. CUDA 13.x would require driver 580 or newer; 12.x needs 525 or newer.
    • Linux: cuda-nvcc, cuda-cudart-devel, and cuda-cccl from NVIDIA's rhel8 repo, installed inside the manylinux_2_28 container (GCC 14).
    • Windows: Jimver/cuda-toolkit, then msvc-dev-cmd, and the build uses Ninja instead of the Visual Studio generator, as cuda.yml does.
  • Architectures: 75-real;80-real;86-real;90-real;100-real;120-real;120-virtual. Turing through Blackwell get SASS, and newer GPUs can JIT from the sm_120 PTX.
  • Runtime: static cudart (the CMake default). The wheel needs only the NVIDIA driver, and auditwheel has no libcudart to bundle.

Impacts:

  • pip install ipctk gets ipctk.cuda.LBVH on Linux and Windows.
  • On a machine without a GPU or driver, the wheel still imports. Using a GPU class raises RuntimeError.
  • Windows wheels now build on windows-2022, because windows-latest ships MSVC 19.51 (VS 2026), which CUDA 12.8 rejects.

API changes

  • New ipc::cuda::is_available() (ipc/utils/cuda/is_available.hpp) and ipctk.cuda.is_available().
    • Returns true when cudaGetDeviceCount succeeds with at least one device.
    • Always defined; returns false in non-CUDA builds.

CI

  • pypi.yml now runs on pull requests that touch the wheel build. The upload_pypi job is skipped for them.
  • Each Linux and Windows wheel runs python/tests/check_cuda_wheel.py on the GPU-less runner. It asserts the wheel is a CUDA build, that is_available() is False, and that LBVH.build raises instead of crashing.
  • A step lists each wheel's size in the job summary and fails if any wheel exceeds PyPI's 100 MB limit.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • [utils][cuda] Catch2 test: in CUDA builds, is_available() predicts whether cuda::LBVH builds and detects or throws. In CPU builds, it is false. cuda.yml runs the GPU path on its simulated T4.
  • python/tests/test_cuda.py: the same behavior from Python. python.yml runs it on CPU builds.
  • Locally (macOS, Apple Clang, Release, CPU-only): both tests pass, and check_cuda_wheel.py correctly rejects the CPU build.
  • pypi.yml CUDA wheels build and pass the no-GPU check (this PR's CI).

Checklist

  • My code follows the clang-format style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

zfergus and others added 5 commits October 14, 2026 17:26
- Install CUDA 12.8 in the manylinux container and on a VS 2022 runner
- Target sm_75 through sm_120 SASS plus sm_120 PTX
- Add ipctk.cuda.is_available() (ipc::cuda::is_available() in C++)
- Check each CUDA wheel imports and raises without a GPU
- Fail the build if a wheel exceeds PyPI's 100 MB limit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.92%. Comparing base (4e8173d) to head (3fba971).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #274   +/-   ##
=======================================
  Coverage   96.92%   96.92%           
=======================================
  Files         194      194           
  Lines       17349    17349           
  Branches      943      943           
=======================================
+ Hits        16815    16816    +1     
+ Misses        534      533    -1     
Flag Coverage Δ
unittests 96.92% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

pybind11's -flto reaches nvcc's device-link step, and GCC's LTO drops the
fatbinData symbol the stub defines in top-level asm, so the Linux module
failed to import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zfergus
zfergus merged commit f67f4ca into main Oct 15, 2026
36 checks passed
@zfergus
zfergus deleted the ci/cuda-wheels branch October 15, 2026 01:32
@zfergus zfergus added this to the v2.0.0 milestone Oct 15, 2026
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.

1 participant