From 7aa10b7b9458f21d4c1a69cde2f3493f7de0175e Mon Sep 17 00:00:00 2001 From: Ralf Juengling Date: Mon, 28 Sep 2026 15:03:12 -0700 Subject: [PATCH 1/3] ci: switch cibuildwheel to uv as the build frontend Use build[uv] with UV_* constraint env vars so isolated builds pin the local pathfinder/bindings wheels. Drop pip before-build hooks; uv venvs do not include pip, and cibuildwheel 4 already installs delvewheel. --- .github/workflows/build-wheel.yml | 40 +++++++++++++++++-------------- cuda_bindings/pyproject.toml | 1 - cuda_core/pyproject.toml | 1 - 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml index 09a8b00e952..656d6867692 100644 --- a/.github/workflows/build-wheel.yml +++ b/.github/workflows/build-wheel.yml @@ -227,16 +227,18 @@ jobs: with: package-dir: ./cuda_bindings/ output-dir: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }} + extras: uv env: CIBW_BUILD: ${{ env.CIBW_BUILD }} - CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"' - CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel' + # build[uv]: same PEP 517 orchestration, with uv instead of pip. + # extras: uv puts uv on PATH (required on Windows). + CIBW_BUILD_FRONTEND: "build[uv]" # CIBW mounts the host filesystem under /host CIBW_ENVIRONMENT_LINUX: > CUDA_PATH=/host/${{ env.CUDA_PATH }} CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} - PIP_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt - PIP_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt + UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -248,8 +250,8 @@ jobs: CIBW_ENVIRONMENT_WINDOWS: > CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})" CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} - PIP_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" - PIP_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" + UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" # check cache stats before leaving cibuildwheel CIBW_BEFORE_TEST_LINUX: > "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && @@ -327,17 +329,18 @@ jobs: with: package-dir: ./cuda_core/ output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }} + extras: uv env: CIBW_BUILD: ${{ env.CIBW_BUILD }} - CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"' - CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel' + # See the cuda.bindings step above for UV_* vs PIP_*. + CIBW_BUILD_FRONTEND: "build[uv]" # CIBW mounts the host filesystem under /host CIBW_ENVIRONMENT_LINUX: > CUDA_PATH=/host/${{ env.CUDA_PATH }} CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} - PIP_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt - PIP_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt + UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -350,8 +353,8 @@ jobs: CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})" CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} - PIP_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" - PIP_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" + UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" # check cache stats before leaving cibuildwheel CIBW_BEFORE_TEST_LINUX: > "/host${{ env.SCCACHE_PATH }}" --show-adv-stats && @@ -614,17 +617,18 @@ jobs: with: package-dir: ./cuda_core/ output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }} + extras: uv env: CIBW_BUILD: ${{ env.CIBW_BUILD }} - CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"' - CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel' + # See the cuda.bindings step above for UV_* vs PIP_*. + CIBW_BUILD_FRONTEND: "build[uv]" # CIBW mounts the host filesystem under /host CIBW_ENVIRONMENT_LINUX: > CUDA_PATH=/host/${{ env.CUDA_PATH }} CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} - PIP_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt - PIP_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt + UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -637,8 +641,8 @@ jobs: CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})" CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} - PIP_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" - PIP_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" + UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" # check cache stats before leaving cibuildwheel CIBW_BEFORE_TEST_LINUX: > "/host${{ env.SCCACHE_PATH }}" --show-adv-stats && diff --git a/cuda_bindings/pyproject.toml b/cuda_bindings/pyproject.toml index 10e9f5e2fb1..f628f7b2e1a 100644 --- a/cuda_bindings/pyproject.toml +++ b/cuda_bindings/pyproject.toml @@ -85,7 +85,6 @@ build-verbosity = 1 archs = "native" [tool.cibuildwheel.windows] -before-build = "pip install delvewheel" repair-wheel-command = "delvewheel repair --namespace-pkg cuda -w {dest_dir} {wheel}" [tool.pytest.ini_options] diff --git a/cuda_core/pyproject.toml b/cuda_core/pyproject.toml index 33f72e22dea..9c3173cdfcb 100644 --- a/cuda_core/pyproject.toml +++ b/cuda_core/pyproject.toml @@ -152,5 +152,4 @@ build-verbosity = 1 archs = "native" [tool.cibuildwheel.windows] -before-build = "pip install delvewheel" repair-wheel-command = "delvewheel repair --namespace-pkg cuda --exclude \"torch_cpu.dll;torch_python.dll\" -w {dest_dir} {wheel}" From b574e83775f4591120dc1fc9c035b10641b67a4b Mon Sep 17 00:00:00 2001 From: Ralf Juengling Date: Mon, 28 Sep 2026 15:03:50 -0700 Subject: [PATCH 2/3] ci: drop dummy cibuildwheel tests used only for sccache stats Dump sccache during Linux wheel repair instead of installing the wheel just to echo ok. UV_CONSTRAINT is unused without that test install. --- .github/workflows/build-wheel.yml | 46 ++++++++++--------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml index 656d6867692..4a10d299782 100644 --- a/.github/workflows/build-wheel.yml +++ b/.github/workflows/build-wheel.yml @@ -238,7 +238,6 @@ jobs: CUDA_PATH=/host/${{ env.CUDA_PATH }} CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt - UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -251,16 +250,11 @@ jobs: CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})" CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" - UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" - # check cache stats before leaving cibuildwheel - CIBW_BEFORE_TEST_LINUX: > + # Dump sccache stats during repair; no dummy test stage. + CIBW_REPAIR_WHEEL_COMMAND_LINUX: > "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && - "/host/${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_bindings.json - # force the test stage to be run (so that before-test is not skipped) - # TODO: we might want to think twice on adding this, it does a lot of - # things before reaching this command. - CIBW_TEST_COMMAND: > - echo "ok!" + "/host/${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_bindings.json && + auditwheel repair -w {dest_dir} {wheel} - name: Report sccache stats (cuda.bindings) if: ${{ env.BUILD_BINDINGS == 'true' && !startsWith(inputs.host-platform, 'win') }} @@ -340,7 +334,6 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt - UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -354,16 +347,11 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" - UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" - # check cache stats before leaving cibuildwheel - CIBW_BEFORE_TEST_LINUX: > - "/host${{ env.SCCACHE_PATH }}" --show-adv-stats && - "/host${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_core.json - # force the test stage to be run (so that before-test is not skipped) - # TODO: we might want to think twice on adding this, it does a lot of - # things before reaching this command. - CIBW_TEST_COMMAND: > - echo "ok!" + # Dump sccache stats during repair; no dummy test stage. + CIBW_REPAIR_WHEEL_COMMAND_LINUX: > + "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && + "/host/${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_core.json && + auditwheel repair -w {dest_dir} {wheel} - name: Report sccache stats (cuda.core) if: ${{ env.BUILD_CORE == 'true' && !startsWith(inputs.host-platform, 'win') }} @@ -628,7 +616,6 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt - UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -642,16 +629,11 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" - UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" - # check cache stats before leaving cibuildwheel - CIBW_BEFORE_TEST_LINUX: > - "/host${{ env.SCCACHE_PATH }}" --show-adv-stats && - "/host${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_core_prev.json - # force the test stage to be run (so that before-test is not skipped) - # TODO: we might want to think twice on adding this, it does a lot of - # things before reaching this command. - CIBW_TEST_COMMAND: > - echo "ok!" + # Dump sccache stats during repair; no dummy test stage. + CIBW_REPAIR_WHEEL_COMMAND_LINUX: > + "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && + "/host/${{ env.SCCACHE_PATH }}" --show-stats --stats-format=json > /host/${{ github.workspace }}/sccache_core_prev.json && + auditwheel repair -w {dest_dir} {wheel} - name: Report sccache stats (cuda.core prev) if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' && !startsWith(inputs.host-platform, 'win') }} From 089b12bb2e7f6300c878eca0e7853506d837207e Mon Sep 17 00:00:00 2001 From: Ralf Juengling Date: Tue, 29 Sep 2026 11:02:15 -0700 Subject: [PATCH 3/3] ci: restore UV_CONSTRAINT for build-requirement resolution build --installer=uv calls "uv pip install ", a regular install where UV_CONSTRAINT applies, not UV_BUILD_CONSTRAINT. cuda.core dynamically requires cuda-bindings==13.* as a build dep; for py3.15 there is no cp315 wheel on PyPI, so the local-wheel constraint is mandatory. Removing UV_CONSTRAINT broke all 3.15 builds. --- .github/workflows/build-wheel.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml index 4a10d299782..d1a6d156d91 100644 --- a/.github/workflows/build-wheel.yml +++ b/.github/workflows/build-wheel.yml @@ -238,6 +238,7 @@ jobs: CUDA_PATH=/host/${{ env.CUDA_PATH }} CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-bindings.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -250,6 +251,7 @@ jobs: CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})" CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-bindings.txt)" # Dump sccache stats during repair; no dummy test stage. CIBW_REPAIR_WHEEL_COMMAND_LINUX: > "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && @@ -334,6 +336,7 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -347,6 +350,7 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core.txt)" # Dump sccache stats during repair; no dummy test stage. CIBW_REPAIR_WHEEL_COMMAND_LINUX: > "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats && @@ -616,6 +620,7 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} UV_BUILD_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt + UV_CONSTRAINT=/host/${{ github.workspace }}/wheel-constraints/cuda-core-prev.txt CC="/host/${{ env.SCCACHE_PATH }} cc" CXX="/host/${{ env.SCCACHE_PATH }} c++" SCCACHE_GHA_ENABLED=true @@ -629,6 +634,7 @@ jobs: CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }} CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }} UV_BUILD_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" + UV_CONSTRAINT="$(cygpath -w ./wheel-constraints/cuda-core-prev.txt)" # Dump sccache stats during repair; no dummy test stage. CIBW_REPAIR_WHEEL_COMMAND_LINUX: > "/host/${{ env.SCCACHE_PATH }}" --show-adv-stats &&