diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index b734fdd8c73..92427d2a902 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -43,6 +43,11 @@ on: required: false default: "gh-pages" type: string + bindings-package: + description: "Resolved CUDA bindings package JSON" + required: false + default: "" + type: string jobs: build: @@ -62,23 +67,50 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 - ref: ${{ inputs.git-tag }} + persist-credentials: false + ref: ${{ inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag }} + + # Release sources and workflow tools can come from different commits. + # Keep the shared CI helpers at this workflow revision while reading + # package paths and toolkit settings from the checked-out release tag. + - name: Checkout docs control plane + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.sha }} + path: .ci-control + persist-credentials: false - - name: Read build CTK version + - name: Set up Python for CI tools + # The release checkout can predate this action; use the workflow revision. + uses: ./.ci-control/.github/actions/setup-hardened-python + with: + python-version: "3.12" + + - name: Install CI tool dependencies + # Keep the hardened interpreter ahead of any login-shell activation. + shell: bash --noprofile --norc -euo pipefail {0} + run: python3 -m pip install -e ./.ci-control/ci + + - name: Resolve CUDA bindings package + shell: bash --noprofile --norc -euo pipefail {0} + env: + BINDINGS_PACKAGE: ${{ inputs.bindings-package }} + IS_RELEASE: ${{ inputs.is-release }} + RELEASE_TAG: ${{ inputs.git-tag }} run: | - if [[ -f ci/versions.yml ]]; then - BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml) - elif [[ -f ci/versions.json ]]; then - BUILD_CTK_VER=$(jq -r '.cuda.build.version' ci/versions.json) + set -euo pipefail + if [[ -n "$BINDINGS_PACKAGE" ]]; then + resolved_bindings_package="$BINDINGS_PACKAGE" + elif [[ "${IS_RELEASE}" == "true" ]]; then + resolved_bindings_package=$(cd .ci-control && python3 -m ci.tools.bindings_config \ + --release-tag "$RELEASE_TAG" \ + --release-source-root ..) else - echo "error: cannot find ci/versions.yml or ci/versions.json" >&2 - exit 1 - fi - if [[ ! "${BUILD_CTK_VER}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "error: derived CTK build version ${BUILD_CTK_VER} does not match MAJOR.MINOR.MICRO" >&2 - exit 1 + resolved_bindings_package=$(cd .ci-control && python3 -m ci.tools.bindings_config \ + --release-status current) fi - echo "BUILD_CTK_VER=${BUILD_CTK_VER}" >> "$GITHUB_ENV" + (cd .ci-control && python3 -m ci.tools.bindings_config \ + write-github-env "$GITHUB_ENV" <<< "$resolved_bindings_package") # TODO: This workflow runs on GH-hosted runner and cannot use the proxy cache @@ -86,7 +118,7 @@ jobs: uses: conda-incubator/setup-miniconda@be893c923ea9cf1cf7cd510fbdde27c7e18cbdcb # v4.1.0 with: activate-environment: cuda-python-docs - environment-file: ./cuda_python/docs/environment-docs.yml + environment-file: ./.ci-control/cuda_python/docs/environment-docs.yml miniforge-version: latest conda-remove-defaults: "true" python-version: 3.12 @@ -106,24 +138,16 @@ jobs: cuda-version: ${{ env.BUILD_CTK_VER }} - name: Set environment variables + env: + IS_RELEASE: ${{ inputs.is-release }} + RELEASE_TAG: ${{ inputs.git-tag }} run: | PYTHON_VERSION_FORMATTED="312" # see above REPO_DIR=$(pwd) - # Release docs may check out tags from before the source-root rename. - if [[ -d cuda_bindings_13 ]]; then - CUDA_BINDINGS_SOURCE_DIR=cuda_bindings_13 - elif [[ -d cuda_bindings ]]; then - CUDA_BINDINGS_SOURCE_DIR=cuda_bindings - else - echo "error: cannot find the cuda.bindings source directory" >&2 - exit 1 - fi - echo "CUDA_BINDINGS_SOURCE_DIR=${CUDA_BINDINGS_SOURCE_DIR}" >> "$GITHUB_ENV" - - if [[ ${{ inputs.is-release }} == "true" ]]; then + if [[ "$IS_RELEASE" == "true" ]]; then FILE_HASH="*" - DOCS_GITHUB_REF="${{ inputs.git-tag }}" + DOCS_GITHUB_REF="$RELEASE_TAG" if [[ -z "${DOCS_GITHUB_REF}" ]]; then DOCS_GITHUB_REF="${GITHUB_REF_NAME}" fi @@ -132,6 +156,8 @@ jobs: DOCS_GITHUB_REF=$(python ci/tools/checkout_source_links.py --github-ref) fi + echo "CUDA_BINDINGS_SOURCE_DIR=${BINDINGS_PACKAGE_ROOT}" >> "$GITHUB_ENV" + # make outputs from the previous job as env vars CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-linux-64" echo "CUDA_PYTHON_DOCS_GITHUB_REF=${DOCS_GITHUB_REF}" >> $GITHUB_ENV @@ -141,22 +167,27 @@ jobs: CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${BUILD_CTK_VER}-linux-64" echo "CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" >> $GITHUB_ENV echo "CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${FILE_HASH}" >> $GITHUB_ENV - echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/$CUDA_BINDINGS_SOURCE_DIR/dist")" >> $GITHUB_ENV + echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/${BINDINGS_PACKAGE_ROOT}/dist")" >> $GITHUB_ENV + CUDA_PYTHON_ARTIFACT_NAME="cuda-python-wheel-cuda${BUILD_CTK_VER}" + echo "CUDA_PYTHON_ARTIFACT_NAME=${CUDA_PYTHON_ARTIFACT_NAME}" >> $GITHUB_ENV - name: Download cuda-python build artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }} uses: $/.github/actions/download-artifact-retry with: - name: cuda-python-wheel + name: ${{ env.CUDA_PYTHON_ARTIFACT_NAME }} path: . run-id: ${{ inputs.run-id }} github-token: ${{ github.token }} - name: Display structure of downloaded cuda-python artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }} run: | pwd ls -lahR . - name: Download cuda-pathfinder build artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }} uses: $/.github/actions/download-artifact-retry with: name: cuda-pathfinder-wheel @@ -165,6 +196,7 @@ jobs: github-token: ${{ github.token }} - name: Display structure of downloaded cuda-pathfinder artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }} run: | pwd ls -lahR cuda_pathfinder @@ -177,7 +209,7 @@ jobs: path: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }} - name: Download cuda.bindings build artifacts - if: ${{ inputs.is-release }} + if: ${{ inputs.is-release && (inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core') }} uses: $/.github/actions/download-artifact-retry with: pattern: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }} @@ -187,6 +219,7 @@ jobs: github-token: ${{ github.token }} - name: Display structure of downloaded cuda.bindings artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core' }} run: | pwd ls -lahR $CUDA_BINDINGS_ARTIFACTS_DIR @@ -199,7 +232,7 @@ jobs: path: ${{ env.CUDA_CORE_ARTIFACTS_DIR }} - name: Download cuda.core build artifacts - if: ${{ inputs.is-release }} + if: ${{ inputs.is-release && (inputs.component == 'all' || inputs.component == 'cuda-core') }} uses: $/.github/actions/download-artifact-retry with: pattern: ${{ env.CUDA_CORE_ARTIFACT_NAME }} @@ -209,26 +242,37 @@ jobs: github-token: ${{ github.token }} - name: Display structure of downloaded cuda.core build artifacts + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-core' }} run: | pwd ls -lahR $CUDA_CORE_ARTIFACTS_DIR - - name: Install all packages + - name: Install cuda-pathfinder + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }} run: | pushd cuda_pathfinder pip install *.whl popd + - name: Install cuda.bindings + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core' }} + run: | pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}" pip install *.whl popd + - name: Install cuda.core + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-core' }} + run: | pushd "${CUDA_CORE_ARTIFACTS_DIR}" pip install *.whl popd - # Subpackages are already installed from CI artifacts above. - # --no-deps avoids re-resolving cuda-core from PyPI during tag releases. + - name: Install cuda-python + if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }} + run: | + # Documentation builds do not exercise runtime dependencies. + # --no-deps also avoids resolving artifacts absent from focused tag runs. pip install --no-deps cuda_python*.whl # PR CI uses pull-request/ refs regardless of the target branch. @@ -252,9 +296,11 @@ jobs: - name: Build all docs if: ${{ inputs.component == 'all' }} + env: + IS_RELEASE: ${{ inputs.is-release }} run: | pushd cuda_python/docs/ - if [[ "${{ inputs.is-release }}" == "false" ]]; then + if [[ "$IS_RELEASE" == "false" ]]; then ./build_all_docs.sh latest-only else ./build_all_docs.sh @@ -271,13 +317,20 @@ jobs: - name: Build component docs if: ${{ inputs.component != 'all' }} + env: + DOCS_COMPONENT: ${{ inputs.component }} + IS_RELEASE: ${{ inputs.is-release }} run: | - COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_') - if [[ "${{ inputs.component }}" == "cuda-bindings" ]]; then - COMPONENT="${CUDA_BINDINGS_SOURCE_DIR}" + case "$DOCS_COMPONENT" in + cuda-bindings|cuda-core|cuda-pathfinder|cuda-python) ;; + *) echo "error: unsupported docs component: $DOCS_COMPONENT" >&2; exit 1 ;; + esac + COMPONENT="${DOCS_COMPONENT//-/_}" + if [[ "$DOCS_COMPONENT" == "cuda-bindings" ]]; then + COMPONENT="${BINDINGS_PACKAGE_ROOT}" fi - pushd ${COMPONENT}/docs/ - if [[ "${{ inputs.is-release }}" == "false" ]]; then + pushd "${COMPONENT}/docs/" + if [[ "$IS_RELEASE" == "false" ]]; then ./build_docs.sh latest-only else ./build_docs.sh @@ -290,13 +343,13 @@ jobs: fi ls -l build popd - if [[ "${{ inputs.component }}" != "cuda-python" ]]; then - TARGET="${{ inputs.component }}" - mkdir -p artifacts/docs/${TARGET} + if [[ "$DOCS_COMPONENT" != "cuda-python" ]]; then + TARGET="$DOCS_COMPONENT" + mkdir -p "artifacts/docs/${TARGET}" else TARGET="" fi - mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET} + mv "${COMPONENT}"/docs/build/html/* "artifacts/docs/${TARGET}" # Check links and anchors in the rendered HTML built above. # Links in authored Markdown and reST files are checked separately by the @@ -305,7 +358,7 @@ jobs: # interpreter instead of the conda environment used above. - name: Set up Python for link checks if: ${{ !inputs.is-release && startsWith(github.ref_name, 'pull-request/') }} - uses: ./.github/actions/setup-hardened-python + uses: ./.ci-control/.github/actions/setup-hardened-python with: python-version: "3.14" @@ -363,7 +416,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 - ref: ${{ inputs.git-tag }} + ref: ${{ inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag }} - name: Download docs deployment payload uses: $/.github/actions/download-artifact-retry diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml index f2026a379e3..475f68d0839 100644 --- a/.github/workflows/ci-nightly.yml +++ b/.github/workflows/ci-nightly.yml @@ -74,26 +74,41 @@ jobs: outputs: RUN_ID: ${{ steps.find.outputs.run_id }} HEAD_SHA: ${{ steps.find.outputs.head_sha }} - CUDA_BUILD_VER: ${{ steps.find.outputs.cuda_build_ver }} + BINDINGS_CONFIG: ${{ steps.find.outputs.bindings_config }} steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 + - name: Set up Python + uses: ./.github/actions/setup-hardened-python + with: + python-version: "3.11" + + - name: Install CI tool dependencies + run: python -m pip install -e ./ci + - name: Find latest successful CI run on main id: find env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_REPOSITORY: ${{ github.repository }} + REQUESTED_RUN_ID: ${{ inputs.run-id }} run: | - if [[ -n "${{ inputs.run-id }}" ]]; then - RUN_ID="${{ inputs.run-id }}" + set -euo pipefail + if [[ -n "$REQUESTED_RUN_ID" ]]; then + if [[ ! "$REQUESTED_RUN_ID" =~ ^[1-9][0-9]*$ ]]; then + echo "::error::run-id must be a positive integer" + exit 1 + fi + RUN_ID="$REQUESTED_RUN_ID" HEAD_SHA=$(gh run view "$RUN_ID" \ - -R "${{ github.repository }}" \ + -R "$RELEASE_REPOSITORY" \ --json headSha | jq -r '.headSha') else # lookup-run-id --branch --head-sha prints two lines: run_id then head_sha - OUTPUT=$(./ci/tools/lookup-run-id --branch main --head-sha "${{ github.repository }}" "CI") + OUTPUT=$(./ci/tools/lookup-run-id --branch main --head-sha "$RELEASE_REPOSITORY" "CI") RUN_ID=$(echo "$OUTPUT" | sed -n '1p') HEAD_SHA=$(echo "$OUTPUT" | sed -n '2p') fi @@ -103,20 +118,19 @@ jobs: exit 1 fi - CUDA_BUILD_VER=$(gh api \ - "repos/${{ github.repository }}/contents/ci/versions.yml?ref=$HEAD_SHA" \ - --jq '.content' \ - | base64 -d \ - | yq '.cuda.build.version') - - if [[ -z "$CUDA_BUILD_VER" || "$CUDA_BUILD_VER" == "null" ]]; then - echo "::error::Could not resolve CUDA build version from $HEAD_SHA" + git fetch --depth=1 origin "$HEAD_SHA" + snapshot=$(mktemp -d) + trap 'rm -rf -- "$snapshot"' EXIT + git archive "$HEAD_SHA" ci/versions.yml | tar -x -C "$snapshot" + if ! BINDINGS_CONFIG=$(python -m ci.tools.bindings_config \ + --config "$snapshot/ci/versions.yml"); then + echo "::error::CI run $RUN_ID ($HEAD_SHA) has no bindings registry compatible with this nightly workflow. Wait for a successful main CI run with the current registry, or dispatch ci-nightly.yml with a compatible run-id. See ci/README.md#nightly-artifact-sources-and-rollout." exit 1 fi echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT echo "head_sha=$HEAD_SHA" >> $GITHUB_OUTPUT - echo "cuda_build_ver=$CUDA_BUILD_VER" >> $GITHUB_OUTPUT + echo "bindings_config=$BINDINGS_CONFIG" >> $GITHUB_OUTPUT # ── PyTorch interop tests ── @@ -132,7 +146,7 @@ jobs: with: build-type: nightly host-platform: linux-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-pytorch @@ -150,7 +164,7 @@ jobs: with: build-type: nightly host-platform: linux-aarch64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-pytorch @@ -168,7 +182,7 @@ jobs: with: build-type: nightly host-platform: win-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-pytorch @@ -188,7 +202,7 @@ jobs: with: build-type: nightly host-platform: linux-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-numba-cuda @@ -206,7 +220,7 @@ jobs: with: build-type: nightly host-platform: linux-aarch64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-numba-cuda @@ -224,7 +238,7 @@ jobs: with: build-type: nightly host-platform: win-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-numba-cuda @@ -244,7 +258,7 @@ jobs: with: build-type: nightly host-platform: linux-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-numba-cuda-mlir @@ -262,7 +276,7 @@ jobs: with: build-type: nightly host-platform: win-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-numba-cuda-mlir @@ -282,7 +296,7 @@ jobs: with: build-type: nightly host-platform: linux-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-cuda-core @@ -300,7 +314,7 @@ jobs: with: build-type: nightly host-platform: win-64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: nightly-cuda-core @@ -320,7 +334,7 @@ jobs: with: build-type: nightly host-platform: linux-aarch64 - build-ctk-ver: ${{ needs.find-wheels.outputs.CUDA_BUILD_VER }} + bindings-config: ${{ needs.find-wheels.outputs.BINDINGS_CONFIG }} run-id: ${{ needs.find-wheels.outputs.RUN_ID }} sha: ${{ needs.find-wheels.outputs.HEAD_SHA }} test-mode: standard diff --git a/.github/workflows/ci-pixi-source-test.yml b/.github/workflows/ci-pixi-source-test.yml index 1e10d2a5a42..1cd22c60d5d 100644 --- a/.github/workflows/ci-pixi-source-test.yml +++ b/.github/workflows/ci-pixi-source-test.yml @@ -11,14 +11,14 @@ # cython-test build mechanics drift (see #2182, #2183). This workflow is the # only thing that runs the pixi source build end to end. # -# Two tiers, to spend GPU minutes deliberately (GPUs are scarce): +# Three tiers, to spend GPU minutes deliberately (GPUs are scarce): # - build-smoke (PRs): CPU-only. Source-builds bindings + core, imports them, # builds the cython test extensions and checks placement. Catches the # compile / ABI / .so-placement regressions WITHOUT a GPU. -# - build-identity-roundtrip (nightly + manual): CPU-only. cu13 -> cu12 -> -# cu13 in one checkout, so build artifacts cannot be reused across CUDA -# majors. Kept off PRs to avoid adding another job to the org's shared -# concurrent-job quota; the fast unit tests in +# - build-identity-roundtrip (nightly + manual): CPU-only. The current ABI -> +# another configured ABI -> current ABI in one checkout, so build artifacts +# cannot be reused across CUDA majors. Kept off PRs to avoid adding another +# job to the org's shared concurrent-job quota; the fast unit tests in # cuda_core/tests/test_build_hooks.py cover the same intent per-PR. # - full-test (nightly + manual): GPU runner, full `pixi run test`. @@ -41,11 +41,15 @@ on: # Path-dependency metadata (including cuda_python_test_helpers) feeds the # solve, so it can break the source build without a pixi.toml edit. - "**/pyproject.toml" - - "cuda_bindings_13/build_hooks.py" + - "cuda_bindings*/build_hooks.py" - "cuda_core/build_hooks.py" - - "cuda_bindings_13/cuda/bindings/**" # generated bindings sources - - "cuda_bindings_13/tests/cython/**" + - "cuda_bindings*/cuda/bindings/**" # generated bindings sources + - "cuda_bindings*/docs/**" + - "cuda_bindings*/tests/cython/**" - "cuda_core/tests/cython/**" + - "ci/tools/bindings_config.py" + - "ci/tools/compute_ci_plan.py" + - "ci/pyproject.toml" - "ci/versions.yml" - "ci/pixi-version.env" - ".github/actions/setup-pixi/action.yml" @@ -53,9 +57,9 @@ on: workflow_dispatch: inputs: cuda-env: - description: "pixi environment to test (cu13 or cu12)." + description: "Registered pixi CUDA ABI environment to test (empty selects current)." type: string - default: "cu13" + default: "" defaults: run: @@ -73,7 +77,7 @@ env: jobs: # ── PR guard: CPU-only build + import + placement smoke ── build-smoke: - name: "build smoke (cu13, linux-64, CPU)" + name: "build smoke (selected CUDA packages, linux-64, CPU)" if: >- github.repository_owner == 'nvidia' && (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') @@ -83,9 +87,9 @@ jobs: - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # Full history + tags so setuptools-scm derives the real (13.x) + # Full history + tags so setuptools-scm derives the real # package version; a shallow checkout yields 0.1.dev1, which trips - # cuda.core's "cuda.bindings 12.x or 13.x must be installed" guard. + # cuda.core's supported cuda.bindings-version guard. fetch-depth: 0 filter: blob:none # Fetch CCCL separately: checkout's filter does not apply to submodules. @@ -96,60 +100,182 @@ jobs: git submodule sync --recursive git submodule update --init --force --depth=1 --filter=blob:none --recursive + - name: Set up Python + uses: ./.github/actions/setup-hardened-python + with: + python-version: "3.11" + + - name: Install CI tool dependencies + run: python3 -m pip install -e ./ci + - name: Setup pixi uses: ./.github/actions/setup-pixi - - name: Source-build + import + cython-placement smoke + - name: Select CUDA environments env: - CUDA_ENV: ${{ inputs.cuda-env || 'cu13' }} + BASE_SHA: ${{ github.event.pull_request.base.sha || '' }} + EVENT_NAME: ${{ github.event_name }} + REQUESTED_CUDA_ENV: ${{ inputs.cuda-env || '' }} run: | - # pathfinder: pure-Python, no GPU. - pixi run -e "${CUDA_ENV}" test-pathfinder - - # bindings + core: force the source build (catches nvrtc/driver - # compile errors like #2182) and import them (catches ABI mismatches). - pixi run --manifest-path cuda_bindings_13 -e "${CUDA_ENV}" \ - python -c "import cuda.bindings.driver, cuda.bindings.nvrtc, cuda.bindings.runtime; print('bindings import OK')" - pixi run --manifest-path cuda_core -e "${CUDA_ENV}" \ - python -c "import cuda.core; print('core import OK')" - - # cython test extensions: build them and confirm each .so landed next - # to its .pyx in tests/cython (catches the placement regression #2180). - pixi run --manifest-path cuda_bindings_13 -e "${CUDA_ENV}" build-cython-tests - pixi run --manifest-path cuda_core -e "${CUDA_ENV}" build-cython-tests - for d in cuda_bindings_13/tests/cython cuda_core/tests/cython; do - if ! compgen -G "${d}/*.cpython-*.so" > /dev/null; then - echo "::error::no compiled cython test .so in ${d} (placement regression)" - exit 1 + bindings_packages=$(python3 -m ci.tools.bindings_config --package-roots) + selected_packages='[]' + docs_packages='[]' + + merge_packages() { + jq -cn --argjson left "$1" --argjson right "$2" \ + '$left + $right | unique_by(.package_root)' + } + + if [[ "${EVENT_NAME}" == "workflow_dispatch" ]]; then + if [[ -n "${REQUESTED_CUDA_ENV}" ]]; then + selected_packages=$(jq -c --arg cuda_env "${REQUESTED_CUDA_ENV}" \ + '[.[] | select(.cuda_variant == $cuda_env)]' <<< "${bindings_packages}") + if [[ "${selected_packages}" == '[]' ]]; then + registered_envs=$(jq -r '[.[].cuda_variant] | join(", ")' <<< "${bindings_packages}") + echo "::error::cuda-env must be a registered pixi environment: ${registered_envs}" + exit 1 + fi + else + selected_packages=$(jq -c '[.[] | select(.release_status == "current")]' \ + <<< "${bindings_packages}") fi - done + else + merge_base=$(git merge-base HEAD "${BASE_SHA}") + workplan=$(python3 -m ci.tools.compute_ci_plan \ + --merge-base "${merge_base}" \ + --baseline-run-id pixi-source) + + # Keep package-specific work package-specific, while selecting the + # registered package for any ABI-level work. + selected_packages=$(jq -cn \ + --argjson registry "${bindings_packages}" \ + --argjson plan "${workplan}" ' + $registry + | map(. as $package | select( + ($plan.modules.bindings.package_roots[$package.package_root].needs_build // false) + or ($plan.modules.bindings.package_roots[$package.package_root].needs_test // false) + or ($plan.modules.python.package_roots[$package.package_root].needs_build // false) + or ($plan.modules.python.package_roots[$package.package_root].needs_test // false) + or ($plan.jobs.test_cuda_majors[$package.cuda_variant] // false) + )) + ') + + # Pixi manifests are deliberately ignored by the wheel planner. + # Add their package-local impact to its source/test decisions. The + # wheel planner also deliberately ignores documentation changes. + while IFS= read -r -d '' path; do + manifest_packages=$(jq -c --arg path "${path}" ' + [.[] as $package + | select( + $path == ($package.package_root + "/pixi.toml") + or $path == ($package.package_root + "/pixi.lock") + ) + | $package] + ' <<< "${bindings_packages}") + if [[ "${manifest_packages}" != '[]' ]]; then + selected_packages=$(merge_packages "${selected_packages}" "${manifest_packages}") + else + case "${path}" in + */pixi.toml|*/pixi.lock|pixi.toml|pixi.lock) + selected_packages=$(merge_packages "${selected_packages}" "${bindings_packages}") + ;; + esac + fi + + changed_docs_packages=$(jq -c --arg path "${path}" ' + [.[] as $package + | select($path | startswith($package.package_root + "/docs/")) + | $package] + ' <<< "${bindings_packages}") + if [[ "${changed_docs_packages}" != '[]' ]]; then + selected_packages=$(merge_packages "${selected_packages}" "${changed_docs_packages}") + docs_packages=$(merge_packages "${docs_packages}" "${changed_docs_packages}") + fi + done < <(git diff --no-renames --name-only -z "${merge_base}" HEAD) + fi + + if [[ "${selected_packages}" == '[]' ]]; then + echo "::error::no bindings package selected for source-build smoke tests" + exit 1 + fi + echo "BINDINGS_PACKAGES=${selected_packages}" | tee -a "$GITHUB_ENV" + { + echo '### Selected source builds' + jq -r '.[] | "- \(.package_root): CUDA \(.cuda_major), pixi \(.cuda_variant)"' <<< "$selected_packages" + } >> "$GITHUB_STEP_SUMMARY" + echo "BINDINGS_DOC_PACKAGES=${docs_packages}" | tee -a "$GITHUB_ENV" + + - name: Source-build + import + cython-placement smoke + run: | + while IFS= read -r bindings_package; do + BINDINGS_ROOT=$(jq -r '.package_root' <<< "${bindings_package}") + CUDA_ENV=$(jq -r '.cuda_variant' <<< "${bindings_package}") + echo "::group::Source-build ${BINDINGS_ROOT} (${CUDA_ENV})" + # Avoid carrying Cython outputs between bindings packages or CUDA ABIs. + rm -rf cuda_core/build/cython cuda_core/cython_debug + find cuda_core/cuda/core -type f -name '*.so' -delete + find "${BINDINGS_ROOT}/tests/cython" cuda_core/tests/cython \ + -maxdepth 1 -type f \( -name 'test_*.cpp' -o -name 'test_*.so' \) -delete + + # pathfinder: pure-Python, no GPU. + pixi run -e "${CUDA_ENV}" test-pathfinder + + # Force both source builds and import them to catch compile/ABI + # regressions such as #2182. cuda-core environments may use + # published bindings by design; wheel CI covers local pairing. + pixi run --manifest-path "${BINDINGS_ROOT}" -e "${CUDA_ENV}" \ + python -c "import cuda.bindings.driver, cuda.bindings.nvrtc, cuda.bindings.runtime; print('bindings import OK')" + pixi run --manifest-path cuda_core -e "${CUDA_ENV}" \ + python -c "import cuda.core; print('core import OK')" + pixi run --manifest-path "${BINDINGS_ROOT}" -e "${CUDA_ENV}" build-cython-tests + pixi run --manifest-path cuda_core -e "${CUDA_ENV}" build-cython-tests + + # Confirm each extension landed next to its .pyx (catches #2180). + for d in "${BINDINGS_ROOT}/tests/cython" cuda_core/tests/cython; do + if ! compgen -G "${d}/*.cpython-*.so" > /dev/null; then + echo "::error::no compiled cython test .so in ${d} (placement regression)" + exit 1 + fi + done + echo "::endgroup::" + done < <(jq -c '.[]' <<< "${BINDINGS_PACKAGES}") echo "cython test extensions placed correctly" + - name: Build changed bindings documentation + if: ${{ env.BINDINGS_DOC_PACKAGES != '[]' }} + run: | + while IFS= read -r bindings_package; do + bindings_root=$(jq -r '.package_root' <<< "${bindings_package}") + pixi run --manifest-path "${bindings_root}" -e docs build-docs + done < <(jq -c '.[]' <<< "${BINDINGS_DOC_PACKAGES}") + # ── Nightly guard: build artifacts must be CUDA-major aware ── # # Neither Cython nor setuptools tracks the CUDA major in its own up-to-date # check: Cython does not hash `compile_time_env`, and an editable install's # .so is named by the Python ABI tag alone. Before build_hooks keyed them, - # a cu13 build followed by a cu12 build in the same checkout failed while - # compiling cu13-generated C++ against CUDA 12 headers. + # a build for one ABI followed by another in the same checkout failed while + # compiling generated C++ against headers from the second ABI. # - # The round trip (not just cu13 -> cu12) is what catches the second half: - # coming back to cu13 must not silently reuse the cu12 extension. + # The round trip is what catches the second half: coming back to the current + # ABI must not silently reuse the other ABI's extension. # - # cuda_core only: cuda-bindings cannot be source-built in its cu12 - # environment at all, for reasons unrelated to stale artifacts. + # cuda_core only: not every bindings package can be source-built in every ABI + # environment, for reasons unrelated to stale artifacts. build-identity-roundtrip: - name: "cu13 -> cu12 -> cu13 round trip (linux-64, CPU)" + name: "current -> maintenance -> current round trip (linux-64, CPU)" if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository_owner == 'nvidia' }} runs-on: ubuntu-latest timeout-minutes: 60 + outputs: + bindings-packages: ${{ steps.roundtrip.outputs.bindings-packages }} steps: - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # Full history + tags so setuptools-scm derives the real (13.x) + # Full history + tags so setuptools-scm derives the real # package version; a shallow checkout yields 0.1.dev1, which trips - # cuda.core's "cuda.bindings 12.x or 13.x must be installed" guard. + # cuda.core's supported cuda.bindings-version guard. fetch-depth: 0 filter: blob:none # Fetch CCCL separately: checkout's filter does not apply to submodules. @@ -160,18 +286,53 @@ jobs: git submodule sync --recursive git submodule update --init --force --depth=1 --filter=blob:none --recursive + - name: Set up Python + uses: ./.github/actions/setup-hardened-python + with: + python-version: "3.11" + + - name: Install CI tool dependencies + run: python3 -m pip install -e ./ci + - name: Setup pixi uses: ./.github/actions/setup-pixi - - name: Build cu13, then cu12, then cu13 again in one checkout + - name: Build current, another ABI, then current again in one checkout + id: roundtrip + env: + EVENT_NAME: ${{ github.event_name }} + REQUESTED_CUDA_ENV: ${{ inputs.cuda-env || '' }} run: | - for cuda_env in cu13 cu12 cu13; do + current_package=$(python3 -m ci.tools.bindings_config --release-status current) + bindings_packages=$(python3 -m ci.tools.bindings_config --package-roots) + current_env=$(jq -r '.cuda_variant' <<< "${current_package}") + other_env=$(jq -r --arg current_env "${current_env}" \ + '[.[] | select(.cuda_variant != $current_env) | .cuda_variant] | first // empty' \ + <<< "${bindings_packages}") + + # Scheduled source tests cover both registered ABIs; manual runs + # retain a single selected ABI, defaulting to the current package. + if [[ "${EVENT_NAME}" == schedule ]]; then + selected_packages="${bindings_packages}" + else + selected_env="${REQUESTED_CUDA_ENV:-${current_env}}" + selected_packages=$(jq -c --arg cuda_env "${selected_env}" \ + '[.[] | select(.cuda_variant == $cuda_env)]' <<< "${bindings_packages}") + if [[ "${selected_packages}" == '[]' ]]; then + registered_envs=$(jq -r '[.[].cuda_variant] | join(", ")' <<< "${bindings_packages}") + echo "::error::cuda-env must be a registered pixi environment: ${registered_envs}" + exit 1 + fi + fi + echo "bindings-packages=${selected_packages}" >> "$GITHUB_OUTPUT" + + for cuda_env in "${current_env}" "${other_env}" "${current_env}"; do echo "::group::${cuda_env}" pixi run --manifest-path cuda_core -e "${cuda_env}" \ python -c "import cuda.core; print('core import OK')" echo "::endgroup::" done - # The last build was cu13, and each major must have kept its own + # The last build was current, and each ABI must have kept its own # generated sources rather than overwriting the other's. # Stamp is ABI-scoped (.build-config.). Unset and gnu # both record as "gnu"; llvm records as "llvm". @@ -182,22 +343,27 @@ jobs: exit 1 fi stamp=$(<"${stamps[0]}") - if [[ ! "${stamp}" =~ ^cu13-(gnu|llvm)-(debug|opt)(-cov)?$ ]]; then - echo "::error::build stamp is '${stamp}', expected cu13-{gnu|llvm}-{debug|opt}" + if [[ ! "${stamp}" =~ ^${current_env}-(gnu|llvm)-(debug|opt)(-cov)?$ ]]; then + echo "::error::build stamp is '${stamp}', expected ${current_env}-{gnu|llvm}-{debug|opt}" exit 1 fi - suffix="${stamp#cu13-}" - for major in cu12 cu13; do - if [ ! -d "cuda_core/build/cython/${major}-${suffix}" ]; then - echo "::error::no ${major}-${suffix} generated-source directory" + suffix="${stamp#"${current_env}-"}" + for cuda_env in "${other_env}" "${current_env}"; do + if [ ! -d "cuda_core/build/cython/${cuda_env}-${suffix}" ]; then + echo "::error::no ${cuda_env}-${suffix} generated-source directory" exit 1 fi done # ── Nightly: full `pixi run test` on a GPU runner ── full-test: - name: "pixi run test (${{ inputs.cuda-env || 'cu13' }}, linux-64, GPU)" + name: "pixi run test (${{ matrix.bindings-package.cuda_variant }}, linux-64, GPU)" if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository_owner == 'nvidia' }} + needs: build-identity-roundtrip + strategy: + fail-fast: false + matrix: + bindings-package: ${{ fromJSON(needs.build-identity-roundtrip.outputs.bindings-packages) }} runs-on: "linux-amd64-gpu-l4-latest-1" # same label scheme as test-wheel-linux.yml timeout-minutes: 90 container: @@ -212,17 +378,17 @@ jobs: - name: Install system packages run: | apt-get update - # ca-certificates + git for checkout; libgl1/libegl1 for pyglet - # (pulled in by the test env). pixi itself is installed by setup-pixi. + # ca-certificates + git for checkout; libgl1/libegl1 for pyglet. + # Pixi supplies the package build and test environments. apt-get install -y --no-install-recommends \ - ca-certificates git libgl1 libegl1 + ca-certificates git jq libgl1 libegl1 - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # Full history + tags so setuptools-scm derives the real (13.x) + # Full history + tags so setuptools-scm derives the real # package version; a shallow checkout yields 0.1.dev1, which trips - # cuda.core's "cuda.bindings 12.x or 13.x must be installed" guard. + # cuda.core's supported cuda.bindings-version guard. fetch-depth: 0 filter: blob:none # Fetch CCCL separately: checkout's filter does not apply to submodules. @@ -233,6 +399,16 @@ jobs: git submodule sync --recursive git submodule update --init --force --depth=1 --filter=blob:none --recursive + - name: Trust the checkout for container source builds + # checkout's temporary Git configuration does not reach later steps. + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Prepare selected CUDA environment + env: + CUDA_ENV: ${{ matrix.bindings-package.cuda_variant }} + run: | + echo "CUDA_ENV=${CUDA_ENV}" | tee -a "$GITHUB_ENV" + - name: Setup proxy cache uses: nv-gha-runners/setup-proxy-cache@main continue-on-error: true @@ -241,4 +417,4 @@ jobs: uses: ./.github/actions/setup-pixi - name: pixi run test - run: pixi run -e "${{ inputs.cuda-env || 'cu13' }}" test + run: pixi run -e "${CUDA_ENV}" test diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 50d168db042..199b458b6c6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -20,18 +20,30 @@ jobs: if: ${{ github.repository_owner == 'nvidia' }} runs-on: ubuntu-latest outputs: + BINDINGS_ROOT: ${{ steps.get-vars.outputs.bindings_root }} CUDA_VER: ${{ steps.get-vars.outputs.cuda_ver }} steps: - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Get CUDA version + - name: Set up Python + uses: ./.github/actions/setup-hardened-python + with: + python-version: "3.12" + + - name: Install CI tool dependencies + run: python3 -m pip install -e ./ci + - name: Resolve current CUDA bindings package id: get-vars run: | - cuda_ver=$(yq '.cuda.build.version' ci/versions.yml) - echo "cuda_ver=$cuda_ver" >> $GITHUB_OUTPUT + set -euo pipefail + current=$(python3 -m ci.tools.bindings_config --release-status current) + { + echo "bindings_root=$(jq -r '.package_root' <<< "$current")" + echo "cuda_ver=$(jq -r '.toolkit_version' <<< "$current")" + } >> "$GITHUB_OUTPUT" coverage-linux: - name: Coverage (Linux) + name: Coverage ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} + core (Linux) needs: [coverage-vars] runs-on: "linux-amd64-gpu-a100-latest-1" permissions: @@ -43,6 +55,7 @@ jobs: env: HOST_PLATFORM: "linux-64" ARCH: "x86_64" + BINDINGS_ROOT: ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} CUDA_VER: ${{ needs.coverage-vars.outputs.CUDA_VER }} # Our self-hosted runners require a container # TODO: use a different (nvidia?) container @@ -97,9 +110,13 @@ jobs: - name: Set environment variables env: BUILD_CUDA_VER: ${{ env.CUDA_VER }} + BINDINGS_SOURCE: local + BINDINGS_SOURCE_DIR: ${{ env.BINDINGS_ROOT }} + DEFAULT_BINDINGS_SOURCE_DIR: ${{ env.BINDINGS_ROOT }} CUDA_VER: ${{ env.CUDA_VER }} HOST_PLATFORM: ${{ env.HOST_PLATFORM }} LOCAL_CTK: ${{ env.LOCAL_CTK }} + PATHFINDER_SOURCE: artifact PY_VER: ${{ env.PY_VER }} SHA: ${{ github.sha }} run: | @@ -138,8 +155,16 @@ jobs: run: | export PIP_BUILD_CONSTRAINT="$(pwd)/wheel-constraints/cuda-bindings.txt" export PIP_CONSTRAINT="${PIP_BUILD_CONSTRAINT}" - .venv/bin/pip wheel -v --no-deps ./cuda_bindings_13 -w ./wheels/ - .venv/bin/pip install -v ./wheels/cuda_bindings*.whl --group ./cuda_bindings_13/pyproject.toml:test + .venv/bin/pip wheel -v --no-deps "./${BINDINGS_ROOT}" -w ./wheels/ + bindings_wheels=(./wheels/cuda_bindings*.whl) + test "${#bindings_wheels[@]}" -eq 1 + test -f "${bindings_wheels[0]}" + bindings_pyproject="./${BINDINGS_ROOT}/pyproject.toml" + if grep -q '^\[dependency-groups\][[:space:]]*$' "${bindings_pyproject}"; then + .venv/bin/python -m pip install "${bindings_wheels[0]}" --group "${bindings_pyproject}:test" + else + .venv/bin/python -m pip install "${bindings_wheels[0]}[test]" + fi - name: Constrain cuda-core to the local cuda-bindings wheel run: | @@ -184,7 +209,7 @@ jobs: continue-on-error: true run: | cd $INSTALL_ROOT - $REPO_ROOT/.venv/bin/pytest -v --cov=./cuda --cov-append --cov-context=test --cov-config=$REPO_ROOT/.coveragerc $REPO_ROOT/cuda_bindings_13/tests + $REPO_ROOT/.venv/bin/pytest -v --cov=./cuda --cov-append --cov-context=test --cov-config=$REPO_ROOT/.coveragerc "$REPO_ROOT/${BINDINGS_ROOT}/tests" - name: Run cuda.core tests continue-on-error: true @@ -217,7 +242,7 @@ jobs: # Build Windows wheels on GitHub-hosted runner (has VS, no GPU) build-wheel-windows: - name: Build Wheels (Windows) + name: Build ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} + core for coverage (Windows) needs: [coverage-vars] runs-on: windows-2022 permissions: @@ -228,6 +253,7 @@ jobs: env: HOST_PLATFORM: "win-64" CUDA_PYTHON_COVERAGE: "1" + BINDINGS_ROOT: ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} CUDA_VER: ${{ needs.coverage-vars.outputs.CUDA_VER }} steps: - name: Harden OS certificate trust (eMudhra/emSign CA stopgap) @@ -286,8 +312,7 @@ jobs: run: | export PIP_BUILD_CONSTRAINT="$(cygpath -w "$(pwd)/wheel-constraints/cuda-bindings.txt")" export PIP_CONSTRAINT="${PIP_BUILD_CONSTRAINT}" - cd cuda_bindings_13 - ../.venv/Scripts/pip wheel -v --no-deps . -w ../wheels/ + .venv/Scripts/pip wheel -v --no-deps "./${BINDINGS_ROOT}" -w ./wheels/ - name: Constrain cuda.core to the local cuda.bindings wheel run: | @@ -342,7 +367,7 @@ jobs: # Run coverage tests on self-hosted GPU runner (no VS needed, installs pre-built wheels) coverage-windows: - name: Coverage (Windows) + name: Coverage ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} + core (Windows) needs: [coverage-vars, build-wheel-windows] runs-on: "windows-amd64-gpu-a100-latest-1" permissions: @@ -352,6 +377,7 @@ jobs: HOST_PLATFORM: "win-64" ARCH: "amd64" CUDA_PYTHON_COVERAGE: "1" + BINDINGS_ROOT: ${{ needs.coverage-vars.outputs.BINDINGS_ROOT }} CUDA_VER: ${{ needs.coverage-vars.outputs.CUDA_VER }} defaults: run: @@ -423,7 +449,15 @@ jobs: run: | .venv/Scripts/pip install coverage pytest-cov Cython .venv/Scripts/pip install --group ./cuda_pathfinder/pyproject.toml:test - .venv/Scripts/pip install --group ./cuda_bindings_13/pyproject.toml:test + bindings_wheels=(./wheels/cuda_bindings*.whl) + test "${#bindings_wheels[@]}" -eq 1 + test -f "${bindings_wheels[0]}" + bindings_pyproject="./${BINDINGS_ROOT}/pyproject.toml" + if grep -q '^\[dependency-groups\][[:space:]]*$' "${bindings_pyproject}"; then + .venv/Scripts/python -m pip install "${bindings_wheels[0]}" --group "${bindings_pyproject}:test" + else + .venv/Scripts/python -m pip install "${bindings_wheels[0]}[test]" + fi .venv/Scripts/pip install --group ./cuda_core/pyproject.toml:test - name: Get install root @@ -448,7 +482,7 @@ jobs: "$GITHUB_WORKSPACE/.venv/Scripts/python" -m pytest \ -v --cov=./cuda --cov-append --cov-context=test \ --cov-config="$GITHUB_WORKSPACE/.coveragerc" \ - "$GITHUB_WORKSPACE/cuda_bindings_13/tests" + "$GITHUB_WORKSPACE/${BINDINGS_ROOT}/tests" - name: Run cuda.core tests continue-on-error: true diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml index ce529fc73ce..6a4475848e8 100644 --- a/.github/workflows/test-wheel-linux.yml +++ b/.github/workflows/test-wheel-linux.yml @@ -13,7 +13,8 @@ on: host-platform: type: string required: true - build-ctk-ver: + bindings-config: + description: Normalized CUDA bindings package-root registry JSON. type: string required: true matrix_filter: @@ -52,17 +53,33 @@ defaults: jobs: compute-matrix: + if: >- + ${{ inputs.workplan == '' || + contains(fromJSON(inputs.workplan).jobs.test_cuda_majors.*, true) }} runs-on: ubuntu-latest env: + BINDINGS_CONFIG: ${{ inputs.bindings-config }} BUILD_TYPE: ${{ inputs.build-type }} + WORKPLAN: ${{ inputs.workplan }} + TEST_MODE: ${{ inputs.test-mode }} ARCH: ${{ (inputs.host-platform == 'linux-64' && 'amd64') || (inputs.host-platform == 'linux-aarch64' && 'arm64') }} outputs: MATRIX: ${{ steps.compute-matrix.outputs.MATRIX }} - OLD_BRANCH: ${{ steps.compute-matrix.outputs.OLD_BRANCH }} steps: - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ inputs.sha || github.sha }} + + - name: Checkout CI matrix helper + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # Artifact sources can predate this helper; use the workflow's revision. + ref: ${{ github.sha }} + path: .ci-control + sparse-checkout: ci/tools/select_test_matrix.py + sparse-checkout-cone-mode: false - name: Validate Test Type run: | @@ -83,27 +100,28 @@ jobs: # Read base matrix from YAML file for the specific architecture TEST_MATRIX=$(yq -o json ".linux[\"${MATRIX_TYPE}\"] | map(select(.ARCH == \"${ARCH}\"))" ci/test-matrix.yml) - # Apply matrix filter; reject custom DRIVER + FLAVOR=wsl (the - # in-container driver swap doesn't work under WSL); add a - # RUNNER_DRIVER field that maps any custom version back to - # 'latest' (the install script swaps the driver itself, so we - # need to land on the runner that ships with the most recent - # pre-installed driver); wrap in include structure. - MATRIX=$(echo "$TEST_MATRIX" | jq -c '${{ inputs.matrix_filter }} | if any(.[]; .DRIVER != "latest" and .DRIVER != "earliest" and .FLAVOR == "wsl") then "Error: custom DRIVER is not supported with FLAVOR=wsl\n" | halt_error(1) else . end | map(. + {RUNNER_DRIVER: (if .DRIVER == "latest" or .DRIVER == "earliest" then .DRIVER else "latest" end)}) | if (. | length) > 0 then {include: .} else "Error: Empty matrix\n" | halt_error(1) end') + # Keep the caller's free-form jq filter; shared Python code handles + # source selection, test suites, runner routing, and coverage checks. + MATRIX=$(jq -c '${{ inputs.matrix_filter }}' <<< "$TEST_MATRIX" \ + | python3 .ci-control/ci/tools/select_test_matrix.py --platform linux) - echo "MATRIX=${MATRIX}" | tee --append "${GITHUB_OUTPUT}" + { + echo '### Selected wheel test coverage' + echo '| Suites | Python | CTK | Toolkit source | Bindings source | GPU |' + echo '| --- | --- | --- | --- | --- | --- |' + jq -r '.include[] | "| \(.SUITES) | \(.PY_VER) | \(.CUDA_VER) | \(if .LOCAL_CTK == "1" then "local CTK" else "wheels" end) | \(if .BINDINGS_SOURCE == "local" then .BINDINGS_SOURCE_DIR else "published floor" end) | \(.GPU) |"' <<< "$MATRIX" + } >> "$GITHUB_STEP_SUMMARY" - # This job has yq already installed, so let's do it here - OLD_BRANCH=$(yq '.backport_branch' ci/versions.yml) - echo "OLD_BRANCH=${OLD_BRANCH}" >> "$GITHUB_OUTPUT" + echo "MATRIX=${MATRIX}" | tee --append "${GITHUB_OUTPUT}" test: env: + BINDINGS_CONFIG: ${{ inputs.bindings-config }} TEST_PATHFINDER: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.pathfinder.needs_test }} - TEST_BINDINGS: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.bindings.needs_test }} - TEST_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.needs_test }} - TEST_PYTHON: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.python.needs_test }} - name: Python ${{ matrix.PY_VER }}, CUDA ${{ matrix.CUDA_VER }} (${{ (matrix.LOCAL_CTK == '1' && 'local') || 'wheels' }}), GPU ${{ matrix.GPU }}${{ matrix.GPU_COUNT != '1' && format(' (x{0})', matrix.GPU_COUNT) || '' }}${{ matrix.FLAVOR && format(', {0}', matrix.FLAVOR) || '' }}${{ matrix.ENV.TORCH_VER && format(', {0}+{1}', matrix.ENV.TORCH_VER, matrix.ENV.TORCH_CUDA) || '' }}${{ matrix.ENV.MODE == 'nightly-numba-cuda' && ', latest' || '' }} + TEST_BINDINGS: ${{ inputs.workplan == '' || (matrix.BINDINGS_SOURCE == 'local' && fromJSON(inputs.workplan).modules.bindings.package_roots[matrix.BINDINGS_SOURCE_DIR].needs_test) }} + TEST_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.cuda_majors[matrix.CUDA_VARIANT].needs_test }} + TEST_PYTHON: ${{ inputs.workplan == '' || (matrix.BINDINGS_SOURCE == 'local' && fromJSON(inputs.workplan).modules.python.package_roots[matrix.BINDINGS_SOURCE_DIR].needs_test) }} + name: ${{ matrix.SUITES }} / py${{ matrix.PY_VER }}, CTK${{ matrix.CUDA_VER }} (${{ (matrix.LOCAL_CTK == '1' && 'local CTK') || 'wheels' }}; bindings ${{ matrix.BINDINGS_SOURCE == 'local' && 'PR' || 'floor' }}), GPU ${{ matrix.GPU }}${{ matrix.GPU_COUNT != '1' && format(' (x{0})', matrix.GPU_COUNT) || '' }}${{ matrix.FLAVOR && format(', {0}', matrix.FLAVOR) || '' }}${{ matrix.ENV.TORCH_VER && format(', {0}+{1}', matrix.ENV.TORCH_VER, matrix.ENV.TORCH_CUDA) || '' }}${{ matrix.ENV.MODE == 'nightly-numba-cuda' && ', latest' || '' }} timeout-minutes: 60 needs: compute-matrix strategy: @@ -111,7 +129,8 @@ jobs: matrix: ${{ fromJSON(needs.compute-matrix.outputs.MATRIX) }} runs-on: "${{ matrix.FLAVOR || 'linux' }}-${{ matrix.ARCH }}-gpu-${{ matrix.GPU }}-${{ matrix.RUNNER_DRIVER }}-${{ matrix.GPU_COUNT }}" # The build stage could fail but we want the CI to keep moving. - if: ${{ github.repository_owner == 'nvidia' && !cancelled() }} + if: ${{ github.repository_owner == 'nvidia' && !cancelled() && + (inputs.workplan == '' || contains(fromJSON(inputs.workplan).jobs.test_cuda_majors.*, true)) }} # Our self-hosted runners require a container # TODO: use a different (nvidia?) container container: @@ -142,9 +161,8 @@ jobs: # for artifact fetching, graphics libs, g++ required for cffi in # example; util-linux for `nsenter` (custom-DRIVER rows re-exec # install_gpu_driver.sh onto the host through nsenter) - # yq: ci/tools/env-vars reads ci/versions.yml with it - dependencies: "jq wget libgl1 libegl1 g++ util-linux yq" - dependent_exes: "jq wget yq" + dependencies: "jq wget libgl1 libegl1 g++ util-linux" + dependent_exes: "jq wget" - name: Update container CA certificates run: | @@ -173,10 +191,14 @@ jobs: - name: Set environment variables env: - BUILD_CUDA_VER: ${{ inputs.build-ctk-ver }} + BUILD_CUDA_VER: ${{ matrix.BINDINGS_BUILD_VERSION }} + BINDINGS_SOURCE: ${{ matrix.BINDINGS_SOURCE }} + BINDINGS_SOURCE_DIR: ${{ matrix.BINDINGS_SOURCE_DIR }} + DEFAULT_BINDINGS_SOURCE_DIR: ${{ matrix.DEFAULT_BINDINGS_SOURCE_DIR }} CUDA_VER: ${{ matrix.CUDA_VER }} HOST_PLATFORM: ${{ inputs.host-platform }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} + PATHFINDER_SOURCE: ${{ matrix.PATHFINDER_SOURCE }} PY_VER: ${{ matrix.PY_VER }} SHA: ${{ inputs.sha || github.sha }} SKIP_BINDINGS_TEST_OVERRIDE: ${{ env.TEST_BINDINGS != 'true' && '1' || '0' }} @@ -189,7 +211,8 @@ jobs: run: echo "$MATRIX_ENV" | jq -r 'to_entries[] | "\(.key)=\(.value)"' >> "$GITHUB_ENV" - name: Download cuda-pathfinder build artifacts - if: ${{ env.TEST_PATHFINDER == 'true' || env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true' }} + if: ${{ (env.TEST_PATHFINDER == 'true' || env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && + env.PATHFINDER_SOURCE == 'artifact' }} uses: $/.github/actions/download-artifact-retry with: name: cuda-pathfinder-wheel @@ -198,17 +221,17 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python build artifacts - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} uses: $/.github/actions/download-artifact-retry with: - name: cuda-python-wheel + name: ${{ env.CUDA_PYTHON_ARTIFACT_NAME }} path: . run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda.bindings build artifacts if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - (env.BINDINGS_SOURCE == 'main' || (env.BINDINGS_SOURCE == 'floor' && env.TEST_CORE == 'true')) }} + (env.BINDINGS_SOURCE == 'local' || (env.BINDINGS_SOURCE == 'floor' && env.TEST_CORE == 'true')) }} uses: $/.github/actions/download-artifact-retry with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }} @@ -216,77 +239,15 @@ jobs: run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Look up prior-branch artifacts run ID - id: prior - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # See https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt. - # gh is needed for lookup-run-id, which calls gh api. - mkdir -p -m 755 /etc/apt/keyrings \ - && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ - && cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ - && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ - && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ - && apt update \ - && apt install gh -y - - OLD_BRANCH=${{ needs.compute-matrix.outputs.OLD_BRANCH }} - OLD_ARTIFACT_PATTERN="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}-*[0-9a-f]" - LOOKUP_ARGS=( - --branch "${OLD_BRANCH}" - --artifact "${OLD_ARTIFACT_PATTERN}" - ) - if ${{ env.TEST_PYTHON == 'true' }}; then - LOOKUP_ARGS+=(--artifact cuda-python-wheel) - fi - LATEST_PRIOR_RUN_ID=$(./ci/tools/lookup-run-id \ - "${LOOKUP_ARGS[@]}" NVIDIA/cuda-python "CI") - echo "run-id=${LATEST_PRIOR_RUN_ID}" >> "${GITHUB_OUTPUT}" - echo "artifact-pattern=${OLD_ARTIFACT_PATTERN}" >> "${GITHUB_OUTPUT}" - - - name: Download prior-branch cuda.bindings build artifacts - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - uses: $/.github/actions/download-artifact-retry - with: - pattern: ${{ steps.prior.outputs.artifact-pattern }} - merge-multiple: "true" - path: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }} - run-id: ${{ steps.prior.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Download prior-branch cuda-python wheel - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'backport' }} - uses: $/.github/actions/download-artifact-retry - with: - name: cuda-python-wheel - path: . - run-id: ${{ steps.prior.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Verify prior-branch artifact layout - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - run: | - bindings_wheels=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) - if [[ "${#bindings_wheels[@]}" -ne 1 ]] || [[ ! -f "${bindings_wheels[0]}" ]]; then - echo "::error::Expected exactly one cuda_bindings wheel in ${CUDA_BINDINGS_ARTIFACTS_DIR}; found: ${bindings_wheels[*]}" - exit 1 - fi - ls -al "${CUDA_BINDINGS_ARTIFACTS_DIR}" - - name: Display structure of downloaded cuda-python artifacts - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE != 'floor' }} + if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} run: | pwd ls -lah cuda_python*.whl cuda_pathfinder/ - name: Display structure of downloaded cuda.bindings artifacts if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE != 'floor' }} + env.BINDINGS_SOURCE == 'local' }} run: | pwd ls -lahR $CUDA_BINDINGS_ARTIFACTS_DIR @@ -325,7 +286,7 @@ jobs: if: ${{ env.TEST_CORE == 'true' && env.SKIP_CYTHON_TEST == '0' }} uses: $/.github/actions/download-artifact-retry with: - name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-tests + name: ${{ env.CUDA_CORE_CYTHON_TEST_ARTIFACT_NAME }} path: ${{ env.CUDA_CORE_CYTHON_TESTS_DIR }} run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} @@ -419,22 +380,25 @@ jobs: run: run-tests core - name: Ensure cuda-python installable - if: ${{ inputs.test-mode == 'standard' && env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-mode == 'standard' && env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} + env: + LOCAL_CTK: ${{ matrix.LOCAL_CTK }} + shell: bash --noprofile --norc -xeuo pipefail {0} run: | - # Package suites install their own dependencies. A metapackage-only - # 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 ${{ env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' }}; then + # CUDA 13's metapackage also requires Core. A bindings-only release + # must resolve published Core while preserving the selected wheels. + if [[ "$TEST_CORE" == true || ("$TEST_BINDINGS" == true && "$TEST_CUDA_MAJOR" == 12) ]]; then dependency_args=(--no-deps) else - dependency_args=( - ./cuda_pathfinder/cuda_pathfinder-*.whl - "${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl - ) + dependency_args=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) + if [[ "$PATHFINDER_SOURCE" == artifact ]]; then + dependency_args+=(./cuda_pathfinder/cuda_pathfinder-*.whl) + else + dependency_args+=("$(python -c 'from importlib.metadata import version; print("cuda-pathfinder==" + version("cuda-pathfinder"))')") + fi fi python_requirements=(cuda_python*.whl) - if [[ "${{ matrix.LOCAL_CTK }}" != 1 ]]; then + if [[ "$LOCAL_CTK" != 1 ]]; then python_requirements=("${python_requirements[@]/%/[all]}") fi pip install --only-binary=:all: "${dependency_args[@]}" "${python_requirements[@]}" diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml index a3280b2962e..fbf9c17815b 100644 --- a/.github/workflows/test-wheel-windows.yml +++ b/.github/workflows/test-wheel-windows.yml @@ -13,7 +13,8 @@ on: host-platform: type: string required: true - build-ctk-ver: + bindings-config: + description: Normalized CUDA bindings package-root registry JSON. type: string required: true matrix_filter: @@ -48,18 +49,35 @@ on: jobs: compute-matrix: + if: >- + ${{ inputs.workplan == '' || + contains(fromJSON(inputs.workplan).jobs.test_cuda_majors.*, true) }} runs-on: ubuntu-latest defaults: run: shell: bash --noprofile --norc -xeuo pipefail {0} env: + BINDINGS_CONFIG: ${{ inputs.bindings-config }} BUILD_TYPE: ${{ inputs.build-type }} + WORKPLAN: ${{ inputs.workplan }} + TEST_MODE: ${{ inputs.test-mode }} ARCH: ${{ (inputs.host-platform == 'win-64' && 'amd64') }} outputs: MATRIX: ${{ steps.compute-matrix.outputs.MATRIX }} steps: - name: Checkout ${{ github.event.repository.name }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ inputs.sha || github.sha }} + + - name: Checkout CI matrix helper + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # Artifact sources can predate this helper; use the workflow's revision. + ref: ${{ github.sha }} + path: .ci-control + sparse-checkout: ci/tools/select_test_matrix.py + sparse-checkout-cone-mode: false - name: Validate Test Type run: | @@ -79,28 +97,36 @@ jobs: # Read base matrix from YAML file for the specific architecture TEST_MATRIX=$(yq -o json ".windows[\"${MATRIX_TYPE}\"] | map(select(.ARCH == \"${ARCH}\"))" ci/test-matrix.yml) - # Apply matrix filter; add a RUNNER_DRIVER field that maps any - # custom DRIVER version back to 'latest' (install_gpu_driver.ps1 - # swaps the driver itself, so the runner must be the one that - # ships the most recent pre-installed driver); wrap in include. - MATRIX=$(echo "$TEST_MATRIX" | jq -c '${{ inputs.matrix_filter }} | map(. + {RUNNER_DRIVER: (if .DRIVER == "latest" or .DRIVER == "earliest" then .DRIVER else "latest" end)}) | if (. | length) > 0 then {include: .} else "Error: Empty matrix\n" | halt_error(1) end') + # Keep the caller's free-form jq filter; shared Python code handles + # source selection, test suites, runner routing, and coverage checks. + MATRIX=$(jq -c '${{ inputs.matrix_filter }}' <<< "$TEST_MATRIX" \ + | python3 .ci-control/ci/tools/select_test_matrix.py --platform windows) + + { + echo '### Selected wheel test coverage' + echo '| Suites | Python | CTK | Toolkit source | Bindings source | GPU |' + echo '| --- | --- | --- | --- | --- | --- |' + jq -r '.include[] | "| \(.SUITES) | \(.PY_VER) | \(.CUDA_VER) | \(if .LOCAL_CTK == "1" then "local CTK" else "wheels" end) | \(if .BINDINGS_SOURCE == "local" then .BINDINGS_SOURCE_DIR else "published floor" end) | \(.GPU) |"' <<< "$MATRIX" + } >> "$GITHUB_STEP_SUMMARY" echo "MATRIX=${MATRIX}" | tee --append "${GITHUB_OUTPUT}" test: env: + BINDINGS_CONFIG: ${{ inputs.bindings-config }} TEST_PATHFINDER: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.pathfinder.needs_test }} - TEST_BINDINGS: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.bindings.needs_test }} - TEST_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.needs_test }} - TEST_PYTHON: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.python.needs_test }} - name: Python ${{ matrix.PY_VER }}, CUDA ${{ matrix.CUDA_VER }} (${{ (matrix.LOCAL_CTK == '1' && 'local') || 'wheels' }}), GPU ${{ matrix.GPU }}${{ matrix.GPU_COUNT != '1' && format(' (x{0})', matrix.GPU_COUNT) || '' }} (${{ matrix.DRIVER_MODE }})${{ matrix.ENV.TORCH_VER && format(', {0}+{1}', matrix.ENV.TORCH_VER, matrix.ENV.TORCH_CUDA) || '' }}${{ matrix.ENV.MODE == 'nightly-numba-cuda' && ', latest' || '' }} + TEST_BINDINGS: ${{ inputs.workplan == '' || (matrix.BINDINGS_SOURCE == 'local' && fromJSON(inputs.workplan).modules.bindings.package_roots[matrix.BINDINGS_SOURCE_DIR].needs_test) }} + TEST_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.cuda_majors[matrix.CUDA_VARIANT].needs_test }} + TEST_PYTHON: ${{ inputs.workplan == '' || (matrix.BINDINGS_SOURCE == 'local' && fromJSON(inputs.workplan).modules.python.package_roots[matrix.BINDINGS_SOURCE_DIR].needs_test) }} + name: ${{ matrix.SUITES }} / py${{ matrix.PY_VER }}, CTK${{ matrix.CUDA_VER }} (${{ (matrix.LOCAL_CTK == '1' && 'local CTK') || 'wheels' }}; bindings ${{ matrix.BINDINGS_SOURCE == 'local' && 'PR' || 'floor' }}), GPU ${{ matrix.GPU }}${{ matrix.GPU_COUNT != '1' && format(' (x{0})', matrix.GPU_COUNT) || '' }} (${{ matrix.DRIVER_MODE }})${{ matrix.ENV.TORCH_VER && format(', {0}+{1}', matrix.ENV.TORCH_VER, matrix.ENV.TORCH_CUDA) || '' }}${{ matrix.ENV.MODE == 'nightly-numba-cuda' && ', latest' || '' }} timeout-minutes: 60 # The build stage could fail but we want the CI to keep moving. needs: compute-matrix strategy: fail-fast: false matrix: ${{ fromJSON(needs.compute-matrix.outputs.MATRIX) }} - if: ${{ github.repository_owner == 'nvidia' && !cancelled() }} + if: ${{ github.repository_owner == 'nvidia' && !cancelled() && + (inputs.workplan == '' || contains(fromJSON(inputs.workplan).jobs.test_cuda_majors.*, true)) }} runs-on: "windows-${{ matrix.ARCH }}-gpu-${{ matrix.GPU }}-${{ matrix.RUNNER_DRIVER }}-${{ matrix.GPU_COUNT }}" steps: - name: Enable Git symlinks (Windows, must precede checkout) @@ -157,10 +183,14 @@ jobs: - name: Set environment variables env: - BUILD_CUDA_VER: ${{ inputs.build-ctk-ver }} + BUILD_CUDA_VER: ${{ matrix.BINDINGS_BUILD_VERSION }} + BINDINGS_SOURCE: ${{ matrix.BINDINGS_SOURCE }} + BINDINGS_SOURCE_DIR: ${{ matrix.BINDINGS_SOURCE_DIR }} + DEFAULT_BINDINGS_SOURCE_DIR: ${{ matrix.DEFAULT_BINDINGS_SOURCE_DIR }} CUDA_VER: ${{ matrix.CUDA_VER }} HOST_PLATFORM: ${{ inputs.host-platform }} LOCAL_CTK: ${{ matrix.LOCAL_CTK }} + PATHFINDER_SOURCE: ${{ matrix.PATHFINDER_SOURCE }} PY_VER: ${{ matrix.PY_VER }} SHA: ${{ inputs.sha || github.sha }} SKIP_BINDINGS_TEST_OVERRIDE: ${{ env.TEST_BINDINGS != 'true' && '1' || '0' }} @@ -175,7 +205,8 @@ jobs: run: echo "$MATRIX_ENV" | jq -r 'to_entries[] | "\(.key)=\(.value)"' >> "$GITHUB_ENV" - name: Download cuda-pathfinder build artifacts - if: ${{ env.TEST_PATHFINDER == 'true' || env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true' }} + if: ${{ (env.TEST_PATHFINDER == 'true' || env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && + env.PATHFINDER_SOURCE == 'artifact' }} uses: $/.github/actions/download-artifact-retry with: name: cuda-pathfinder-wheel @@ -184,17 +215,17 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda-python build artifacts - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} uses: $/.github/actions/download-artifact-retry with: - name: cuda-python-wheel + name: ${{ env.CUDA_PYTHON_ARTIFACT_NAME }} path: . run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download cuda.bindings build artifacts if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - (env.BINDINGS_SOURCE == 'main' || (env.BINDINGS_SOURCE == 'floor' && env.TEST_CORE == 'true')) }} + (env.BINDINGS_SOURCE == 'local' || (env.BINDINGS_SOURCE == 'floor' && env.TEST_CORE == 'true')) }} uses: $/.github/actions/download-artifact-retry with: name: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }} @@ -202,69 +233,15 @@ jobs: run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Look up prior-branch artifacts run ID - id: prior - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash --noprofile --norc -xeuo pipefail {0} - run: | - OLD_BRANCH=$(yq '.backport_branch' ci/versions.yml) - OLD_ARTIFACT_PATTERN="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}-*[0-9a-f]" - LOOKUP_ARGS=( - --branch "${OLD_BRANCH}" - --artifact "${OLD_ARTIFACT_PATTERN}" - ) - if ${{ env.TEST_PYTHON == 'true' }}; then - LOOKUP_ARGS+=(--artifact cuda-python-wheel) - fi - LATEST_PRIOR_RUN_ID=$(./ci/tools/lookup-run-id \ - "${LOOKUP_ARGS[@]}" NVIDIA/cuda-python "CI") - echo "run-id=${LATEST_PRIOR_RUN_ID}" >> "${GITHUB_OUTPUT}" - echo "artifact-pattern=${OLD_ARTIFACT_PATTERN}" >> "${GITHUB_OUTPUT}" - - - name: Download prior-branch cuda.bindings build artifacts - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - uses: $/.github/actions/download-artifact-retry - with: - pattern: ${{ steps.prior.outputs.artifact-pattern }} - merge-multiple: "true" - path: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }} - run-id: ${{ steps.prior.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Download prior-branch cuda-python wheel - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'backport' }} - uses: $/.github/actions/download-artifact-retry - with: - name: cuda-python-wheel - path: . - run-id: ${{ steps.prior.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Verify prior-branch artifact layout - if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE == 'backport' }} - shell: bash --noprofile --norc -xeuo pipefail {0} - run: | - bindings_wheels=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) - if [[ "${#bindings_wheels[@]}" -ne 1 ]] || [[ ! -f "${bindings_wheels[0]}" ]]; then - echo "::error::Expected exactly one cuda_bindings wheel in ${CUDA_BINDINGS_ARTIFACTS_DIR}; found: ${bindings_wheels[*]}" - exit 1 - fi - ls -al "${CUDA_BINDINGS_ARTIFACTS_DIR}" - - name: Display structure of downloaded cuda-python artifacts - if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE != 'floor' }} + if: ${{ env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} run: | Get-Location Get-ChildItem cuda_python*.whl | Select-Object Mode, LastWriteTime, Length, FullName - name: Display structure of downloaded cuda.bindings artifacts if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') && - env.BINDINGS_SOURCE != 'floor' }} + env.BINDINGS_SOURCE == 'local' }} run: | Get-Location Get-ChildItem -Recurse -Force $env:CUDA_BINDINGS_ARTIFACTS_DIR | Select-Object Mode, LastWriteTime, Length, FullName @@ -303,7 +280,7 @@ jobs: if: ${{ env.TEST_CORE == 'true' && env.SKIP_CYTHON_TEST == '0' }} uses: $/.github/actions/download-artifact-retry with: - name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-tests + name: ${{ env.CUDA_CORE_CYTHON_TEST_ARTIFACT_NAME }} path: ${{ env.CUDA_CORE_CYTHON_TESTS_DIR }} run-id: ${{ inputs.run-id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} @@ -384,25 +361,28 @@ jobs: run: run-tests core - name: Ensure cuda-python installable - if: ${{ inputs.test-mode == 'standard' && env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'main' }} + if: ${{ inputs.test-mode == 'standard' && env.TEST_PYTHON == 'true' && env.BINDINGS_SOURCE == 'local' }} + env: + LOCAL_CTK: ${{ matrix.LOCAL_CTK }} + shell: bash --noprofile --norc -xeuo pipefail {0} run: | - # Package suites install their own dependencies. A metapackage-only - # 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 ('${{ env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' }}' -eq 'true') { - $dependencyArgs = @('--no-deps') - } else { - $dependencyArgs = @( - (Get-Item ./cuda_pathfinder/cuda_pathfinder-*.whl).FullName - (Get-Item "$env:CUDA_BINDINGS_ARTIFACTS_DIR/cuda_bindings-*.whl").FullName - ) - } - $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 + # CUDA 13's metapackage also requires Core. A bindings-only release + # must resolve published Core while preserving the selected wheels. + if [[ "$TEST_CORE" == true || ("$TEST_BINDINGS" == true && "$TEST_CUDA_MAJOR" == 12) ]]; then + dependency_args=(--no-deps) + else + dependency_args=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/cuda_bindings-*.whl) + if [[ "$PATHFINDER_SOURCE" == artifact ]]; then + dependency_args+=(./cuda_pathfinder/cuda_pathfinder-*.whl) + else + dependency_args+=("$(python -c 'from importlib.metadata import version; print("cuda-pathfinder==" + version("cuda-pathfinder"))')") + fi + fi + python_requirements=(cuda_python*.whl) + if [[ "$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' && env.TEST_PATHFINDER == 'true' }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c47db15541d..0afd7bbba6e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,9 +28,7 @@ reproducers, documentation improvements, and code changes are welcome. - [CI infrastructure overview](#ci-infrastructure-overview) - [CI Pipeline Flow](#ci-pipeline-flow) - [Pipeline Execution Details](#pipeline-execution-details) - - [Branch-specific Artifact Flow](#branch-specific-artifact-flow) - - [Main Branch](#main-branch) - - [Backport Branches](#backport-branches) + - [Source and Artifact Flow](#source-and-artifact-flow) - [Key Infrastructure Details](#key-infrastructure-details) - [Code coverage](#code-coverage) @@ -128,14 +126,16 @@ correct.** Packages select tags for their own release line: | Package | Tag pattern | | --- | --- | -| `cuda-bindings` from `cuda_bindings_12/` | `v12.9.*` (e.g. `v12.9.10`) | -| `cuda-bindings` from `cuda_bindings_13/` | `v13.4.*` (e.g. `v13.4.2`) | -| `cuda-python` | The matching bindings selector, chosen with `CUDA_PYTHON_BUILD_MAJOR=12` or `13` (default) | +| `cuda-bindings` from `cuda_bindings_12/` | `v12.*` (e.g. `v12.9.10`) | +| `cuda-bindings` from `cuda_bindings_13/` | `v13.*` (e.g. `v13.4.2`) | +| `cuda-python` | The matching bindings selector, chosen explicitly with `CUDA_PYTHON_BUILD_MAJOR=12` or `13`, or inferred as described below | | `cuda-core` | `cuda-core-v*` (e.g. `cuda-core-v1.1.0`) | | `cuda-pathfinder` | `cuda-pathfinder-v*` (e.g. `cuda-pathfinder-v1.6.0`) | -Git source builds of `cuda-python` default to CUDA 13. Set -`CUDA_PYTHON_BUILD_MAJOR=12` to select CUDA 12, or `13` explicitly for CUDA 13. +Git source builds of `cuda-python` honor `CUDA_PYTHON_BUILD_MAJOR=12` or `13` +when set. Without it, an exact `v12.*` tag at `HEAD` selects CUDA 12 when no +`v13.*` tag points to that commit. Untagged commits and commits tagged for +both majors default to CUDA 13. The resolved version determines dependencies: CUDA 12 depends on matching bindings, while CUDA 13 also depends on Core and Pathfinder. A standalone sdist retains its version and dependency major without requiring this variable. @@ -453,26 +453,26 @@ The CI pipeline diagram is maintained as Mermaid source in [`ci/ci-pipeline.mmd` - **Build Stage**: Different architectures/operating systems (linux-64, linux-aarch64, win-64) are built in parallel across their respective runners - **Test Stage**: Different architectures/operating systems/CUDA versions are tested in parallel; documentation preview is also built in parallel with testing -### Branch-specific Artifact Flow +### Source and Artifact Flow -#### Main Branch -- **Build** → **Test** → **Documentation** → **Potential Release** -- Artifacts stored as `{component}-python{version}-{platform}-{sha}` -- Full test coverage across all platforms and CUDA versions -- **Artifact flow out**: `cuda-pathfinder` artifacts → backport branches +- Pushes to `main` build and test both registered bindings lines and their + dependent packages from the same source revision. +- Pull requests build affected packages and test their consumers. Unchanged + wheels and test artifacts can reuse a successful exact-baseline CI run; + without a complete usable baseline, CI builds and tests everything. +- Bindings tags select their matching bindings root and metapackage, using + published Pathfinder. They do not require a Core release. +- Other branches retain their own release procedure and compatible tooling. + Main-tree CI no longer fetches CUDA 12 bindings artifacts from `12.9.x`. -#### Backport Branches -- **Build** → **Test** → **Backport PR Creation** -- Artifacts used for validation before creating backport pull requests -- Maintains compatibility with older CUDA versions -- **Artifact flow in**: `cuda-pathfinder` artifacts ← main branch -- **Artifact flow out**: older `cuda-bindings` artifacts → main branch +See [Reading CI Jobs and Summaries](ci/README.md#reading-ci-jobs-and-summaries) +for package/major names, local versus published bindings, and reuse details. ### Key Infrastructure Details - **Self-hosted runners**: Used for Linux builds and GPU testing (more resources, faster builds) - **GitHub-hosted runners**: Used for Windows builds and general tasks -- **Artifact retention**: 30 days for GitHub Artifacts (wheels, docs, tests) +- **Artifact retention**: Set per workflow for wheels, documentation, and test results - **Cache retention**: GitHub Cache for build dependencies and environments - **Security**: All commits must be signed, untrusted code blocked - **Parallel execution**: Matrix builds across Python versions and platforms diff --git a/ci/README.md b/ci/README.md index 47fd99aeda6..1b02b3c4fde 100644 --- a/ci/README.md +++ b/ci/README.md @@ -222,12 +222,12 @@ committed lockfiles to address the eMudhra/emSign CA incident; no general lockfile refresh was performed. Re-enable maintenance only after a released Pixi passes both upstream issue -reproducers and repeated byte-stable update/lock/check cycles across all six -workspaces: the repository root, `cuda_pathfinder`, `cuda_bindings_13`, `cuda_core`, -`benchmarks/cuda_bindings`, and `benchmarks/cuda_core`. Verify both `pixi update ---no-install` and `pixi lock`, followed by repeated `pixi lock --check` commands, -converge to unchanged lockfile bytes. Then restore strict freshness checks, -scheduled refreshes, and `PIXI_LOCKED=true` in source-build CI. +reproducers and repeated byte-stable update/lock/check cycles across every +workspace reported by `python ci/tools/list_pixi_workspaces.py`, including both +bindings roots. Verify `pixi update --no-install` and `pixi lock`, followed by +repeated `pixi lock --check` commands, converge to unchanged lockfile bytes. +Then restore strict freshness checks, scheduled refreshes, and `PIXI_LOCKED=true` +in source-build CI. ## Repository Customizations @@ -323,3 +323,109 @@ are unreachable from `main`. Keep pushed tags immutable and follow the A toolkit minor rollover does not change the major-specific SCM selectors. Let reachable tags govern preview versions; release tags establish the intended release number. + +## Nightly Artifact Sources And Rollout + +`ci-nightly.yml` downloads wheels from the latest successful main CI run and +reads the bindings registry from that run's source commit. The source registry +must be compatible with the nightly workflow; the current workflow requires +schema 2. It does not translate an older registry into the new layout. +Selected rows that install a custom driver must also include its +`DRIVER_SHA256` in the source matrix. Registry compatibility alone does not +make a pre-hardening source compatible: choose a newer successful run rather +than disabling installer verification. Rows using preinstalled drivers do not +need an installer checksum. + +After multi-root CI lands on `main`, wait for the first successful, complete +main CI run containing the new registry and both bindings majors before using +it as the nightly artifact source. Until that run succeeds, auto-detection can +still select an older successful run; the nightly job then reports the +incompatible source and stops. PR CI builds and tests everything when it has +no complete, compatible artifact baseline. + +To test the nightly workflow before that main run is available, supply the ID +of a successful CI run built with the compatible registry, required wheel +artifacts, and driver-checksum metadata, such as a validated PR run: + +```console +gh workflow run ci-nightly.yml --repo NVIDIA/cuda-python --ref main -f 'run-id=' +``` + +The override selects both the wheel artifacts and their source revision. It +does not convert old artifacts or change the default selection for later +nightly runs. Once a compatible main run succeeds, ordinary nightly dispatches +can leave `run-id` empty. + +## Reading CI Jobs and Summaries + +A name such as `pathfinder+bindings12+core12+meta12 / py3.11, CTK12.9.1 +(wheels; bindings PR)` identifies the enabled test suites, Python version, +and toolkit. `meta12` means the CUDA 12 `cuda-python` metapackage; `core12` +means Core tested with CUDA 12. The corresponding CUDA 13 suites use `13`. +`pathfinder` is shared across majors. + +The two source descriptions answer different questions: + +- `wheels` or `local CTK` describes how the toolkit libraries are supplied. +- `bindings PR` uses the selected root's artifact from this CI run. Unaffected + packages can reuse exact-baseline wheels, so this label alone does not mean + the bindings were rebuilt for the PR. +- `bindings floor` uses the oldest published bindings supported by the Core + wheel for that CUDA major, as declared in its metadata. These rows test Core + or the selected nightly integration against published bindings, without + running the bindings or metapackage suites. + +Open the change-detection job's **CI workplan** summary and expand its JSON. +The component build/test flags identify selected work; the baseline records +the original run and exact source SHA for reusable artifacts. Reuse requires a +successful push CI run for the exact merge-base commit on the PR's base branch, +with the complete required artifact set. If that baseline is unavailable, CI +builds and tests everything. A bindings-only change reuses the unchanged +merged Core wheel while testing Core against the affected bindings major. + +The platform matrix-setup jobs' **Selected wheel test coverage** summaries +show the final suites, toolkit source, bindings root or published floor, and +GPU. Shared infrastructure changes, regular branch runs, and scheduled CI +cover both majors; a bindings tag deliberately selects one bindings/metapackage +line and published Pathfinder. Windows ARM64 omits CUDA 12 because that toolkit +has no Windows ARM64 build. + +`ci/tools/select_test_matrix.py` applies the shared selection and local-wheel +coverage rules after each platform reads its source matrix and applies an +optional jq filter. Matrix data comes from the artifact source revision; the +helper comes from the workflow control revision so older artifact sources do +not need to contain newly introduced CI tooling. + +## Historical Release And Documentation Reruns + +Current release and documentation workflows read package paths and toolkit +settings from the schema-2 registry committed with the release tag. For tags +that predate that registry, dispatch compatible historical tooling instead. +In particular, CUDA 13.4 releases from `13.4.x` use the release workflow on +that branch, including when rebuilding their documentation. + +Before dispatching historical tooling, bring its control branch up to date +with the applicable CI security fixes, including a verified patched Python +and current CA/download protections. Source-layout compatibility alone is +insufficient. The example below assumes those safeguards are in place; it +does not require changing the immutable release source. + +After meeting that prerequisite, validate the existing `v13.4.4` release and +rebuild its docs with: + +```console +gh workflow run release.yml --repo NVIDIA/cuda-python --ref 13.4.x \ + -f component=cuda-bindings -f release-action=dry-run \ + -f git-tag=v13.4.4 -f 'backport-git-tag=not planned' +``` + +Here `--ref 13.4.x` selects the workflow and its reusable documentation +workflow; `git-tag` selects the immutable release source. Leave `run-id` empty +to find that tag's successful CI run, or supply its validated artifact run ID +if needed. The artifacts must still exist. A dry run validates artifacts and +builds docs without publishing a release; its documentation is retained as a +workflow artifact. Optionally add `-f dry-run-docs-branch=gh-pages-dry-run` to +deploy the documentation to that preview branch. Run once per component when +validating more than one package; use `component=cuda-python` for the matching +metapackage documentation. Other historical release lines likewise need +tooling compatible with their tagged layout. diff --git a/ci/ci-pipeline.mmd b/ci/ci-pipeline.mmd index 6dcce24e4f9..a9c9abab092 100644 --- a/ci/ci-pipeline.mmd +++ b/ci/ci-pipeline.mmd @@ -42,7 +42,7 @@ flowchart TB subgraph ARTIFACTS["ARTIFACT STORAGE"] direction TB subgraph GITHUB_ARTIFACTS["GitHub Artifacts"] - GA1["Wheel files (.whl)
Test artifacts
Documentation
(30-day retention)"] + GA1["Wheel files (.whl)
Test artifacts
Documentation
(Workflow-specific retention)"] end subgraph GITHUB_CACHE["GitHub Cache"] GC1["Mini CTK cache"] diff --git a/ci/tools/env-vars b/ci/tools/env-vars index 2d01dd12a39..b036c95c620 100755 --- a/ci/tools/env-vars +++ b/ci/tools/env-vars @@ -64,6 +64,9 @@ if [[ "${BUILD_MODE}" == "build" ]]; then --host-platform "$HOST_PLATFORM" --sha "$SHA" else + CURRENT_BUILD_CUDA_VER="$(jq -r '.package_roots[] | select(.release_status == "current") | .toolkit_version' <<< "${BINDINGS_CONFIG}")" + BUILD_CUDA_MAJOR="${CURRENT_BUILD_CUDA_VER%%.*}" + BUILD_CUDA_MINOR="$(cut -d '.' -f 2 <<< "${CURRENT_BUILD_CUDA_VER}")" TEST_CUDA_MAJOR="$(cut -d '.' -f 1 <<< "${CUDA_VER}")" # BINDINGS_SOURCE controls which cuda-bindings to install at test time: @@ -82,13 +85,14 @@ else if [[ "${BINDINGS_SOURCE}" == "local" ]]; then : "${BINDINGS_SOURCE_DIR:?BINDINGS_SOURCE_DIR is required for local bindings}" - BINDINGS_BUILD_CUDA_VER="${CUDA_VER}" + BINDINGS_BUILD_CUDA_VER="${BUILD_CUDA_VER}" CUDA_BINDINGS_ROOT="${BINDINGS_SOURCE_DIR}" elif [[ "${BINDINGS_SOURCE}" == "floor" ]]; then # The matrix selects floor bindings for toolkit rows without an exact # registry match. Core declares the supported minimum for each major. : "${DEFAULT_BINDINGS_SOURCE_DIR:?DEFAULT_BINDINGS_SOURCE_DIR is required for floor bindings}" CUDA_BINDINGS_ROOT="${DEFAULT_BINDINGS_SOURCE_DIR}" + BINDINGS_BUILD_CUDA_VER="${CURRENT_BUILD_CUDA_VER}" SKIP_CUDA_BINDINGS_TEST=1 SKIP_CYTHON_TEST=1 else @@ -108,9 +112,8 @@ else CUDA_BINDINGS_CYTHON_TESTS_DIR="$(realpath "${REPO_DIR}/${CUDA_BINDINGS_ROOT}/tests/cython")" CUDA_PYTHON_ARTIFACT_NAME="cuda-python-wheel-cuda${BINDINGS_BUILD_CUDA_VER}" else - # These are unused for floor bindings, but deterministic paths make - # environment dumps and ad-hoc invocations easier to understand. - CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${CUDA_VER}-${HOST_PLATFORM}" + # Core can use the current local wheel during a toolkit minor rollover. + CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${BINDINGS_BUILD_CUDA_VER}-${HOST_PLATFORM}" CUDA_BINDINGS_ARTIFACTS_DIR="$(realpath "${REPO_DIR}/${CUDA_BINDINGS_ROOT}/dist")" CUDA_BINDINGS_CYTHON_TESTS_DIR="$(realpath "${REPO_DIR}/${CUDA_BINDINGS_ROOT}/tests/cython")" fi @@ -136,6 +139,8 @@ else echo "SKIP_CYTHON_TEST=${SKIP_CYTHON_TEST}" echo "TEST_CUDA_MAJOR=${TEST_CUDA_MAJOR}" echo "TEST_CUDA_MINOR=${TEST_CUDA_MINOR}" + echo "BUILD_CUDA_MAJOR=${BUILD_CUDA_MAJOR}" + echo "BUILD_CUDA_MINOR=${BUILD_CUDA_MINOR}" echo "CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" echo "CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${SHA}" echo "CUDA_BINDINGS_ARTIFACTS_DIR=${CUDA_BINDINGS_ARTIFACTS_DIR}" diff --git a/ci/tools/lookup-run-id b/ci/tools/lookup-run-id index 4f7eb2c043f..7ece969ded5 100755 --- a/ci/tools/lookup-run-id +++ b/ci/tools/lookup-run-id @@ -25,14 +25,11 @@ Options: --tag Find run by git tag (requires local git repo with the tag) --branch Find latest successful run on the given branch --event Restrict branch-mode runs to a trigger event (for example push) - --artifact Require an unexpired artifact matching this shell glob - (repeatable; branch mode only) --head-sha Also print the run's head commit SHA (second line) Examples: $0 --tag v13.0.1 NVIDIA/cuda-python $0 --branch main NVIDIA/cuda-python - $0 --branch 12.9.x --artifact 'cuda-bindings-python313-*' NVIDIA/cuda-python $0 --branch main --head-sha NVIDIA/cuda-python "CI" $0 --branch main --event push --head-sha NVIDIA/cuda-python "CI" EOF @@ -44,7 +41,6 @@ MODE="" REF="" HEAD_SHA_FLAG=0 EVENT="" -ARTIFACT_PATTERNS=() while [[ $# -gt 0 ]]; do case "${1}" in @@ -56,9 +52,6 @@ while [[ $# -gt 0 ]]; do [[ $# -ge 2 ]] || usage [[ -n "${MODE}" && "${MODE}" != "branch" ]] && { echo "Error: --tag and --branch are mutually exclusive" >&2; exit 1; } MODE="branch"; REF="${2}"; shift 2 ;; - --artifact) - [[ $# -ge 2 ]] || usage - ARTIFACT_PATTERNS+=("${2}"); shift 2 ;; --event) [[ $# -ge 2 && -n "${2}" ]] || usage EVENT="${2}"; shift 2 ;; @@ -84,11 +77,6 @@ WORKFLOW_NAME="${1:-CI}" if [[ -z "${REPOSITORY}" ]]; then usage; fi -if [[ "${MODE}" != "branch" && ${#ARTIFACT_PATTERNS[@]} -gt 0 ]]; then - echo "Error: --artifact is only supported with --branch" >&2 - exit 1 -fi - if [[ "${MODE}" != "branch" && -n "${EVENT}" ]]; then echo "Error: --event is only supported with --branch" >&2 exit 1 @@ -110,8 +98,8 @@ done # ── Mode: branch ── # # Walk the branch's commit history from HEAD and return the first commit -# whose workflow has a successful run matching any required artifact -# patterns. The one Actions-API filter used is ?head_sha=, which is +# whose workflow has a successful run. The one Actions-API filter used is +# ?head_sha=, which is # not on the list of filters flagged as returning stale/cached slices in # https://github.com/orgs/community/discussions/24626. if [[ "${MODE}" == "branch" ]]; then @@ -153,13 +141,7 @@ if [[ "${MODE}" == "branch" ]]; then exit 1 fi - if [[ ${#ARTIFACT_PATTERNS[@]} -gt 0 ]]; then - echo "Requiring unexpired artifacts matching:" >&2 - printf ' - %s\n' "${ARTIFACT_PATTERNS[@]}" >&2 - fi - - # Walk branch commits newest-first; accept the first commit with a - # successful run that passes the artifact check. + # Walk branch commits newest-first; accept the first successful run. COMMIT_SCAN_LIMIT="${LOOKUP_RUN_ID_COMMIT_SCAN_LIMIT:-200}" RUN_ID="" HEAD_SHA="" @@ -202,37 +184,6 @@ if [[ "${MODE}" == "branch" ]]; then for ((i=0; i&2 - exit 1 - fi - - for pattern in "${ARTIFACT_PATTERNS[@]}"; do - pattern_matched=0 - while IFS= read -r artifact_name; do - # The caller supplies a shell glob; RHS must stay unquoted. - # shellcheck disable=SC2053 - if [[ -n "${artifact_name}" && "${artifact_name}" == ${pattern} ]]; then - pattern_matched=1 - break - fi - done <<< "${ARTIFACT_NAMES}" - if [[ ${pattern_matched} == 0 ]]; then - missing_patterns+=("${pattern}") - fi - done - fi - - if [[ ${#missing_patterns[@]} -gt 0 ]]; then - echo "Skipping run ${candidate_id} (sha ${candidate_sha:0:12}, ${candidate_created_at}); missing unexpired artifact(s): ${missing_patterns[*]}" >&2 - continue - fi RUN_ID="${candidate_id}" HEAD_SHA="${candidate_sha}" @@ -244,7 +195,7 @@ if [[ "${MODE}" == "branch" ]]; then done if [[ -z "${RUN_ID}" ]]; then - echo "Error: No successful '${WORKFLOW_NAME}' run with required artifacts found in the ${commits_scanned} most-recent commits of branch '${REF}'" >&2 + echo "Error: No successful '${WORKFLOW_NAME}' run found in the ${commits_scanned} most-recent commits of branch '${REF}'" >&2 echo "Branch HEAD: ${BRANCH_HEAD_SHA}" >&2 exit 1 fi diff --git a/ci/tools/run-tests b/ci/tools/run-tests index 68fe5768deb..88c4fc40792 100755 --- a/ci/tools/run-tests +++ b/ci/tools/run-tests @@ -38,9 +38,11 @@ fi test_module=${1} TEST_FT_GROUP=() +TEST_FT_REQUIREMENT=() PYTEST_PARALLEL_ARGS=() if python -c 'import sys; assert not sys._is_gil_enabled()' 2> /dev/null; then TEST_FT_GROUP=(--group test-ft) + TEST_FT_REQUIREMENT=(pytest-run-parallel==0.10.0) PYTEST_PARALLEL_ARGS=(--parallel-threads=4) fi @@ -49,8 +51,21 @@ fi # all wheels together in a single pip call further below. if [[ "${test_module}" != nightly-* ]]; then pushd ./cuda_pathfinder - echo "Installing pathfinder wheel" - pip install ./*.whl --group test "${TEST_FT_GROUP[@]}" + if [[ "${PATHFINDER_SOURCE:-}" == "artifact" ]]; then + echo "Installing pathfinder wheel from CI artifacts" + pathfinder_wheels=(./*.whl) + if [[ "${#pathfinder_wheels[@]}" -ne 1 || ! -f "${pathfinder_wheels[0]}" ]]; then + echo "Expected exactly one cuda-pathfinder wheel in $(pwd)" >&2 + exit 1 + fi + pip install "${pathfinder_wheels[0]}" --group test "${TEST_FT_GROUP[@]}" + elif [[ "${PATHFINDER_SOURCE:-}" == "published" && "${test_module}" == "bindings" ]]; then + echo "Installing published pathfinder for a focused bindings release" + pip install cuda-pathfinder --group test "${TEST_FT_GROUP[@]}" + else + echo "Error: PATHFINDER_SOURCE must be artifact, or published for bindings release tests; got ${PATHFINDER_SOURCE:-}" >&2 + exit 1 + fi popd fi @@ -68,15 +83,33 @@ if [[ "${test_module}" == "pathfinder" ]]; then popd elif [[ "${test_module}" == "bindings" ]]; then echo "Installing bindings wheel" - pushd ./cuda_bindings_13 - if [[ "${LOCAL_CTK}" == 1 ]]; then - pip install "${CUDA_BINDINGS_ARTIFACTS_DIR}"/*.whl --group test "${TEST_FT_GROUP[@]}" - else + pushd "./${CUDA_BINDINGS_ROOT}" + bindings_wheels=("${CUDA_BINDINGS_ARTIFACTS_DIR}"/*.whl) + if [[ "${#bindings_wheels[@]}" -ne 1 || ! -f "${bindings_wheels[0]}" ]]; then + echo "Expected exactly one cuda-bindings wheel in ${CUDA_BINDINGS_ARTIFACTS_DIR}" >&2 + exit 1 + fi + bindings_requirement="${bindings_wheels[0]}" + bindings_toolkit_requirement=() + if [[ "${LOCAL_CTK}" != 1 ]]; then TEST_CUDA_MAJOR_MINOR="$(cut -d '.' -f 1-2 <<< "${CUDA_VER}")" # Keep the wheel-installed Toolkit aligned with the matrix-selected minor; # newer minors can grow ABI structs beyond the size compiled into this wheel. - pip install $(ls "${CUDA_BINDINGS_ARTIFACTS_DIR}"/*.whl)[all] --group test "${TEST_FT_GROUP[@]}" \ - "cuda-toolkit==${TEST_CUDA_MAJOR_MINOR}.*" + bindings_toolkit_requirement=("cuda-toolkit==${TEST_CUDA_MAJOR_MINOR}.*") + fi + if grep -q '^\[dependency-groups\][[:space:]]*$' pyproject.toml; then + if [[ "${LOCAL_CTK}" != 1 ]]; then + bindings_requirement+="[all]" + fi + python -m pip install "${bindings_requirement}" --group pyproject.toml:test \ + "${TEST_FT_GROUP[@]}" "${bindings_toolkit_requirement[@]}" + else + bindings_extras="test" + if [[ "${LOCAL_CTK}" != 1 ]]; then + bindings_extras="all,test" + fi + python -m pip install "${bindings_requirement}[${bindings_extras}]" \ + "${TEST_FT_REQUIREMENT[@]}" "${bindings_toolkit_requirement[@]}" fi echo "Running bindings tests" ${SANITIZER_CMD} pytest -rsxXfE -v --randomly-dont-reorganize --exclude-warning-annotations "${PYTEST_PARALLEL_ARGS[@]}" --junitxml "${TEST_RESULTS_DIR}/junit-bindings.xml" tests/ | fold_pytest_log @@ -86,13 +119,13 @@ elif [[ "${test_module}" == "bindings" ]]; then popd elif [[ "${test_module}" == "core" || "${test_module}" == nightly-* ]]; then # Shared setup for core and nightly modes. - TEST_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${CUDA_VER})" + TEST_CUDA_MAJOR="$(cut -d '.' -f 1 <<< "${CUDA_VER}")" TEST_CUDA_MAJOR_MINOR="$(cut -d '.' -f 1-2 <<< "${CUDA_VER}")" # Resolve bindings based on BINDINGS_SOURCE (set by env-vars): - # main/backport → local wheel from artifacts dir - # floor → the oldest cuda-bindings that the cuda-core wheel under test - # supports, read from that wheel and installed from PyPI + # local → matching configured-package wheel from this run + # floor -> the oldest supported bindings, read from the Core wheel + # and installed from PyPI BINDINGS_ARGS=() if [[ "${BINDINGS_SOURCE}" == "floor" ]]; then CORE_WHL_FOR_FLOOR=("${CUDA_CORE_ARTIFACTS_DIR}"/*.whl) @@ -131,10 +164,19 @@ elif [[ "${test_module}" == "core" || "${test_module}" == nightly-* ]]; then fi if [[ "${test_module}" == nightly-* ]]; then + if [[ "${PATHFINDER_SOURCE:-}" != "artifact" ]]; then + echo "Error: nightly tests require PATHFINDER_SOURCE=artifact" >&2 + exit 1 + fi # Resolve pathfinder wheel to absolute path before pushd. # CUDA_BINDINGS_ARTIFACTS_DIR and CUDA_CORE_ARTIFACTS_DIR are already # absolute (set via realpath in env-vars). - PATHFINDER_WHL=($(realpath ./cuda_pathfinder/*.whl)) + pathfinder_wheels=(./cuda_pathfinder/*.whl) + if [[ "${#pathfinder_wheels[@]}" -ne 1 || ! -f "${pathfinder_wheels[0]}" ]]; then + echo "Expected exactly one cuda-pathfinder wheel in ./cuda_pathfinder" >&2 + exit 1 + fi + PATHFINDER_WHL=("$(realpath "${pathfinder_wheels[0]}")") fi if [[ "${test_module}" == "core" ]]; then @@ -167,8 +209,8 @@ elif [[ "${test_module}" == "core" || "${test_module}" == nightly-* ]]; then pip list echo "Running core tests" ${SANITIZER_CMD} pytest -rsxXfE -v --randomly-dont-reorganize --exclude-warning-annotations "${PYTEST_PARALLEL_ARGS[@]}" --junitxml "${TEST_RESULTS_DIR}/junit-core.xml" tests/ | fold_pytest_log - # Currently our CI always installs the latest bindings (from either major version). - # This is not compatible with the test requirements. + # Compiled Cython tests require the bindings used to build them. Older + # toolkit rows intentionally exercise published floor bindings instead. if [[ "${SKIP_CYTHON_TEST}" == 0 ]]; then ${SANITIZER_CMD} pytest -rsxXfE -v --randomly-dont-reorganize --exclude-warning-annotations "${PYTEST_PARALLEL_ARGS[@]}" --junitxml "${TEST_RESULTS_DIR}/junit-core-cython.xml" tests/cython | fold_pytest_log fi diff --git a/ci/tools/select_test_matrix.py b/ci/tools/select_test_matrix.py new file mode 100644 index 00000000000..6c178fa9ba6 --- /dev/null +++ b/ci/tools/select_test_matrix.py @@ -0,0 +1,115 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Select wheel-test rows and their local or published bindings sources.""" + +from __future__ import annotations + +import argparse +import json +import os +import sys +from typing import Any + + +def select_test_matrix( + rows: list[dict[str, Any]], + packages: list[dict[str, Any]], + *, + workplan: dict[str, Any] | None = None, + build_type: str = "pull-request", + test_mode: str = "standard", + platform: str = "linux", +) -> dict[str, list[dict[str, Any]]]: + """Apply the workplan after the caller's optional jq matrix filter.""" + current_root = next(package["package_root"] for package in packages if package["release_status"] == "current") + enabled = ( + {package["cuda_variant"]: True for package in packages} + if workplan is None + else workplan["jobs"]["test_cuda_majors"] + ) + modules = None if workplan is None else workplan["modules"] + selected = [] + for source_row in rows: + major = source_row["CUDA_VER"].split(".")[0] + variant = f"cu{major}" + if not enabled.get(variant, False): + continue + ctk_target = ".".join(source_row["CUDA_VER"].split(".")[:2]) + package = next((package for package in packages if package["ctk_target"] == ctk_target), None) + root = "" if package is None else package["package_root"] + suites = [] + if test_mode != "standard": + suites.append(test_mode) + else: + if modules is None or modules["pathfinder"]["needs_test"]: + suites.append("pathfinder") + if package is not None and (modules is None or modules["bindings"]["package_roots"][root]["needs_test"]): + suites.append(f"bindings{major}") + if modules is None or modules["core"]["cuda_majors"][variant]["needs_test"]: + suites.append(f"core{major}") + if package is not None and (modules is None or modules["python"]["package_roots"][root]["needs_test"]): + suites.append(f"meta{major}") + if not suites: + continue + driver = source_row["DRIVER"] + # Custom versions are installed after scheduling on a latest-driver + # runner. WSL cannot perform that driver swap. + runner_driver = driver if driver in ("latest", "earliest") else "latest" + if platform == "linux" and runner_driver != driver and source_row.get("FLAVOR") == "wsl": + raise ValueError("custom DRIVER is not supported with FLAVOR=wsl") + selected.append( + { + **source_row, + "CUDA_VARIANT": variant, + "BINDINGS_SOURCE": "floor" if package is None else "local", + "BINDINGS_SOURCE_DIR": root, + "BINDINGS_BUILD_VERSION": "" if package is None else package["toolkit_version"], + "DEFAULT_BINDINGS_SOURCE_DIR": current_root, + "PATHFINDER_SOURCE": "artifact" if workplan is None else workplan["sources"]["pathfinder"], + "SUITES": "+".join(suites), + "RUNNER_DRIVER": runner_driver, + } + ) + if not selected: + raise ValueError("Empty matrix after CUDA-major workplan filtering") + # Nightly integrations may deliberately use published bindings with older + # toolkits. Ordinary PRs must not silently lose a required local-wheel row. + if test_mode == "standard" and build_type == "pull-request": + covered = {row["BINDINGS_SOURCE_DIR"] for row in selected if row["BINDINGS_SOURCE"] == "local"} + missing = [ + package["package_root"] + for package in packages + if enabled.get(package["cuda_variant"], False) + and ( + modules is None + or modules["bindings"]["package_roots"][package["package_root"]]["needs_test"] + or modules["python"]["package_roots"][package["package_root"]]["needs_test"] + ) + and package["package_root"] not in covered + ] + if missing: + raise ValueError(f"filtered test matrix omits required local-wheel coverage: {', '.join(missing)}") + return {"include": selected} + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--platform", choices=("linux", "windows"), required=True) + args = parser.parse_args() + try: + result = select_test_matrix( + json.load(sys.stdin), + json.loads(os.environ["BINDINGS_CONFIG"])["package_roots"], + workplan=json.loads(os.environ.get("WORKPLAN") or "null"), + build_type=os.environ["BUILD_TYPE"], + test_mode=os.environ["TEST_MODE"], + platform=args.platform, + ) + except ValueError as error: + parser.error(str(error)) + print(json.dumps(result, separators=(",", ":"))) + + +if __name__ == "__main__": + main() diff --git a/ci/tools/tests/test_merge_cuda_core_wheels.py b/ci/tools/tests/test_merge_cuda_core_wheels.py index bdabb168819..b1eab55e291 100644 --- a/ci/tools/tests/test_merge_cuda_core_wheels.py +++ b/ci/tools/tests/test_merge_cuda_core_wheels.py @@ -1,31 +1,12 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -from pathlib import Path from zipfile import ZipFile import pytest from wheel.wheelfile import WheelFile -from ci.tools.merge_cuda_core_wheels import cuda_variant_from_wheel, merge_wheels - - -@pytest.mark.agent_authored(model="gpt-5.6-sol") -@pytest.mark.parametrize( - ("name", "expected"), - [ - ("cuda_core-1.2.3-cp312-cp312-manylinux_x86_64.cu12.whl", "cu12"), - ("cuda_core-2.0.0-cp315-cp315-win_amd64.cu14.whl", "cu14"), - ], -) -def test_cuda_variant_from_wheel(name, expected): - assert cuda_variant_from_wheel(Path(name)) == expected - - -@pytest.mark.agent_authored(model="gpt-5.6-sol") -def test_cuda_variant_from_wheel_rejects_missing_suffix(): - with pytest.raises(ValueError, match=r"does not contain a \.cuN suffix"): - cuda_variant_from_wheel(Path("cuda_core-1.2.3-py3-none-any.whl")) +from ci.tools.merge_cuda_core_wheels import merge_wheels @pytest.mark.agent_authored(model="gpt-6-astra") diff --git a/ci/tools/tests/test_select_test_matrix.py b/ci/tools/tests/test_select_test_matrix.py new file mode 100644 index 00000000000..81c47ef2e1c --- /dev/null +++ b/ci/tools/tests/test_select_test_matrix.py @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +import pytest + +from ci.tools.select_test_matrix import select_test_matrix + +PACKAGES = [ + { + "package_root": "bindings12", + "toolkit_version": "12.9.1", + "ctk_target": "12.9", + "cuda_variant": "cu12", + "release_status": "maintenance", + }, + { + "package_root": "bindings13", + "toolkit_version": "13.4.2", + "ctk_target": "13.4", + "cuda_variant": "cu13", + "release_status": "current", + }, +] + + +def rows(*toolkits): + return [{"CUDA_VER": toolkit, "DRIVER": "latest"} for toolkit in toolkits] + + +def plan(*, bindings=False, core=True, meta=False): + return { + "jobs": {"test_cuda_majors": {"cu12": True, "cu13": False}}, + "sources": {"pathfinder": "artifact"}, + "modules": { + "pathfinder": {"needs_test": False}, + "bindings": {"package_roots": {package["package_root"]: {"needs_test": bindings} for package in PACKAGES}}, + "core": {"cuda_majors": {"cu12": {"needs_test": core}, "cu13": {"needs_test": core}}}, + "python": {"package_roots": {package["package_root"]: {"needs_test": meta} for package in PACKAGES}}, + }, + } + + +@pytest.mark.agent_authored(model="gpt-6.1-sol") +def test_exact_toolkit_rows_use_local_bindings_and_older_toolkits_use_published_floors(): + matrix = select_test_matrix(rows("12.9.1", "12.6.3", "13.4.2", "13.0.2"), PACKAGES) + + assert [(row["CUDA_VARIANT"], row["BINDINGS_SOURCE"], row["BINDINGS_SOURCE_DIR"]) for row in matrix["include"]] == [ + ("cu12", "local", "bindings12"), + ("cu12", "floor", ""), + ("cu13", "local", "bindings13"), + ("cu13", "floor", ""), + ] + + +@pytest.mark.agent_authored(model="gpt-6.1-sol") +def test_workplan_retains_only_the_required_cuda_major_and_suites(): + matrix = select_test_matrix( + rows("12.9.1", "12.6.3", "13.4.2"), PACKAGES, workplan=plan(bindings=True, core=False, meta=True) + ) + + # Without Core or Pathfinder tests the older-toolkit row has no applicable + # suites. The required maintenance bindings/metapackage row must remain. + assert [(row["CUDA_VER"], row["BINDINGS_SOURCE_DIR"]) for row in matrix["include"]] == [("12.9.1", "bindings12")] + + +@pytest.mark.parametrize("component", ("bindings", "meta")) +@pytest.mark.agent_authored(model="gpt-6.1-sol") +def test_filter_cannot_silently_drop_required_local_wheel_coverage(component): + with pytest.raises(ValueError, match="omits required local-wheel coverage: bindings12"): + select_test_matrix(rows("12.6.3", "13.4.2"), PACKAGES, workplan=plan(**{component: True})) + + +@pytest.mark.parametrize("test_mode", ("nightly-pytorch", "standard")) +@pytest.mark.agent_authored(model="gpt-6.1-sol") +def test_nightly_subsets_may_use_published_floor_bindings(test_mode): + matrix = select_test_matrix(rows("12.6.3"), PACKAGES, build_type="nightly", test_mode=test_mode) + + assert [row["BINDINGS_SOURCE"] for row in matrix["include"]] == ["floor"] + + +@pytest.mark.agent_authored(model="gpt-6") +def test_toolkit_patch_updates_keep_nightly_bindings_coverage(): + packages = [dict(package) for package in PACKAGES] + packages[1]["toolkit_version"] = "13.4.3" + + row = select_test_matrix(rows("13.4.2"), packages, build_type="nightly")["include"][0] + + assert row["BINDINGS_SOURCE"] == "local" + assert row["BINDINGS_BUILD_VERSION"] == "13.4.3" + assert {"bindings13", "meta13"} <= set(row["SUITES"].split("+")) diff --git a/cuda_bindings_12/docs/README.md b/cuda_bindings_12/docs/README.md index 8b445f41e65..9465dcedf39 100644 --- a/cuda_bindings_12/docs/README.md +++ b/cuda_bindings_12/docs/README.md @@ -1,10 +1,22 @@ # Build the documentation -1. Install the `cuda-bindings` package of the version that we need to document. +Use a separate environment from CUDA 13 documentation builds: both roots +install the same `cuda-bindings` distribution and `cuda.bindings` namespace. +The aggregate `cuda_python/docs/build_all_docs.sh` script builds the current +CUDA 13 line, so build this maintenance documentation separately. + +1. Install the CUDA 12 `cuda-bindings` build that you need to document. 2. Ensure the version is included in the canonical [`nv-versions.json`](../../cuda_bindings_13/docs/nv-versions.json). 3. Build the docs with `./build_docs.sh`. 4. The html artifacts should be available under both `./build/html/latest` and `./build/html/`. -To publish the docs with the built version, it is important to note that the html files of older versions -should be kept intact, in order for the version selection (through `nv-versions.json`) to work. +The Pixi `docs` environment currently installs a published `12.9.*` package. +To document APIs changed in the checkout, install the matching source build +in your documentation environment before running `./build_docs.sh`. + +`build/html/latest` is for local preview only. Follow the selected branch's +release procedure for publication. Maintenance publication must exclude `latest` +and the shared version-selector files so it cannot overwrite the current-major +site. Keep older versioned pages intact; do not publish the entire local build +directory over the shared site. diff --git a/cuda_bindings_12/docs/source/install.md b/cuda_bindings_12/docs/source/install.md index 728c06729a4..3696157ab8c 100644 --- a/cuda_bindings_12/docs/source/install.md +++ b/cuda_bindings_12/docs/source/install.md @@ -6,14 +6,24 @@ * Linux (x86-64, arm64) and Windows (x86-64) * Python 3.11 - 3.15 -* Driver: Linux (450.80.02 or later) Windows (456.38 or later) -* Optionally, NVRTC, nvJitLink, and NVVM from CUDA Toolkit 12.x +* Driver: Linux (525.60.13 or later), Windows (528.33 or later) +* Optionally, NVRTC, nvJitLink, NVVM, nvFatbin, and cuFile (Linux only) from CUDA Toolkit 12.x + +These driver versions are the CUDA 12 minor-version compatibility baseline in the +[CUDA 12.9 release notes](https://docs.nvidia.com/cuda/archive/12.9.1/cuda-toolkit-release-notes/index.html#cuda-driver). +Features introduced with newer drivers and PTX compilation can require a newer +driver; see the +[minor-version compatibility limitations](https://docs.nvidia.com/deploy/cuda-compatibility/minor-version-compatibility.html#application-considerations-for-minor-version-compatibility). ```{note} The optional CUDA Toolkit components can be installed via PyPI, Conda, OS-specific package managers, or local installers (as described in the CUDA Toolkit [Windows](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html) and [Linux](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html) Installation Guides). ``` -Starting from v12.8.0, `cuda-python` becomes a meta package which currently depends only on `cuda-bindings`; in the future more sub-packages will be added to `cuda-python`. In the instructions below, we still use `cuda-python` as example to serve existing users, but everything is applicable to `cuda-bindings` as well. +The CUDA 12 releases of `cuda-python` are a metapackage that depends directly +on `cuda-bindings`. The examples below use `cuda-python` for existing users; +install `cuda-bindings` directly if you only need the low-level interfaces. + +Both main-tree CUDA 12 packages require Python 3.11 or newer. ## Installing from PyPI @@ -32,6 +42,8 @@ Where the optional dependencies are: * nvidia-cuda-nvrtc-cu12 (Provides NVRTC shared library) * nvidia-nvjitlink-cu12>=12.3 (Provides nvJitLink shared library) * nvidia-cuda-nvcc-cu12 (Provides NVVM shared library) +* nvidia-nvfatbin-cu12 (Provides nvFatbin shared library) +* nvidia-cufile-cu12 (Provides cuFile shared library, Linux only) ## Installing from Conda @@ -43,6 +55,19 @@ $ conda install -c conda-forge cuda-python=12.9 ## Installing from Source +Start with the repository +[recommended clone](https://github.com/NVIDIA/cuda-python/blob/main/CONTRIBUTING.md#recommended-clone). +On native Windows outside WSL, complete its symlink setup before cloning. +CUDA 12 sources live in `cuda_bindings_12/`; CUDA 13 sources have a separate root. +Both build the same `cuda-bindings` distribution, so use a separate Python +environment for each major. + +Versions are derived from reachable `v12.*` tags using `setuptools-scm`. +Historical tags from the old maintenance branch may not be ancestors of `main`. +Before a suitable tag is reachable, follow the +[maintenance preview-build guidance](https://github.com/NVIDIA/cuda-python/blob/main/ci/README.md#cuda-bindings-package-root-registry) +in an independent clone; worktrees share tags with the rest of their repository. + ### Requirements * CUDA Toolkit headers[^1] @@ -67,10 +92,12 @@ Only `cydriver`, `cyruntime` and `cynvrtc` are impacted by the header requiremen ### Editable Install -You can use +From the repository root, run: ```console -$ pip install -v -e . +$ cd cuda_bindings_12 +$ python -m pip install -v -e . ``` -to install the module as editable in your current Python environment (e.g. for testing of porting other libraries to use the binding). +This installs the CUDA 12 bindings as editable in your current Python environment +for development and testing. diff --git a/cuda_bindings_12/docs/source/release/12.X.Y-notes.rst b/cuda_bindings_12/docs/source/release/12.X.Y-notes.rst index 08a35aaf194..4aaf9485ad6 100644 --- a/cuda_bindings_12/docs/source/release/12.X.Y-notes.rst +++ b/cuda_bindings_12/docs/source/release/12.X.Y-notes.rst @@ -24,3 +24,11 @@ Packaging declarations and includes (``.pxd`` and ``.pxi``), together with required headers, remain available for downstream Cython builds. Source distributions retain the sources, templates, and other inputs needed to build the package. + +Documentation +------------- + +* Corrected the CUDA 12 driver guidance to its existing minor-version + compatibility baseline: Linux 525.60.13 and Windows 528.33. This is a + documentation correction, not a new runtime version check. Newer features + and PTX compilation can still require a newer driver. diff --git a/cuda_bindings_12/tests/nvml/test_cuda.py b/cuda_bindings_12/tests/nvml/test_cuda.py index d05e2634a12..aaab23e55fe 100644 --- a/cuda_bindings_12/tests/nvml/test_cuda.py +++ b/cuda_bindings_12/tests/nvml/test_cuda.py @@ -1,6 +1,8 @@ # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +import pytest + import cuda.bindings.driver as cuda from cuda.bindings import nvml @@ -15,10 +17,15 @@ def get_nvml_device_names(): for idx in range(num_devices): handle = nvml.device_get_handle_by_index_v2(idx) name = nvml.device_get_name(handle) - info = nvml.device_get_pci_info_v3(handle) - assert isinstance(info.bus, int) + try: + info = nvml.device_get_pci_info_v3(handle) + except nvml.NotSupportedError: + bus_id = -1 + else: + bus_id = info.bus + assert isinstance(bus_id, int) assert isinstance(name, str) - result.append({"name": name, "id": info.bus}) + result.append({"name": name, "id": bus_id}) return result @@ -54,4 +61,15 @@ def test_cuda_device_order(): cuda_devices = get_cuda_device_names() nvml_devices = get_nvml_device_names() - assert cuda_devices == nvml_devices, "CUDA and NVML device lists do not match" + for kind in ("Orin", "Thor"): + if any(kind in device["name"] for device in nvml_devices): + pytest.skip(f"Skipping test on {kind}, which has non-standard device naming") + + def compare(cuda_device, nvml_device): + return cuda_device["name"] == nvml_device["name"] and ( + nvml_device["id"] == -1 or cuda_device["id"] == nvml_device["id"] + ) + + assert len(cuda_devices) <= len(nvml_devices) + for cuda_device in cuda_devices: + assert any(compare(cuda_device, nvml_device) for nvml_device in nvml_devices) diff --git a/cuda_bindings_12/tests/nvml/test_init.py b/cuda_bindings_12/tests/nvml/test_init.py index 2be94434591..fcde20853d7 100644 --- a/cuda_bindings_12/tests/nvml/test_init.py +++ b/cuda_bindings_12/tests/nvml/test_init.py @@ -6,7 +6,15 @@ import pytest -from cuda.bindings import nvml +from cuda.bindings import driver, nvml + + +def _driver_version_at_least_13_4(): + (status,) = driver.cuInit(0) + assert status == driver.CUresult.CUDA_SUCCESS + status, version = driver.cuDriverGetVersion() + assert status == driver.CUresult.CUDA_SUCCESS + return version >= 13040 def assert_nvml_is_initialized(): @@ -36,10 +44,14 @@ def test_devices_are_the_same_architecture(all_devices): @pytest.mark.skipif(sys.platform == "win32", reason="Test not supported on Windows") +@pytest.mark.thread_unsafe(reason="nvml init affects other threads") def test_init_ref_count(): """ Verifies that we can call NVML shutdown and init(2) multiple times, and that ref counting works """ + if _driver_version_at_least_13_4(): + pytest.skip("Init behavior changed in CUDA 13.4") + with pytest.raises(nvml.UninitializedError): nvml.shutdown() diff --git a/cuda_bindings_12/tests/nvml/test_pynvml.py b/cuda_bindings_12/tests/nvml/test_pynvml.py index a96b2c87575..e3ea533dd83 100644 --- a/cuda_bindings_12/tests/nvml/test_pynvml.py +++ b/cuda_bindings_12/tests/nvml/test_pynvml.py @@ -4,8 +4,6 @@ # A set of tests ported from https://github.com/gpuopenanalytics/pynvml/blob/11.5.3/pynvml/tests/test_nvml.py import os -import time - import pytest from cuda.bindings import nvml @@ -147,22 +145,6 @@ def test_device_get_power_usage(ngpus, handles): assert power_mwatts >= 0.0 -def test_device_get_total_energy_consumption(ngpus, handles): - for i in range(ngpus): - with unsupported_before(handles[i], nvml.DeviceArch.VOLTA): - energy_mjoules1 = nvml.device_get_total_energy_consumption(handles[i]) - - for j in range(10): # idle for 150 ms - time.sleep(0.015) # and check for increase every 15 ms - with unsupported_before(handles[i], nvml.DeviceArch.VOLTA): - energy_mjoules2 = nvml.device_get_total_energy_consumption(handles[i]) - assert energy_mjoules2 >= energy_mjoules1 - if energy_mjoules2 > energy_mjoules1: - break - else: - raise AssertionError("energy did not increase across 150 ms interval") - - # [Skipping] pynvml.nvmlDeviceGetGpuOperationMode # [Skipping] pynvml.nvmlDeviceGetCurrentGpuOperationMode # [Skipping] pynvml.nvmlDeviceGetPendingGpuOperationMode diff --git a/cuda_bindings_12/tests/nvml/util.py b/cuda_bindings_12/tests/nvml/util.py index 038fe58d8be..06cb1c2277a 100644 --- a/cuda_bindings_12/tests/nvml/util.py +++ b/cuda_bindings_12/tests/nvml/util.py @@ -43,5 +43,5 @@ def supports_ecc(device): def supports_nvlink(device): fields = nvml.FieldValue(1) - fields[0].field_id = nvml.FI.DEV_NVLINK_GET_STATE + fields[0].field_id = nvml.FieldId.DEV_NVLINK_GET_STATE return nvml.device_get_field_values(device, fields)[0].nvml_return == nvml.Return.SUCCESS diff --git a/cuda_bindings_12/tests/test_cuda.py b/cuda_bindings_12/tests/test_cuda.py index a03844a2b84..57744c95df8 100644 --- a/cuda_bindings_12/tests/test_cuda.py +++ b/cuda_bindings_12/tests/test_cuda.py @@ -610,6 +610,7 @@ def test_cuda_graphMem_attr(): or not supportsCudaAPI("cuCoredumpGetAttributeGlobal"), reason="Coredump API not present", ) +@pytest.mark.thread_unsafe(reason="coredump settings are process-global") def test_cuda_coredump_attr(): (err,) = cuda.cuInit(0) assert err == cuda.CUresult.CUDA_SUCCESS diff --git a/cuda_bindings_13/docs/README.md b/cuda_bindings_13/docs/README.md index 54d670d0917..c0311407c28 100644 --- a/cuda_bindings_13/docs/README.md +++ b/cuda_bindings_13/docs/README.md @@ -1,11 +1,15 @@ # Build the documentation -1. Install the `cuda-bindings` package of the version that we need to document. +1. Install the CUDA 13 `cuda-bindings` build that you need to document. 2. Ensure the version is included in the [`nv-versions.json`](./nv-versions.json). 3. Build the docs with `./build_docs.sh`. 4. The html artifacts should be available under both `./build/html/latest` and `./build/html/`. -Alternatively, we can build all the docs at once by running [`cuda_python/docs/build_all_docs.sh`](../../cuda_python/docs/build_all_docs.sh). +[`cuda_python/docs/build_all_docs.sh`](../../cuda_python/docs/build_all_docs.sh) +builds this current bindings line together with the metapackage, Core, and +Pathfinder documentation. Build [CUDA 12 maintenance documentation](../../cuda_bindings_12/docs/README.md) +separately in its own environment; both roots install the same `cuda-bindings` +distribution and `cuda.bindings` namespace. To publish the docs with the built version, it is important to note that the html files of older versions should be kept intact, in order for the version selection (through `nv-versions.json`) to work. diff --git a/cuda_bindings_13/docs/build_docs.sh b/cuda_bindings_13/docs/build_docs.sh index 199ababce60..53d0e14d0ea 100755 --- a/cuda_bindings_13/docs/build_docs.sh +++ b/cuda_bindings_13/docs/build_docs.sh @@ -16,13 +16,12 @@ fi # SPHINX_CUDA_BINDINGS_VER is used to create a subdir under build/html # (the Makefile file for sphinx-build also honors it if defined). -# If there's a post release (ex: .post1) we don't want it to show up in the -# version selector or directory structure. +# Post releases reuse their base release directory, while prerelease and +# development releases remain distinct so they cannot overwrite stable docs. if [[ -z "${SPHINX_CUDA_BINDINGS_VER}" ]]; then export SPHINX_CUDA_BINDINGS_VER=$(python -c "from importlib.metadata import version; \ - ver = '.'.join(str(version('cuda-bindings')).split('.')[:3]); \ - print(ver)" \ - | awk -F'+' '{print $1}') + ver = str(version('cuda-bindings')).split('+', 1)[0]; \ + print(ver if '.dev' in ver else ver.split('.post', 1)[0])") fi if [[ "${LATEST_ONLY}" == "1" && -z "${BUILD_PREVIEW:-}" && -z "${BUILD_LATEST:-}" ]]; then diff --git a/cuda_bindings_13/docs/source/install.rst b/cuda_bindings_13/docs/source/install.rst index 4958b096238..d5e7dee4839 100644 --- a/cuda_bindings_13/docs/source/install.rst +++ b/cuda_bindings_13/docs/source/install.rst @@ -18,7 +18,11 @@ Runtime Requirements The optional CUDA Toolkit components are now installed via the ``cuda-toolkit`` metapackage from PyPI for improved dependency resolution. Components can also be installed via Conda, OS-specific package managers, or local installers (as described in the CUDA Toolkit `Windows `_ and `Linux `_ Installation Guides). -Starting from v12.8.0, ``cuda-python`` becomes a meta package which currently depends only on ``cuda-bindings``; in the future more sub-packages will be added to ``cuda-python``. In the instructions below, we still use ``cuda-python`` as example to serve existing users, but everything is applicable to ``cuda-bindings`` as well. +The CUDA 13 releases of ``cuda-python`` are a metapackage that installs +``cuda-bindings``, ``cuda-core``, and ``cuda-pathfinder``. The examples below use +``cuda-python`` for existing users; install ``cuda-bindings`` directly if you +only need the low-level interfaces. Its ``all`` extra installs the optional +Toolkit components listed below. Free-threading Build Support @@ -108,9 +112,9 @@ obtain the most recent build, use the following commands: Replace ``python312`` with your Python version (e.g. ``python311``, ``python313``, ``python314``, ``python314t``, ``python315``, ``python315t``). For aarch64, replace ``linux-64`` -with ``linux-aarch64``; for Windows, use ``win-64``. Only the current CUDA -major version is built on ``main``; wheels for the prior CUDA major are -published from the corresponding backport branch. +with ``linux-aarch64``; for Windows, use ``win-64``. To use the CUDA 12 line, +replace ``cuda13`` with ``cuda12`` in both commands. Both supported CUDA major +lines are published by CI from ``main``. Installing from Source ~~~~~~~~~~~~~~~~~~~~~~ @@ -133,8 +137,10 @@ Requirements .. [#] The CUDA Runtime static library (``libcudart_static.a`` on Linux, ``cudart_static.lib`` on Windows) is part of the CUDA Toolkit. If using conda packages, it is contained in the ``cuda-cudart-static`` package. .. [#] The version is derived from git tags via ``setuptools-scm``, so the clone - must include tags reaching back to at least the latest ``v*`` tag. Do not use - ``--depth`` or ``--no-tags``: a clone without reachable tags can build with a + must include a reachable tag matching the release line configured in this + package's ``pyproject.toml`` (currently ``v13.*``). A tag from the other CUDA + major does not determine this package's version. Do not use ``--depth`` or + ``--no-tags``: a clone without matching reachable tags can build with a bogus version such as ``0.1.dev1+g0d22cb444``. See `Cloning the repository `_ for details. diff --git a/cuda_bindings_13/docs/source/support.rst b/cuda_bindings_13/docs/source/support.rst index 665c29c029f..b9617826d5c 100644 --- a/cuda_bindings_13/docs/source/support.rst +++ b/cuda_bindings_13/docs/source/support.rst @@ -12,8 +12,8 @@ The ``cuda.bindings`` module has the following support policy: third number in the version string), however, is reserved to reflect Python-only changes and is out of sync with the Toolkit patch version. 2. The module is actively maintained to support the latest CUDA major version and its prior major - version. For example, as of writing the bindings for CUDA 12 & 13 are maintained. Any fix in the - latest bindings would be backported to the prior major version. + version. Both active source trees live on the main branch so applicable fixes can update the + CUDA 12 and CUDA 13 packages in one change. 3. The module supports `CUDA minor version compatibility`_, meaning that ``cuda.bindings`` 12.x supports any Toolkit 12.y. (Whether or not a binding API would actually correctly function depends on the underlying driver and the Toolkit versions, as described in the compatibility diff --git a/cuda_bindings_13/pixi.lock b/cuda_bindings_13/pixi.lock index da78181c381..9c97e6117a6 100644 --- a/cuda_bindings_13/pixi.lock +++ b/cuda_bindings_13/pixi.lock @@ -2,13 +2,13 @@ version: 7 platforms: - name: linux-64 virtual-packages: - - __unix=0 + - __unix=0=0 - __linux=4.18 - __glibc=2.28 - __archspec=0=x86_64 - name: linux-aarch64 virtual-packages: - - __unix=0 + - __unix=0=0 - __linux=4.18 - __glibc=2.28 - __archspec=0=aarch64 @@ -2027,9 +2027,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py312he9c40d5_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/charset-normalizer-3.5.2-h1114479_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-13.2.0-py312hf79963d_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvrtc-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-13.5.37-h69a702a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-13.5.37-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-13.5.37-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.9-py312h68e6be4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.22-py312h80505a6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-h7cc23a3_1.conda @@ -2101,7 +2102,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.15-py312hd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.8.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-64-13.5.37-ha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda @@ -2194,15 +2195,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.48.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.1-pyh5ded981_0.conda + - conda_source: cuda-bindings[c92b487d] @ . + - conda_source: cuda-pathfinder[10e1cc92] @ ../cuda_pathfinder - pypi: https://files.pythonhosted.org/packages/8c/79/017fab2f7167a9a9795665f894d04f77aafceca80821b51589bb4b23ff5c/nvidia_sphinx_theme-0.0.9.post1-py3-none-any.whl linux-aarch64: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.7.0-py312h22d1088_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py312h41c1d46_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_10.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-bindings-13.2.0-py312hdc0efb6_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-13.5.37-he9431aa_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-impl-13.5.37-hbe86820_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-tools-13.5.37-hbe86820_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.9-py312hbda70bc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/debugpy-1.8.22-py312ha0853ce_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h5bc82ec_1.conda @@ -2276,7 +2280,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.15-py312hd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.8.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-aarch64-13.5.37-h579c4fd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda @@ -2369,6 +2373,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.48.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.1-pyh5ded981_0.conda + - conda_source: cuda-bindings[d088a16d] @ . + - conda_source: cuda-pathfinder[f06c437b] @ ../cuda_pathfinder - pypi: https://files.pythonhosted.org/packages/8c/79/017fab2f7167a9a9795665f894d04f77aafceca80821b51589bb4b23ff5c/nvidia_sphinx_theme-0.0.9.post1-py3-none-any.whl win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda @@ -2388,7 +2394,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.15-py312hd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.8.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_win-64-13.5.37-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda @@ -2485,9 +2491,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py312ha763cb9_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/charset-normalizer-3.5.2-h308a848_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-bindings-13.2.0-py312hc128f0a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvrtc-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-13.5.37-h719f0c7_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-impl-13.5.37-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-tools-13.5.37-hfd05255_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cython-3.2.9-py312hd245ac3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.22-py312ha1a9051_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h5112557_2.conda @@ -2538,6 +2545,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h3a581c9_12.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda + - conda_source: cuda-bindings[c345f5cd] @ . + - conda_source: cuda-pathfinder[6a6a6b0a] @ ../cuda_pathfinder - pypi: https://files.pythonhosted.org/packages/8c/79/017fab2f7167a9a9795665f894d04f77aafceca80821b51589bb4b23ff5c/nvidia_sphinx_theme-0.0.9.post1-py3-none-any.whl packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda @@ -2597,7 +2606,7 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: BSD-3-Clause AND MIT AND EPL-2.0 purls: - - pkg:pypi/backports-zstd?source=compressed-mapping + - pkg:pypi/backports-zstd?source=hash-mapping run_exports: {} size: 241113 timestamp: 1788491295568 @@ -2614,6 +2623,18 @@ packages: run_exports: {} size: 3713752 timestamp: 1784214522814 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.46.1-default_hfdba357_103.conda + sha256: 98f9ddc6dc5d56a824b7eaea5bab6ad4bb47642288fc70d6b1b4024ac39d5595 + md5: e86f9dc615d7533c5be8b15b3a1dee8d + depends: + - ld_impl_linux-64 2.46.1 default_hbd61a6d_103 + - sysroot_linux-64 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 3706604 + timestamp: 1791565481839 - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.46.1-default_h4852527_102.conda sha256: 08d7238663fc408ba2ab60b02fa3d06a7ca9d872962e03e90c7e0fdecb7ed1d0 md5: 32fd07abe84eb14f17c7f5cc6fa8df82 @@ -2624,6 +2645,16 @@ packages: run_exports: {} size: 36337 timestamp: 1784214551894 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.46.1-default_h4852527_103.conda + sha256: 606a42c754752fb905fe2012d52ff370d47b5b6adefd5f7befc4ec30ce758f23 + md5: ca26f0a4f8d04fd83147af557fbd932c + depends: + - binutils_impl_linux-64 2.46.1 default_hfdba357_103 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 36335 + timestamp: 1791565508736 - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-h505cf86_4.conda sha256: 61b78574f002390b6a7fc79834fc344beaab09550068a51100eea5a485dac741 md5: 746aa619a1bcaf4da541101179d7c60e @@ -2764,31 +2795,6 @@ packages: run_exports: {} size: 331601 timestamp: 1789746783338 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-13.2.0-py312hf79963d_1.conda - sha256: 749c0e2e664f76833a24a7a4d970a643888ca582fba1c46ca1b7c01b245dc99d - md5: 13d8b143b3513c95a1d3aec4e65a9529 - depends: - - __glibc >=2.17,<3.0.a0 - - cuda-nvrtc >=13,<14.0a0 - - cuda-nvvm-impl >=13,<14.0a0 - - cuda-pathfinder >=1.1.0,<2 - - cuda-version >=13,<14.0a0 - - libcufile >=1,<2.0a0 - - libgcc >=14 - - libnvfatbin - - libnvjitlink >=13.0,<14.0a0 - - libstdcxx >=14 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - constrains: - - cuda-python >=13.2.0,<13.3.0a0 - - cuda-cudart >=13,<14.0a0 - license: LicenseRef-NVIDIA-SOFTWARE-LICENSE - purls: - - pkg:pypi/cuda-bindings?source=hash-mapping - run_exports: {} - size: 4143685 - timestamp: 1779249651391 - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda sha256: 57d1294ecfaf9dc8cdb5fc4be3e63ebc7614538bddb5de53cfd9b1b7de43aed5 md5: cb15315d19b58bd9cd424084e58ad081 @@ -3968,6 +3974,19 @@ packages: run_exports: {} size: 77893 timestamp: 1790346247149 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.9.0-hd2095e1_0.conda + sha256: 7b930a8b6bc6553cb754b4977a11f9c862c719a652fc2d128d89270992ce8beb + md5: 317ecabe4a58b3068c7958dc5eb89e43 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15 + constrains: + - expat 2.9.0.* + license: MIT + license_family: MIT + run_exports: {} + size: 78894 + timestamp: 1793054221966 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.7.0-h81df57d_1.conda sha256: c8c7583ef063bc3c430f1d48298e5ad24f796a35c22ed5b14183325825a61106 md5: 6525a0b06aa4fd390795f0740636a9dd @@ -5005,6 +5024,17 @@ packages: run_exports: {} size: 572864 timestamp: 1790777898360 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-262.1-h26e0ef7_0.conda + sha256: fc930c169a0844dcb1f3084032d3f4e53798b2f48d4c7f4a151a87012833008a + md5: a6bb6ea85431d21bebdf7184517524ca + depends: + - __glibc >=2.17,<3.0.a0 + - libcap >=2.78,<2.79.0a0 + - libgcc >=15 + license: LGPL-2.1-or-later + run_exports: {} + size: 574718 + timestamp: 1792224216335 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.2-hcc2c06a_1.conda sha256: 10e125da82ca93e09191e66e5a94d566b2cf8d4024e2a0db3a9114297447e0d9 md5: 0907d876f460ebc941ae590338b6102f @@ -5038,6 +5068,17 @@ packages: run_exports: {} size: 184629 timestamp: 1790777902394 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libudev1-262.1-h26e0ef7_0.conda + sha256: 63bc48418ed3be6166c27f294504153bf3da8579aa5d565ae4fee8bdd1682e54 + md5: b7e3531ad0f828ee27f5731fcb9ebdc3 + depends: + - __glibc >=2.17,<3.0.a0 + - libcap >=2.78,<2.79.0a0 + - libgcc >=15 + license: LGPL-2.1-or-later + run_exports: {} + size: 184945 + timestamp: 1792224219990 - conda: https://conda.anaconda.org/conda-forge/linux-64/libunwind-1.8.3-h65a8314_0.conda sha256: 71c8b9d5c72473752a0bb6e91b01dd209a03916cb71f36cc6a564e3a2a132d7a md5: e179a69edd30d75c0144d7a380b88f28 @@ -5096,6 +5137,19 @@ packages: - libuuid >=2.42.4,<3.0a0 size: 34442 timestamp: 1790121449161 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.4-hcfc3c73_1.conda + sha256: 0e2e8f2daa9306e67f046e31092d637431d8cf0a26c407ab22401d108c2d4631 + md5: d852293faea3c04a6e896b908b43aded + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libuuid >=2.42.4,<3.0a0 + size: 36134 + timestamp: 1793891599274 - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.24.1-hb83e432_1.conda sha256: ce7fbe2855257467196613b9fa2bdedb36d4fc3419c43804e52cfe9eb094a35e md5: c3e6df2790fff34ba708722052f02c0e @@ -6038,7 +6092,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/ruamel-yaml-clib?source=compressed-mapping + - pkg:pypi/ruamel-yaml-clib?source=hash-mapping run_exports: {} size: 158648 timestamp: 1788881211578 @@ -6272,6 +6326,20 @@ packages: run_exports: {} size: 14755479 timestamp: 1792672505702 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.13.7-h535ca38_0.conda + sha256: a3014d1c201d62e6192309d67ed50075ce492981b4721bd5b8e7cb222d0c257f + md5: 53bdba3e216e191f2f0ea261efc3c9c2 + depends: + - libgcc >=15 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=15 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - __glibc >=2.17 + license: Apache-2.0 OR MIT + run_exports: {} + size: 14855143 + timestamp: 1793689081389 - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.26.0-hc1c935e_2.conda sha256: df65b987979e6d7f88e756494da5a230d4f2d08d17437d04eecd35559c3a04e4 md5: 88a47e22b53e50865b1cabe2eb648352 @@ -6833,6 +6901,18 @@ packages: run_exports: {} size: 4677171 timestamp: 1784214549910 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.46.1-default_h5f4c503_103.conda + sha256: 1827893f9d6aa13794196b1820b8003bfff0105774a323a61026a16cec6dc66d + md5: 1ebaa45e5556156b3c7bf5bd5c527634 + depends: + - ld_impl_linux-aarch64 2.46.1 default_h1979696_103 + - sysroot_linux-aarch64 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 4911258 + timestamp: 1791565579362 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.46.1-default_hf1166c9_102.conda sha256: d41099a3fe2809a3ab3e4c718ecff4d5f8879e7949f3c8e8efa97fa06a90248c md5: 9a340123cb7217eae51c5cae24484631 @@ -6843,6 +6923,16 @@ packages: run_exports: {} size: 36196 timestamp: 1784214578949 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.46.1-default_hf1166c9_103.conda + sha256: 60e63ac488aac474f8a22ea465d317daa02fccd039cca75e288bd0fc37e8745a + md5: 9074b4a634a2be79ee49cd85b54a7f34 + depends: + - binutils_impl_linux-aarch64 2.46.1 default_h5f4c503_103 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 36474 + timestamp: 1791565619784 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-h52fc18c_4.conda sha256: 73cccc8488da976cbdf32e3b5c6182aef6d77c9dfabd0e5f5fa2ca6e03d51921 md5: 207d4f45f94f6d755a7fe1455e3148d7 @@ -6887,7 +6977,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/brotli?source=compressed-mapping + - pkg:pypi/brotli?source=hash-mapping run_exports: {} size: 366485 timestamp: 1788480367792 @@ -6960,31 +7050,6 @@ packages: run_exports: {} size: 350096 timestamp: 1789746782725 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-bindings-13.2.0-py312hdc0efb6_1.conda - sha256: b8784c43ccd7c61c3944b48e7751e454e8c4b9ae50cabf42696e432b2e5b6b3b - md5: c7560ec15413c9b14e46d26c2ce94fb3 - depends: - - cuda-nvrtc >=13,<14.0a0 - - cuda-nvvm-impl >=13,<14.0a0 - - cuda-pathfinder >=1.1.0,<2 - - cuda-version >=13,<14.0a0 - - libcufile >=1,<2.0a0 - - libgcc >=14 - - libnvfatbin - - libnvjitlink >=13.0,<14.0a0 - - libstdcxx >=14 - - python >=3.12,<3.13.0a0 - - python >=3.12,<3.13.0a0 *_cpython - - python_abi 3.12.* *_cp312 - constrains: - - cuda-python >=13.2.0,<13.3.0a0 - - cuda-cudart >=13,<14.0a0 - license: LicenseRef-NVIDIA-SOFTWARE-LICENSE - purls: - - pkg:pypi/cuda-bindings?source=hash-mapping - run_exports: {} - size: 3866781 - timestamp: 1779249873318 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-12.9.79-h3ae8b8a_0.conda sha256: 3d6699fc27ffabf28a9d359b48e7b88437e4d945844718a58608627998db5d1b md5: df78e19e5fe656631d1470aa0fcf6ced @@ -8093,6 +8158,18 @@ packages: run_exports: {} size: 79463 timestamp: 1790346233159 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.9.0-h4154aff_0.conda + sha256: d3327ab1086334309cab3cf533c95f70c44dcbb8f66a99a92b23fb0f3f20f1da + md5: cb3ce9ae94bc74f792c119312e03bcf7 + depends: + - libgcc >=15 + constrains: + - expat 2.9.0.* + license: MIT + license_family: MIT + run_exports: {} + size: 80340 + timestamp: 1793054214232 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.7.0-hdaad0be_1.conda sha256: b1879d78b622c5f4817fd6d77fe7ae3ab7b501542e3c2f4ac77198c54c62c189 md5: f9e5b3e446b526b34a7e25ecec08efd9 @@ -9042,6 +9119,16 @@ packages: run_exports: {} size: 592152 timestamp: 1790777808830 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsystemd0-262.1-hd1ea486_0.conda + sha256: aea93da32087cc4e1f46bd0596f487ad92e1dbab282dec0d739a7f406cb42df6 + md5: 5f1e0ce7fe60051e614f505b00055cb9 + depends: + - libcap >=2.78,<2.79.0a0 + - libgcc >=15 + license: LGPL-2.1-or-later + run_exports: {} + size: 593299 + timestamp: 1792224110959 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.2-h45f9f85_1.conda sha256: fa6daf2301dee912def3e74344fae792a8fc2bbbf7880dedee0e93ee8fb98fc5 md5: c6f35f8f9695623b9055341bc280a642 @@ -9073,6 +9160,16 @@ packages: run_exports: {} size: 195674 timestamp: 1790777812289 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libudev1-262.1-hd1ea486_0.conda + sha256: ed708af321e72984beb4cbf2c9127b6d0a0b2e484d4cca670f0ae02ceee76a83 + md5: 7d5081ffee4a31823c3af8dc2cb1cf24 + depends: + - libcap >=2.78,<2.79.0a0 + - libgcc >=15 + license: LGPL-2.1-or-later + run_exports: {} + size: 196616 + timestamp: 1792224114009 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libunwind-1.8.3-h6470e1d_0.conda sha256: 86c013d522975b76e16a74341bfcb22f6ec2e9b8b87ec3e15380f46c435eaa7b md5: 5d8191a950e492a06dc29b491dd5f7c5 @@ -9127,6 +9224,18 @@ packages: - libuuid >=2.42.4,<3.0a0 size: 36296 timestamp: 1790121454455 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.4-hd6fdeab_1.conda + sha256: 66d4d6201d52b4e3679dcfcc73658902a1cfb1a096f9d72a7b2d93d78e13948a + md5: 394dc5a24e06bdea0b41389d1eee9a23 + depends: + - libgcc >=15 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libuuid >=2.42.4,<3.0a0 + size: 37956 + timestamp: 1793891605926 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvorbis-1.3.7-h7ac5ae9_2.conda sha256: 066708ca7179a1c6e5639d015de7ed6e432b93ad50525843db67d57eb1ba1faf md5: 9d099329070afe52d797462ca7bf35f3 @@ -9942,7 +10051,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/rpds-py?source=compressed-mapping + - pkg:pypi/rpds-py?source=hash-mapping run_exports: {} size: 296806 timestamp: 1791202315258 @@ -10177,6 +10286,19 @@ packages: run_exports: {} size: 14411564 timestamp: 1792672542028 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/uv-0.13.7-h779c035_0.conda + sha256: 998533e9479fb1478d674a95ad9fc9e3170d9fcc4b150e3b28003b097a408b2a + md5: cefd4c0fba2e7a6e4fb01082ebbec392 + depends: + - libstdcxx >=15 + - libgcc >=15 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - __glibc >=2.17 + license: Apache-2.0 OR MIT + run_exports: {} + size: 14511868 + timestamp: 1793689082823 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.26.0-h637a836_2.conda sha256: 0692327145e39b3484382c2b069003b08398e961575bb6d35d3246f1cafa5d58 md5: cee65dc8a90933553988b50f5a03079a @@ -10809,6 +10931,24 @@ packages: run_exports: {} size: 131396 timestamp: 1792483552251 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-h4c7d964_0.conda + sha256: f1d280d2618de987204102090e83733089c092dc2dd45686fd3dcbe809034f6a + md5: ea9dc39dcd2815202749c1e5bc2a8973 + depends: + - __win + license: ISC + run_exports: {} + size: 130423 + timestamp: 1792772460189 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-hbd8a1cb_0.conda + sha256: 95619b9c1184be7175392eeb0ee7eeb5ccf25d280951f4225f2d62e725790be3 + md5: 3fd02989038a1e1cee627c14c2d73f29 + depends: + - __unix + license: ISC + run_exports: {} + size: 130057 + timestamp: 1792772446739 - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.4-pyha770c72_0.conda sha256: cca3a26282a5bc37a10afb1aa2006a21c45033cbc4ff012f9501f56f2a115c12 md5: 13bdbb9b693b29134c56a9a00c23de41 @@ -11300,20 +11440,6 @@ packages: run_exports: {} size: 37579 timestamp: 1793849341859 -- conda: https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.8.3-pyhc364b38_0.conda - sha256: 25b8f625cebe056be045bf9e484549188296b79793a340e059f13de4338939be - md5: cb2babe521da8b1acaaea1cc12a282af - depends: - - python >=3.10 - - cuda-version >=12.0,<14 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/cuda-pathfinder?source=compressed-mapping - run_exports: {} - size: 53393 - timestamp: 1790912935126 - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda sha256: 5f5f428031933f117ff9f7fcc650e6ea1b3fef5936cf84aa24af79167513b656 md5: b6d5d7f1c171cbd228ea06b556cfa859 @@ -11440,7 +11566,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/filelock?source=compressed-mapping + - pkg:pypi/filelock?source=hash-mapping run_exports: {} size: 85969 timestamp: 1791210321663 @@ -11791,7 +11917,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema?source=hash-mapping + - pkg:pypi/jsonschema?source=compressed-mapping run_exports: {} size: 82084 timestamp: 1787579299493 @@ -12183,7 +12309,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/nbclient?source=hash-mapping + - pkg:pypi/nbclient?source=compressed-mapping run_exports: {} size: 29971 timestamp: 1788212974885 @@ -12292,7 +12418,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/platformdirs?source=compressed-mapping + - pkg:pypi/platformdirs?source=hash-mapping run_exports: {} size: 33902 timestamp: 1791424402874 @@ -13118,6 +13244,13 @@ packages: run_exports: {} size: 118849 timestamp: 1784250406640 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + sha256: 2b7ca858879f183ce2dcc65b300f48a0133d5430550f35b23d80d405a0788dbf + md5: abccc3810d2b97e570dee487f2b46e38 + license: LicenseRef-Public-Domain + run_exports: {} + size: 119208 + timestamp: 1792758382821 - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.8.0-pyhd8ed1ab_0.conda sha256: c5511c190ab55168ca412f3c54592fbf677ae6250784cb72b227a7cf3f538f7d md5: 407a3d3778570bae8e8fcf554e803e43 @@ -13416,30 +13549,6 @@ packages: run_exports: {} size: 252875 timestamp: 1789746805191 -- conda: https://conda.anaconda.org/conda-forge/win-64/cuda-bindings-13.2.0-py312hc128f0a_1.conda - sha256: 31113f2c14b5e549aa59863f711890e9bf442defd7af3bd6ff192ec96e5dcdf1 - md5: a17fac259dd34ef9ee1f508933614967 - depends: - - cuda-nvrtc >=13,<14.0a0 - - cuda-nvvm-impl >=13,<14.0a0 - - cuda-pathfinder >=1.1.0,<2 - - cuda-version >=13,<14.0a0 - - libnvfatbin - - libnvjitlink >=13.0,<14.0a0 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - cuda-python >=13.2.0,<13.3.0a0 - - cuda-cudart >=13,<14.0a0 - license: LicenseRef-NVIDIA-SOFTWARE-LICENSE - purls: - - pkg:pypi/cuda-bindings?source=hash-mapping - run_exports: {} - size: 3509245 - timestamp: 1779249639234 - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-cudart-12.9.79-he0c23c2_0.conda sha256: a30cd9adf3a70d069d4d87c5728ec16778b77071629612ca5d8513cd92d89c09 md5: 0a243d4f000a0d2f51dd94ee9132b234 @@ -14221,6 +14330,20 @@ packages: run_exports: {} size: 72107 timestamp: 1790346254561 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.9.0-hac47afa_0.conda + sha256: d4a8e5aac8999a90cd71aa6f9f5c40d8594ed2b89cd7f898f997767ecc6cd52d + md5: 74ac404611024dc488ae71cfb7a5bf8f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.9.0.* + license: MIT + license_family: MIT + run_exports: {} + size: 72983 + timestamp: 1793054271728 - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda sha256: 613e8077c5cca5df7fe84ade7d5050301bee3c6c4c450ffe61d34a349ab4f11c md5: ceb38b0ba900847d8da4289c3c8e5708 @@ -14930,7 +15053,7 @@ packages: - jinja2 >=3.0.0 license: BSD-3-Clause purls: - - pkg:pypi/markupsafe?source=compressed-mapping + - pkg:pypi/markupsafe?source=hash-mapping run_exports: {} size: 28515 timestamp: 1791548981413 @@ -15044,7 +15167,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/numpy?source=compressed-mapping + - pkg:pypi/numpy?source=hash-mapping run_exports: weak: - numpy >=1.25,<3 @@ -15638,6 +15761,18 @@ packages: run_exports: {} size: 13387537 timestamp: 1792672517235 +- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.13.7-hf7a7c96_0.conda + sha256: b662d664862bf73941b02ce76868398956cf893475dc3e31ff49de198b14b4a8 + md5: bab575f975c8a087dbbc56d8188265d7 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 OR MIT + run_exports: {} + size: 13299866 + timestamp: 1793689103658 - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda sha256: 35444c55a92e2f7f7ba26bc70f81e56e52344f7d064c0fd4b40a46a58517b79c md5: aa805b5522c2a98fa286e551a1f48546 @@ -15651,6 +15786,18 @@ packages: run_exports: {} size: 21383 timestamp: 1785359368566 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_42.conda + sha256: 0598ca1ce913618cff9bd90391bcf75cd9edb22057c85dd6784dd762b7a888e2 + md5: 14166cbeafd1f1d255bd21abcc742a65 + depends: + - vc14_runtime >=14.51.36247 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 21309 + timestamp: 1793305687162 - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda sha256: 4e4cb599cdc41bf2109d1464c127b5bcbddf548ce3e322e612afb691338b48f8 md5: ac5333bb3d429361f23adf704cc49a78 @@ -15665,6 +15812,19 @@ packages: run_exports: {} size: 767955 timestamp: 1785359364369 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_42.conda + sha256: 8dfbfd68ebf53249d11e528cbb80ad5a2460b0c5b4636eed82ee0d3950827a3d + md5: bc3b057d4b2458cf95326daa33acf9da + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.51.36247 habf1de7_42 + constrains: + - vs2015_runtime 14.51.36247.* *_42 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + run_exports: {} + size: 767099 + timestamp: 1793305684782 - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda sha256: 731e043390c9457299484d39e427221fc868a9249540a498a5a4f6456c7744d1 md5: 350bb67a5c8e5f1c53347ac544ab6600 @@ -15680,6 +15840,20 @@ packages: - vcomp14 >=14.51.36247 size: 155910 timestamp: 1785359349999 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_42.conda + sha256: b3558ed059d6272ef919ea959311af73c35b5fe43c789cd43f71b398671fec49 + md5: 948483905faab0e83c9aed0414004194 + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.51.36247.* *_42 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + run_exports: + strong: + - vcomp14 >=14.51.36247 + size: 155686 + timestamp: 1793305669217 - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_41.conda sha256: 9d7d1b43cf4af5a8e8b1646175c9f899ffbcab189a33ac41127a96e7bcf41af0 md5: 04190e0ebd886433300ce9343ee98942 @@ -15698,6 +15872,24 @@ packages: - ucrt >=10.0.20348.0 size: 25462 timestamp: 1785358620723 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_42.conda + sha256: 872123d66fbc41898bea34973cbf64544c41cdcd5123a00abe747c5f35b92898 + md5: 410be03ef3a0eb26e1b20cb90be5493c + depends: + - vswhere + constrains: + - vs_win-64 2022.14 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + size: 25374 + timestamp: 1793120002126 - conda: https://conda.anaconda.org/conda-forge/win-64/wcwidth-0.9.2-py311hdbcae8a_0.conda noarch: python sha256: ad6a9373bed593daf3f8645044a2ac793726b4482ce78dbdb46a81cb9dfb4448 @@ -15714,7 +15906,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/wcwidth?source=compressed-mapping + - pkg:pypi/wcwidth?source=hash-mapping run_exports: {} size: 348834 timestamp: 1791194558195 @@ -16289,68 +16481,351 @@ packages: - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda - conda_source: cuda-pathfinder[f6abc7c0] @ ../cuda_pathfinder -- conda_source: cuda-bindings[e3183a23] @ . +- conda_source: cuda-bindings[c345f5cd] @ . variants: - c_stdlib: sysroot - c_stdlib_version: '2.28' - cuda_version: 12.* - python: 3.14.* - target_platform: linux-aarch64 + c_compiler: vs2022 + cuda_version: 13.5.* + cxx_compiler: vs2022 + python: 3.12.* + target_platform: win-64 depends: - - __glibc >=2.28,<3.0.a0 - cuda-nvrtc - - cuda-nvrtc >=12.9.86,<13.0a0 + - cuda-nvrtc >=13.5.37,<14.0a0 - cuda-nvvm - cuda-pathfinder - cuda-version - - libcufile - - libcufile >=1.14.1.1,<2.0a0 - - libgcc >=16 - - libgcc >=16 - libnvfatbin - libnvjitlink - - libstdcxx >=16 - python - python >=3.11 - - python_abi 3.14.* *_cp314 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 source_depends: cuda-pathfinder: path: ../cuda_pathfinder build_packages: - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.46.1-default_h5f4c503_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.46.1-default_hf1166c9_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-16.2.0-h5425ead_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-16.2.0-h25cc031_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-16.2.0-h1e3c31f_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-16.2.0-h423111d_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-16.2.0-h205dda4_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-16.2.0-h73cac2c_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-16.2.0-hc0c2482_107.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-16.2.0-h082e5f6_107.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_42.conda host_packages: - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_10.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-12.9.79-h3ae8b8a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-dev-12.9.79-h3ae8b8a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-static-12.9.79-h3ae8b8a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-12.9.86-h8f3c8d4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-dev-12.9.86-h8f3c8d4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-12.9.86-he9431aa_106.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-impl-12.9.86-h7b14b0b_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-tools-12.9.86-h7b14b0b_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-profiler-api-12.9.79-h16bee8c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.9-py314hc6b4731_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_102.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_win-64-13.3.5.0.6-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_win-64-13.5.37-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_win-64-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-static_win-64-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart_win-64-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_win-64-13.5.37-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-9_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-cudart-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-cudart-dev-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-cudart-static-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvrtc-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvrtc-dev-13.5.37-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-13.5.37-h719f0c7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-impl-13.5.37-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-nvvm-tools-13.5.37-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cuda-profiler-api-13.5.25-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cython-3.2.9-py312hd245ac3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.9.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpython-3.12.16-hfb4101e_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.54.1-hf5d6505_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.5-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.16-hb12b558_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.13.7-hf7a7c96_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda + - conda_source: cuda-pathfinder[6a6a6b0a] @ ../cuda_pathfinder +- conda_source: cuda-bindings[c92b487d] @ . + variants: + c_stdlib: sysroot + c_stdlib_version: '2.28' + cuda_version: 13.5.* + python: 3.12.* + target_platform: linux-64 + depends: + - __glibc >=2.28,<3.0.a0 + - cuda-nvrtc + - cuda-nvrtc >=13.5.37,<14.0a0 + - cuda-nvvm + - cuda-pathfinder + - cuda-version + - libcufile + - libcufile >=1.20.0.107,<2.0a0 + - libgcc >=16 + - libgcc >=16 + - libnvfatbin + - libnvjitlink + - libstdcxx >=16 + - python + - python >=3.11 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + source_depends: + cuda-pathfinder: + path: ../cuda_pathfinder + build_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.46.1-default_hfdba357_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.46.1-default_h4852527_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-16.2.0-h9891192_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-16.2.0-h0ab548f_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-16.2.0-h0d273dc_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-16.2.0-h23aca61_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.2.0-ha9f2e26_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.2.0-he0feb66_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-16.2.0-h3048135_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-16.2.0-he3ce08f_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-16.2.0-h86e191b_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + host_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-static-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvrtc-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvrtc-dev-13.5.37-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-13.5.37-h69a702a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-13.5.37-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-13.5.37-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-13.5.25-h7938cbb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.9-py312h68e6be4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.78-h084b8d7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.20.0.107-h63c01a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcufile-dev-1.20.0.107-h393e864_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.9.0-hd2095e1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.7.0-h81df57d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.2.0-ha9f2e26_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.2.0-he0feb66_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpython-3.12.16-ha57cdbe_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.54.1-h0737f62_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-262.1-h26e0ef7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libudev1-262.1-h26e0ef7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.4-hcfc3c73_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.38-h280c20c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.5-h781a0a9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.16-h5f976f7_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rdma-core-65.0-h7b4f2e6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-hd6e31c0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h1df4ec4_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.13.7-h535ca38_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-64-13.3.5.0.6-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_linux-64-13.5.37-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-13.5.37-h528332f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-static_linux-64-13.5.37-h528332f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart_linux-64-13.5.37-h528332f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-64-13.5.37-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-9_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda + - conda_source: cuda-pathfinder[10e1cc92] @ ../cuda_pathfinder +- conda_source: cuda-bindings[d088a16d] @ . + variants: + c_stdlib: sysroot + c_stdlib_version: '2.28' + cuda_version: 13.5.* + python: 3.12.* + target_platform: linux-aarch64 + depends: + - __glibc >=2.28,<3.0.a0 + - cuda-nvrtc + - cuda-nvrtc >=13.5.37,<14.0a0 + - cuda-nvvm + - cuda-pathfinder + - cuda-version + - libcufile + - libcufile >=1.20.0.107,<2.0a0 + - libgcc >=16 + - libgcc >=16 + - libnvfatbin + - libnvjitlink + - libstdcxx >=16 + - python + - python >=3.11 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + source_depends: + cuda-pathfinder: + path: ../cuda_pathfinder + build_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.46.1-default_h5f4c503_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.46.1-default_hf1166c9_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-16.2.0-h5425ead_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-16.2.0-h25cc031_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-16.2.0-h1e3c31f_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-16.2.0-h423111d_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-16.2.0-h205dda4_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-16.2.0-h73cac2c_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-16.2.0-hc0c2482_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-16.2.0-h082e5f6_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + host_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-dev-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-static-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-dev-13.5.37-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-13.5.37-he9431aa_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-impl-13.5.37-hbe86820_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-tools-13.5.37-hbe86820_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-profiler-api-13.5.25-h16bee8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.9-py312hbda70bc_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcap-2.78-hfcc8634_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcufile-1.20.0.107-hc7dfe37_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcufile-dev-1.20.0.107-hc1d3098_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.9.0-h4154aff_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.7.0-hdaad0be_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-16.2.0-h205dda4_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnl-3.11.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpython-3.12.16-h3cfa5a6_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.54.1-hd26f1b6_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsystemd0-262.1-hd1ea486_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libudev1-262.1-hd1ea486_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.4-hd6fdeab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.38-h80f16a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-h2b6f883_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.5-he6ad1d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.12.16-h94ad73b_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rdma-core-65.0-h807d763_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-ha7194a6_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_hf03c496_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/uv-0.13.7-h779c035_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arm-variant-1.2.0-sbsa.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-aarch64-13.3.5.0.6-h579c4fd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_linux-aarch64-13.5.37-h579c4fd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-aarch64-13.5.37-hf3a43d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-static_linux-aarch64-13.5.37-hf3a43d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-cudart_linux-aarch64-13.5.37-hf3a43d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-aarch64-13.5.37-h579c4fd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-13.5-h3499c3b_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-9_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda + - conda_source: cuda-pathfinder[f06c437b] @ ../cuda_pathfinder +- conda_source: cuda-bindings[e3183a23] @ . + variants: + c_stdlib: sysroot + c_stdlib_version: '2.28' + cuda_version: 12.* + python: 3.14.* + target_platform: linux-aarch64 + depends: + - __glibc >=2.28,<3.0.a0 + - cuda-nvrtc + - cuda-nvrtc >=12.9.86,<13.0a0 + - cuda-nvvm + - cuda-pathfinder + - cuda-version + - libcufile + - libcufile >=1.14.1.1,<2.0a0 + - libgcc >=16 + - libgcc >=16 + - libnvfatbin + - libnvjitlink + - libstdcxx >=16 + - python + - python >=3.11 + - python_abi 3.14.* *_cp314 + license: Apache-2.0 + source_depends: + cuda-pathfinder: + path: ../cuda_pathfinder + build_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.46.1-default_h5f4c503_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.46.1-default_hf1166c9_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-16.2.0-h5425ead_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-16.2.0-h25cc031_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-16.2.0-h1e3c31f_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-16.2.0-h423111d_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-16.2.0-h205dda4_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-16.2.0-h73cac2c_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-16.2.0-hc0c2482_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-16.2.0-h082e5f6_107.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda + host_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-12.9.79-h3ae8b8a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-dev-12.9.79-h3ae8b8a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-cudart-static-12.9.79-h3ae8b8a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-12.9.86-h8f3c8d4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvrtc-dev-12.9.86-h8f3c8d4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-12.9.86-he9431aa_106.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-impl-12.9.86-h7b14b0b_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-nvvm-tools-12.9.86-h7b14b0b_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cuda-profiler-api-12.9.79-h16bee8c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.9-py314hc6b4731_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_102.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcap-2.78-hfcc8634_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcufile-1.14.1.1-had8bf56_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcufile-dev-1.14.1.1-he38c790_1.conda @@ -16394,6 +16869,43 @@ packages: - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda - conda_source: cuda-pathfinder[a51836e4] @ ../cuda_pathfinder +- conda_source: cuda-pathfinder[10e1cc92] @ ../cuda_pathfinder + variants: + target_platform: noarch + depends: + - python * + - python >=3.11 + license: Apache-2.0 + host_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20260512-pl5321h373387f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.9.0-hd2095e1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.7.0-h81df57d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.2.0-ha9f2e26_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.2.0-he0feb66_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.54.1-h0737f62_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.4-hcfc3c73_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.5-h781a0a9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.15.2-h6e52b48_100_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h1df4ec4_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.13.7-h535ca38_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.15-9_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda - conda_source: cuda-pathfinder[3da77f45] @ ../cuda_pathfinder variants: target_platform: noarch @@ -16431,6 +16943,39 @@ packages: - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda +- conda_source: cuda-pathfinder[6a6a6b0a] @ ../cuda_pathfinder + variants: + target_platform: noarch + depends: + - python * + - python >=3.11 + license: Apache-2.0 + host_packages: + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.15-9_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.9.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.54.1-hf5d6505_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.5-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.15.2-h53f6dd8_100_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.13.7-hf7a7c96_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_42.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda - conda_source: cuda-pathfinder[8f545c34] @ ../cuda_pathfinder variants: target_platform: noarch @@ -16575,6 +17120,43 @@ packages: - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda +- conda_source: cuda-pathfinder[f06c437b] @ ../cuda_pathfinder + variants: + target_platform: noarch + depends: + - python * + - python >=3.11 + license: Apache-2.0 + host_packages: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.46.1-default_h1979696_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20260512-pl5321hc48eb74_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.9.0-h4154aff_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.7.0-hdaad0be_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-16.2.0-h205dda4_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.54.1-hd26f1b6_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.4-hd6fdeab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-h2b6f883_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.5-he6ad1d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.15.2-h0c7c799_100_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_hf03c496_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/uv-0.13.7-h779c035_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.10.23-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.15-9_cp315.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-84.2.1-pyhe730653_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-10.3.4-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.5.0-pyh5ded981_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026e-h5d301ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vcs_versioning-2.6.0-pyh5ded981_0.conda - conda_source: cuda-pathfinder[f6abc7c0] @ ../cuda_pathfinder variants: target_platform: noarch diff --git a/cuda_bindings_13/pixi.toml b/cuda_bindings_13/pixi.toml index 854ca2fadac..a3d33e67819 100644 --- a/cuda_bindings_13/pixi.toml +++ b/cuda_bindings_13/pixi.toml @@ -28,7 +28,8 @@ cuda-python-test-helpers = { path = "../cuda_python_test_helpers", editable = tr # Keep this dependency set aligned with cuda_python/docs/environment-docs.yml. [feature.docs.dependencies] -cuda-bindings = "13.2.*" +# Document the checkout's API, including modules absent from published packages. +cuda-bindings = { path = "." } python = "3.12.*" cython = ">=3.2.5,<3.3" enum_tools = "*" diff --git a/cuda_core/docs/source/install.rst b/cuda_core/docs/source/install.rst index e2d74063140..299c9ebb7be 100644 --- a/cuda_core/docs/source/install.rst +++ b/cuda_core/docs/source/install.rst @@ -101,10 +101,10 @@ obtain the most recent build, use the following commands: $ # Install the downloaded wheel: $ pip install cuda-core-python312-linux-64-*/cuda_core*.whl[cu13] -Replace ``python312`` with your Python version (e.g. ``python310``, ``python311``, -``python313``, ``python314``, ``python314t``). For aarch64, replace ``linux-64`` -with ``linux-aarch64``; for Windows, use ``win-64``. Replace ``cu13`` with -``cu12`` for CUDA 12.x environments. +Replace ``python312`` with your Python version (e.g. ``python311``, +``python313``, ``python314``, ``python314t``, ``python315``, ``python315t``). +For aarch64, replace ``linux-64`` with ``linux-aarch64``; for Windows, use +``win-64``. Replace ``cu13`` with ``cu12`` for CUDA 12.x environments. .. _cuda-core-source-install: diff --git a/cuda_python/docs/README.md b/cuda_python/docs/README.md index 4cf18ee74d0..76b46c7d061 100644 --- a/cuda_python/docs/README.md +++ b/cuda_python/docs/README.md @@ -4,7 +4,11 @@ 2. Build the docs with `./build_docs.sh`. 3. The html artifacts should be available under both `./build/html/latest` and `./build/html/`. -Alternatively, we can build all the docs at once by running [`./build_all_docs.sh`](./build_all_docs.sh). +[`./build_all_docs.sh`](./build_all_docs.sh) builds the metapackage, current +CUDA 13 bindings, Core, and Pathfinder documentation together. It does not +build the [CUDA 12 maintenance documentation](../../cuda_bindings_12/docs/README.md). +Build that separately in its own environment: both bindings roots install the +same `cuda-bindings` distribution and `cuda.bindings` namespace. When building the docs, some (but not all) of the urls can be rendered/examined locally by setting the environment variable `CUDA_PYTHON_DOMAIN` as follows: diff --git a/cuda_python/docs/environment-docs.yml b/cuda_python/docs/environment-docs.yml index 3152f0a3a93..a82fd02aa5e 100644 --- a/cuda_python/docs/environment-docs.yml +++ b/cuda_python/docs/environment-docs.yml @@ -19,6 +19,8 @@ dependencies: - sphinx-copybutton - myst-nb - enum_tools + # cuda_bindings_12/docs/source/conf.py uses the Furo theme. + - furo - sphinx-toolbox - pyclibrary - pip: diff --git a/toolshed/setup-docs-env.sh b/toolshed/setup-docs-env.sh index 9acbaa8e391..73afbbf06f9 100755 --- a/toolshed/setup-docs-env.sh +++ b/toolshed/setup-docs-env.sh @@ -51,6 +51,7 @@ conda create -y -n "${ENV_NAME}" \ sphinx-copybutton \ myst-nb \ enum_tools \ + furo \ sphinx-toolbox \ pyclibrary