From e1c425e7ca2b42566cb1b9112fdba30401306c15 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Fri, 31 Jul 2026 01:22:06 -0400 Subject: [PATCH 1/5] ci: add selective wheel test plumbing --- .github/workflows/test-wheel-linux.yml | 92 +++++++++++++++--------- .github/workflows/test-wheel-windows.yml | 87 ++++++++++++++-------- 2 files changed, 115 insertions(+), 64 deletions(-) diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml index 4235e01d321..0e5816552b9 100644 --- a/.github/workflows/test-wheel-linux.yml +++ b/.github/workflows/test-wheel-linux.yml @@ -22,13 +22,18 @@ on: nruns: type: number default: 1 - # When true, cuda.bindings tests (and the Cython tests that depend on - # them) are skipped even when CTK majors match. Callers set this based - # on the output of the detect-changes job in ci.yml so PRs that only - # touch unrelated modules avoid the expensive bindings test suite. - skip-bindings-test: + test-pathfinder: type: boolean - default: false + default: true + test-bindings: + type: boolean + default: true + test-core: + type: boolean + default: true + test-python: + type: boolean + default: true run-id: description: > Workflow run ID to download artifacts from. @@ -159,7 +164,7 @@ jobs: LOCAL_CTK: ${{ matrix.LOCAL_CTK }} PY_VER: ${{ matrix.PY_VER }} SHA: ${{ inputs.sha || github.sha }} - SKIP_BINDINGS_TEST_OVERRIDE: ${{ inputs.skip-bindings-test && '1' || '0' }} + SKIP_BINDINGS_TEST_OVERRIDE: ${{ !inputs.test-bindings && '1' || '0' }} run: ./ci/tools/env-vars test - name: Apply extra matrix environment variables @@ -169,6 +174,7 @@ jobs: run: echo "$MATRIX_ENV" | jq -r 'to_entries[] | "\(.key)=\(.value)"' >> "$GITHUB_ENV" - name: Download cuda-pathfinder build artifacts + if: ${{ inputs.test-pathfinder || inputs.test-bindings || inputs.test-core || inputs.test-python }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: cuda-pathfinder-wheel @@ -177,7 +183,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python build artifacts - if: ${{ env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-python && env.BINDINGS_SOURCE == 'main' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: cuda-python-wheel @@ -186,7 +192,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda.bindings build artifacts - if: ${{ env.BINDINGS_SOURCE == 'main' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE == 'main' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }} @@ -195,7 +202,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python & cuda.bindings build artifacts from the prior branch - if: ${{ env.BINDINGS_SOURCE == 'backport' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE == 'backport' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -220,25 +228,28 @@ jobs: mv $OLD_BASENAME/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"/ rmdir $OLD_BASENAME - gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python - ls -al cuda-python-wheel - mv cuda-python-wheel/*.whl . - rmdir cuda-python-wheel + if ${{ inputs.test-python }}; then + gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python + ls -al cuda-python-wheel + mv cuda-python-wheel/*.whl . + rmdir cuda-python-wheel + fi - name: Display structure of downloaded cuda-python artifacts - if: ${{ env.BINDINGS_SOURCE != 'published' }} + if: ${{ inputs.test-python && env.BINDINGS_SOURCE != 'published' }} run: | pwd ls -lah cuda_python*.whl cuda_pathfinder/ - name: Display structure of downloaded cuda.bindings artifacts - if: ${{ env.BINDINGS_SOURCE != 'published' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE != 'published' }} run: | pwd ls -lahR $CUDA_BINDINGS_ARTIFACTS_DIR - name: Download cuda.bindings Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-bindings && env.SKIP_CYTHON_TEST == '0' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }}-tests @@ -247,12 +258,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.bindings Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-bindings && env.SKIP_CYTHON_TEST == '0' }} run: | pwd ls -lahR $CUDA_BINDINGS_CYTHON_TESTS_DIR - name: Download cuda.core build artifacts + if: ${{ inputs.test-core }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }} @@ -261,12 +273,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core build artifacts + if: ${{ inputs.test-core }} run: | pwd ls -lahR $CUDA_CORE_ARTIFACTS_DIR - name: Download cuda.core Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-core && env.SKIP_CYTHON_TEST == '0' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-tests @@ -275,12 +288,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-core && env.SKIP_CYTHON_TEST == '0' }} run: | pwd ls -lahR $CUDA_CORE_CYTHON_TESTS_DIR - name: Download cuda.core test binaries + if: ${{ inputs.test-core }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-test-binaries @@ -289,6 +303,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core test binaries + if: ${{ inputs.test-core }} run: | pwd ls -lahR $CUDA_CORE_TEST_BINARIES_DIR @@ -304,7 +319,7 @@ jobs: AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache" - name: Enable Scientific Python Nightly Wheels for Python 3.15 - if: ${{ startsWith(matrix.PY_VER, '3.15') }} + if: ${{ (inputs.test-bindings || inputs.test-core) && startsWith(matrix.PY_VER, '3.15') }} run: | echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV" echo "PIP_ONLY_BINARY=numpy" >> "$GITHUB_ENV" @@ -318,7 +333,7 @@ jobs: cuda-version: ${{ matrix.CUDA_VER }} - name: Set up latest cuda_sanitizer_api - if: ${{ env.SETUP_SANITIZER == '1' }} + if: ${{ (inputs.test-bindings || inputs.test-core) && env.SETUP_SANITIZER == '1' }} uses: ./.github/actions/fetch_ctk continue-on-error: false with: @@ -327,6 +342,7 @@ jobs: cuda-components: "cuda_sanitizer_api" - name: Set up compute-sanitizer + if: ${{ inputs.test-bindings || inputs.test-core }} run: setup-sanitizer - name: Set up test repetition on nightly runs @@ -334,7 +350,7 @@ jobs: # ── Standard test steps (skipped for nightly modes) ── - name: Run cuda.pathfinder tests with see_what_works - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} env: CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: see_what_works @@ -342,14 +358,14 @@ jobs: run: run-tests pathfinder - name: Run cuda.bindings tests - if: ${{ inputs.test-mode == 'standard' && env.SKIP_CUDA_BINDINGS_TEST == '0' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-bindings && env.SKIP_CUDA_BINDINGS_TEST == '0' }} env: CUDA_VER: ${{ matrix.CUDA_VER }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} run: run-tests bindings - name: Run cuda.bindings benchmarks (smoke test) - if: ${{ inputs.test-mode == 'standard' && env.SKIP_CUDA_BINDINGS_TEST == '0' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-bindings && env.SKIP_CUDA_BINDINGS_TEST == '0' }} run: | pip install pyperf pushd benchmarks/cuda_bindings @@ -357,25 +373,35 @@ jobs: popd - name: Run cuda.core tests - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-core }} env: CUDA_VER: ${{ matrix.CUDA_VER }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} run: run-tests core - name: Ensure cuda-python installable - if: ${{ inputs.test-mode == 'standard' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-python && env.BINDINGS_SOURCE == 'main' }} run: | - # Subpackages are already installed from CI artifacts; --no-deps keeps - # tag-release cuda-core wheels from being replaced by PyPI pins. + # Package suites install their own dependencies. A metapackage-only + # run has no preceding suite, so resolve its exact cuda-bindings pin + # from this run while allowing its released cuda-core pin from PyPI. + if ${{ inputs.test-bindings || inputs.test-core }}; then + dependency_args=(--no-deps) + else + dependency_args=( + --find-links ./cuda_pathfinder + --find-links "${CUDA_BINDINGS_ARTIFACTS_DIR}" + ) + fi + wheel=$(ls cuda_python*.whl) if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then - pip install --only-binary=:all: --no-deps cuda_python*.whl + pip install --only-binary=:all: "${dependency_args[@]}" "${wheel}" else - pip install --only-binary=:all: --no-deps $(ls cuda_python*.whl)[all] + pip install --only-binary=:all: "${dependency_args[@]}" "${wheel}[all]" fi - name: Install cuda.pathfinder extra wheels for testing - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} run: | set -euo pipefail pushd cuda_pathfinder @@ -384,7 +410,7 @@ jobs: popd - name: Run cuda.pathfinder tests with all_must_work - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} env: CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: all_must_work diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml index 91da06d9eac..19182b77528 100644 --- a/.github/workflows/test-wheel-windows.yml +++ b/.github/workflows/test-wheel-windows.yml @@ -22,13 +22,18 @@ on: nruns: type: number default: 1 - # When true, cuda.bindings tests (and the Cython tests that depend on - # them) are skipped even when CTK majors match. Callers set this based - # on the output of the detect-changes job in ci.yml so PRs that only - # touch unrelated modules avoid the expensive bindings test suite. - skip-bindings-test: + test-pathfinder: type: boolean - default: false + default: true + test-bindings: + type: boolean + default: true + test-core: + type: boolean + default: true + test-python: + type: boolean + default: true run-id: description: > Workflow run ID to download artifacts from. @@ -146,7 +151,7 @@ jobs: LOCAL_CTK: ${{ matrix.LOCAL_CTK }} PY_VER: ${{ matrix.PY_VER }} SHA: ${{ inputs.sha || github.sha }} - SKIP_BINDINGS_TEST_OVERRIDE: ${{ inputs.skip-bindings-test && '1' || '0' }} + SKIP_BINDINGS_TEST_OVERRIDE: ${{ !inputs.test-bindings && '1' || '0' }} shell: bash --noprofile --norc -xeuo pipefail {0} run: ./ci/tools/env-vars test @@ -158,6 +163,7 @@ jobs: run: echo "$MATRIX_ENV" | jq -r 'to_entries[] | "\(.key)=\(.value)"' >> "$GITHUB_ENV" - name: Download cuda-pathfinder build artifacts + if: ${{ inputs.test-pathfinder || inputs.test-bindings || inputs.test-core || inputs.test-python }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: cuda-pathfinder-wheel @@ -166,7 +172,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python build artifacts - if: ${{ env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-python && env.BINDINGS_SOURCE == 'main' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: cuda-python-wheel @@ -175,7 +181,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda.bindings build artifacts - if: ${{ env.BINDINGS_SOURCE == 'main' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE == 'main' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }} @@ -184,7 +191,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python & cuda.bindings build artifacts from the prior branch - if: ${{ env.BINDINGS_SOURCE == 'backport' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE == 'backport' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash --noprofile --norc -xeuo pipefail {0} @@ -200,25 +208,28 @@ jobs: mv $OLD_BASENAME/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"/ rmdir $OLD_BASENAME - gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python - ls -al cuda-python-wheel - mv cuda-python-wheel/*.whl . - rmdir cuda-python-wheel + if ${{ inputs.test-python }}; then + gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python + ls -al cuda-python-wheel + mv cuda-python-wheel/*.whl . + rmdir cuda-python-wheel + fi - name: Display structure of downloaded cuda-python artifacts - if: ${{ env.BINDINGS_SOURCE != 'published' }} + if: ${{ inputs.test-python && env.BINDINGS_SOURCE != 'published' }} run: | Get-Location Get-ChildItem cuda_python*.whl | Select-Object Mode, LastWriteTime, Length, FullName - name: Display structure of downloaded cuda.bindings artifacts - if: ${{ env.BINDINGS_SOURCE != 'published' }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + env.BINDINGS_SOURCE != 'published' }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_BINDINGS_ARTIFACTS_DIR | Select-Object Mode, LastWriteTime, Length, FullName - name: Download cuda.bindings Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-bindings && env.SKIP_CYTHON_TEST == '0' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }}-tests @@ -227,12 +238,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.bindings Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-bindings && env.SKIP_CYTHON_TEST == '0' }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_BINDINGS_CYTHON_TESTS_DIR | Select-Object Mode, LastWriteTime, Length, FullName - name: Download cuda.core build artifacts + if: ${{ inputs.test-core }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }} @@ -241,12 +253,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core build artifacts + if: ${{ inputs.test-core }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_CORE_ARTIFACTS_DIR | Select-Object Mode, LastWriteTime, Length, FullName - name: Download cuda.core Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-core && env.SKIP_CYTHON_TEST == '0' }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-tests @@ -255,12 +268,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core Cython tests - if: ${{ env.SKIP_CYTHON_TEST == '0' }} + if: ${{ inputs.test-core && env.SKIP_CYTHON_TEST == '0' }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_CORE_CYTHON_TESTS_DIR | Select-Object Mode, LastWriteTime, Length, FullName - name: Download cuda.core test binaries + if: ${{ inputs.test-core }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-test-binaries @@ -269,6 +283,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Display structure of downloaded cuda.core test binaries + if: ${{ inputs.test-core }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_CORE_TEST_BINARIES_DIR | Select-Object Mode, LastWriteTime, Length, FullName @@ -281,7 +296,7 @@ jobs: allow-prereleases: ${{ startsWith(matrix.PY_VER, '3.15') }} - name: Enable Scientific Python Nightly Wheels for Python 3.15 - if: ${{ startsWith(matrix.PY_VER, '3.15') }} + if: ${{ (inputs.test-bindings || inputs.test-core) && startsWith(matrix.PY_VER, '3.15') }} shell: bash --noprofile --norc -xeuo pipefail {0} run: | echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV" @@ -310,7 +325,7 @@ jobs: # ── Standard test steps (skipped for nightly modes) ── - name: Run cuda.pathfinder tests with see_what_works - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} env: CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: see_what_works @@ -319,7 +334,7 @@ jobs: run: run-tests pathfinder - name: Run cuda.bindings tests - if: ${{ inputs.test-mode == 'standard' && env.SKIP_CUDA_BINDINGS_TEST == '0' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-bindings && env.SKIP_CUDA_BINDINGS_TEST == '0' }} env: CUDA_VER: ${{ matrix.CUDA_VER }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} @@ -327,7 +342,7 @@ jobs: run: run-tests bindings - name: Run cuda.core tests - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-core }} env: CUDA_VER: ${{ matrix.CUDA_VER }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} @@ -335,18 +350,28 @@ jobs: run: run-tests core - name: Ensure cuda-python installable - if: ${{ inputs.test-mode == 'standard' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-python && env.BINDINGS_SOURCE == 'main' }} run: | - # Subpackages are already installed from CI artifacts; --no-deps keeps - # tag-release cuda-core wheels from being replaced by PyPI pins. + # Package suites install their own dependencies. A metapackage-only + # run has no preceding suite, so resolve its exact cuda-bindings pin + # from this run while allowing its released cuda-core pin from PyPI. + if ('${{ inputs.test-bindings || inputs.test-core }}' -eq 'true') { + $dependencyArgs = @('--no-deps') + } else { + $dependencyArgs = @( + '--find-links', './cuda_pathfinder', + '--find-links', $env:CUDA_BINDINGS_ARTIFACTS_DIR + ) + } + $wheel = (Get-ChildItem -Filter cuda_python*.whl).FullName if ('${{ matrix.LOCAL_CTK }}' -eq '1') { - pip install --only-binary=:all: --no-deps (Get-ChildItem -Filter cuda_python*.whl).FullName + pip install --only-binary=:all: @dependencyArgs $wheel } else { - pip install --only-binary=:all: --no-deps "$((Get-ChildItem -Filter cuda_python*.whl).FullName)[all]" + pip install --only-binary=:all: @dependencyArgs "$wheel[all]" } - name: Install cuda.pathfinder extra wheels for testing - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} shell: bash --noprofile --norc -xeuo pipefail {0} run: | pushd cuda_pathfinder @@ -355,7 +380,7 @@ jobs: popd - name: Run cuda.pathfinder tests with all_must_work - if: ${{ inputs.test-mode == 'standard' }} + if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} env: CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: all_must_work From 3bb41144ed17c4d6326627ef55eb516b7d8d10cd Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Mon, 3 Aug 2026 13:23:18 -0400 Subject: [PATCH 2/5] ci: update selective wheel test callers --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24b81f406f5..2aadf222306 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -433,7 +433,7 @@ jobs: host-platform: ${{ matrix.host-platform }} build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }} nruns: ${{ (github.event_name == 'schedule' && 5) || 1}} - skip-bindings-test: ${{ !fromJSON(needs.detect-changes.outputs.test_bindings) }} + test-bindings: ${{ fromJSON(needs.detect-changes.outputs.test_bindings) }} # See test-linux-64 for why test jobs are split by platform. test-linux-aarch64: @@ -458,7 +458,7 @@ jobs: host-platform: ${{ matrix.host-platform }} build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }} nruns: ${{ (github.event_name == 'schedule' && 5) || 1}} - skip-bindings-test: ${{ !fromJSON(needs.detect-changes.outputs.test_bindings) }} + test-bindings: ${{ fromJSON(needs.detect-changes.outputs.test_bindings) }} # See test-linux-64 for why test jobs are split by platform. test-windows: @@ -483,7 +483,7 @@ jobs: host-platform: ${{ matrix.host-platform }} build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }} nruns: ${{ (github.event_name == 'schedule' && 5) || 1}} - skip-bindings-test: ${{ !fromJSON(needs.detect-changes.outputs.test_bindings) }} + test-bindings: ${{ fromJSON(needs.detect-changes.outputs.test_bindings) }} doc: name: Docs From fbef1b935ce5b8766f8928a489e37b1128bdb527 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 13 Aug 2026 15:33:58 -0400 Subject: [PATCH 3/5] ci: enable nightly NumPy for metapackage tests --- .github/workflows/test-wheel-linux.yml | 3 ++- .github/workflows/test-wheel-windows.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml index 0e5816552b9..f20d92cc92b 100644 --- a/.github/workflows/test-wheel-linux.yml +++ b/.github/workflows/test-wheel-linux.yml @@ -319,7 +319,8 @@ jobs: AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache" - name: Enable Scientific Python Nightly Wheels for Python 3.15 - if: ${{ (inputs.test-bindings || inputs.test-core) && startsWith(matrix.PY_VER, '3.15') }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + startsWith(matrix.PY_VER, '3.15') }} run: | echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV" echo "PIP_ONLY_BINARY=numpy" >> "$GITHUB_ENV" diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml index 19182b77528..c2ca06f9cba 100644 --- a/.github/workflows/test-wheel-windows.yml +++ b/.github/workflows/test-wheel-windows.yml @@ -296,7 +296,8 @@ jobs: allow-prereleases: ${{ startsWith(matrix.PY_VER, '3.15') }} - name: Enable Scientific Python Nightly Wheels for Python 3.15 - if: ${{ (inputs.test-bindings || inputs.test-core) && startsWith(matrix.PY_VER, '3.15') }} + if: ${{ (inputs.test-bindings || inputs.test-core || inputs.test-python) && + startsWith(matrix.PY_VER, '3.15') }} shell: bash --noprofile --norc -xeuo pipefail {0} run: | echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV" From 428ea82b9f0dfb1a35d7075d3ff382b358e4acad Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 13 Aug 2026 16:19:45 -0400 Subject: [PATCH 4/5] ci: install exact local wheels in metapackage tests --- .github/workflows/test-wheel-linux.yml | 28 ++++++++++++------- .github/workflows/test-wheel-windows.yml | 34 +++++++++++++++++------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml index f20d92cc92b..648326e24cb 100644 --- a/.github/workflows/test-wheel-linux.yml +++ b/.github/workflows/test-wheel-linux.yml @@ -384,21 +384,31 @@ jobs: if: ${{ inputs.test-mode == 'standard' && inputs.test-python && env.BINDINGS_SOURCE == 'main' }} run: | # Package suites install their own dependencies. A metapackage-only - # run has no preceding suite, so resolve its exact cuda-bindings pin - # from this run while allowing its released cuda-core pin from PyPI. + # run has no preceding suite, so install the exact local internal + # wheels in one transaction while resolving released dependencies + # such as cuda-core from the package index. if ${{ inputs.test-bindings || inputs.test-core }}; then dependency_args=(--no-deps) else - dependency_args=( - --find-links ./cuda_pathfinder - --find-links "${CUDA_BINDINGS_ARTIFACTS_DIR}" - ) + pathfinder_wheels=(./cuda_pathfinder/cuda_pathfinder-*.whl) + bindings_wheels=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) + test "${#pathfinder_wheels[@]}" -eq 1 + test "${#bindings_wheels[@]}" -eq 1 + test -f "${pathfinder_wheels[0]}" + test -f "${bindings_wheels[0]}" + if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then + dependency_args=("${pathfinder_wheels[0]}" "${bindings_wheels[0]}") + else + dependency_args=("${pathfinder_wheels[0]}" "${bindings_wheels[0]}[all]") + fi fi - wheel=$(ls cuda_python*.whl) + python_wheels=(cuda_python*.whl) + test "${#python_wheels[@]}" -eq 1 + test -f "${python_wheels[0]}" if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then - pip install --only-binary=:all: "${dependency_args[@]}" "${wheel}" + pip install --only-binary=:all: "${dependency_args[@]}" "${python_wheels[0]}" else - pip install --only-binary=:all: "${dependency_args[@]}" "${wheel}[all]" + pip install --only-binary=:all: "${dependency_args[@]}" "${python_wheels[0]}[all]" fi - name: Install cuda.pathfinder extra wheels for testing diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml index c2ca06f9cba..a3c403f2d38 100644 --- a/.github/workflows/test-wheel-windows.yml +++ b/.github/workflows/test-wheel-windows.yml @@ -354,21 +354,37 @@ jobs: if: ${{ inputs.test-mode == 'standard' && inputs.test-python && env.BINDINGS_SOURCE == 'main' }} run: | # Package suites install their own dependencies. A metapackage-only - # run has no preceding suite, so resolve its exact cuda-bindings pin - # from this run while allowing its released cuda-core pin from PyPI. + # run has no preceding suite, so install the exact local internal + # wheels in one transaction while resolving released dependencies + # such as cuda-core from the package index. if ('${{ inputs.test-bindings || inputs.test-core }}' -eq 'true') { $dependencyArgs = @('--no-deps') } else { - $dependencyArgs = @( - '--find-links', './cuda_pathfinder', - '--find-links', $env:CUDA_BINDINGS_ARTIFACTS_DIR - ) + $pathfinderWheels = @(Get-ChildItem -Path ./cuda_pathfinder -Filter cuda_pathfinder-*.whl -File) + $bindingsWheels = @(Get-ChildItem -Path $env:CUDA_BINDINGS_ARTIFACTS_DIR -Filter cuda_bindings-*.whl -File) + if ($pathfinderWheels.Count -ne 1) { + throw "Expected exactly one cuda-pathfinder wheel, found $($pathfinderWheels.Count)" + } + if ($bindingsWheels.Count -ne 1) { + throw "Expected exactly one cuda-bindings wheel, found $($bindingsWheels.Count)" + } + $pathfinderWheel = $pathfinderWheels[0].FullName + $bindingsWheel = $bindingsWheels[0].FullName + if ('${{ matrix.LOCAL_CTK }}' -eq '1') { + $dependencyArgs = @($pathfinderWheel, $bindingsWheel) + } else { + $dependencyArgs = @($pathfinderWheel, "${bindingsWheel}[all]") + } + } + $pythonWheels = @(Get-ChildItem -Filter cuda_python*.whl -File) + if ($pythonWheels.Count -ne 1) { + throw "Expected exactly one cuda-python wheel, found $($pythonWheels.Count)" } - $wheel = (Get-ChildItem -Filter cuda_python*.whl).FullName + $pythonWheel = $pythonWheels[0].FullName if ('${{ matrix.LOCAL_CTK }}' -eq '1') { - pip install --only-binary=:all: @dependencyArgs $wheel + pip install --only-binary=:all: @dependencyArgs $pythonWheel } else { - pip install --only-binary=:all: @dependencyArgs "$wheel[all]" + pip install --only-binary=:all: @dependencyArgs "${pythonWheel}[all]" } - name: Install cuda.pathfinder extra wheels for testing From c562e9b0a0b5dbdceb0044cb22d7eb4a00136444 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 13 Aug 2026 16:29:40 -0400 Subject: [PATCH 5/5] ci: simplify local wheel selection --- .github/workflows/test-wheel-linux.yml | 26 ++++++------------- .github/workflows/test-wheel-windows.yml | 32 ++++++------------------ 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml index 648326e24cb..8134a6844fd 100644 --- a/.github/workflows/test-wheel-linux.yml +++ b/.github/workflows/test-wheel-linux.yml @@ -390,26 +390,16 @@ jobs: if ${{ inputs.test-bindings || inputs.test-core }}; then dependency_args=(--no-deps) else - pathfinder_wheels=(./cuda_pathfinder/cuda_pathfinder-*.whl) - bindings_wheels=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) - test "${#pathfinder_wheels[@]}" -eq 1 - test "${#bindings_wheels[@]}" -eq 1 - test -f "${pathfinder_wheels[0]}" - test -f "${bindings_wheels[0]}" - if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then - dependency_args=("${pathfinder_wheels[0]}" "${bindings_wheels[0]}") - else - dependency_args=("${pathfinder_wheels[0]}" "${bindings_wheels[0]}[all]") - fi + dependency_args=( + ./cuda_pathfinder/cuda_pathfinder-*.whl + "${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl + ) fi - python_wheels=(cuda_python*.whl) - test "${#python_wheels[@]}" -eq 1 - test -f "${python_wheels[0]}" - if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then - pip install --only-binary=:all: "${dependency_args[@]}" "${python_wheels[0]}" - else - pip install --only-binary=:all: "${dependency_args[@]}" "${python_wheels[0]}[all]" + python_requirements=(cuda_python*.whl) + if [[ "${{ matrix.LOCAL_CTK }}" != 1 ]]; then + python_requirements=("${python_requirements[@]/%/[all]}") fi + pip install --only-binary=:all: "${dependency_args[@]}" "${python_requirements[@]}" - name: Install cuda.pathfinder extra wheels for testing if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }} diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml index a3c403f2d38..04b290b1cd0 100644 --- a/.github/workflows/test-wheel-windows.yml +++ b/.github/workflows/test-wheel-windows.yml @@ -360,32 +360,16 @@ jobs: if ('${{ inputs.test-bindings || inputs.test-core }}' -eq 'true') { $dependencyArgs = @('--no-deps') } else { - $pathfinderWheels = @(Get-ChildItem -Path ./cuda_pathfinder -Filter cuda_pathfinder-*.whl -File) - $bindingsWheels = @(Get-ChildItem -Path $env:CUDA_BINDINGS_ARTIFACTS_DIR -Filter cuda_bindings-*.whl -File) - if ($pathfinderWheels.Count -ne 1) { - throw "Expected exactly one cuda-pathfinder wheel, found $($pathfinderWheels.Count)" - } - if ($bindingsWheels.Count -ne 1) { - throw "Expected exactly one cuda-bindings wheel, found $($bindingsWheels.Count)" - } - $pathfinderWheel = $pathfinderWheels[0].FullName - $bindingsWheel = $bindingsWheels[0].FullName - if ('${{ matrix.LOCAL_CTK }}' -eq '1') { - $dependencyArgs = @($pathfinderWheel, $bindingsWheel) - } else { - $dependencyArgs = @($pathfinderWheel, "${bindingsWheel}[all]") - } - } - $pythonWheels = @(Get-ChildItem -Filter cuda_python*.whl -File) - if ($pythonWheels.Count -ne 1) { - throw "Expected exactly one cuda-python wheel, found $($pythonWheels.Count)" + $dependencyArgs = @( + (Get-Item ./cuda_pathfinder/cuda_pathfinder-*.whl).FullName + (Get-Item "$env:CUDA_BINDINGS_ARTIFACTS_DIR/cuda_bindings-*.whl").FullName + ) } - $pythonWheel = $pythonWheels[0].FullName - if ('${{ matrix.LOCAL_CTK }}' -eq '1') { - pip install --only-binary=:all: @dependencyArgs $pythonWheel - } else { - pip install --only-binary=:all: @dependencyArgs "${pythonWheel}[all]" + $pythonRequirements = @((Get-Item ./cuda_python*.whl).FullName) + if ('${{ matrix.LOCAL_CTK }}' -ne '1') { + $pythonRequirements = @($pythonRequirements | ForEach-Object { "$($_)[all]" }) } + pip install --only-binary=:all: @dependencyArgs @pythonRequirements - name: Install cuda.pathfinder extra wheels for testing if: ${{ inputs.test-mode == 'standard' && inputs.test-pathfinder }}