Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
497 changes: 345 additions & 152 deletions .github/workflows/build-wheel.yml

Large diffs are not rendered by default.

258 changes: 141 additions & 117 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

73 changes: 47 additions & 26 deletions .github/workflows/test-sdist-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ on:
host-platform:
required: true
type: string
cuda-version:
bindings-package:
description: Normalized CUDA bindings package JSON.
required: true
type: string
workplan:
description: JSON workplan. An empty value builds everything.
required: false
default: ""
description: JSON workplan.
required: true
type: string

defaults:
Expand All @@ -27,13 +27,17 @@ permissions:

jobs:
test-sdist:
name: Test sdist builds
if: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).jobs.sdist_tests }}
name: Sdist ${{ fromJSON(inputs.workplan).labels.sdist[fromJSON(inputs.bindings-package).package_root] }}
if: ${{ fromJSON(inputs.workplan).jobs.sdist_package_roots[fromJSON(inputs.bindings-package).package_root] }}
env:
BUILD_PATHFINDER: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.pathfinder.needs_build }}
BUILD_BINDINGS: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.bindings.needs_build }}
BUILD_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.needs_build }}
BUILD_PYTHON: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.python.needs_build }}
BINDINGS_ROOT: ${{ fromJSON(inputs.bindings-package).package_root }}
CUDA_BUILD_VERSION: ${{ fromJSON(inputs.bindings-package).toolkit_version }}
CUDA_PYTHON_BUILD_MAJOR: ${{ fromJSON(inputs.bindings-package).cuda_major }}
BUILD_PATHFINDER: ${{ fromJSON(inputs.workplan).modules.pathfinder.needs_build }}
BUILD_BINDINGS: ${{ fromJSON(inputs.workplan).modules.bindings.package_roots[fromJSON(inputs.bindings-package).package_root].needs_build }}
BUILD_CORE: ${{ fromJSON(inputs.workplan).modules.core.cuda_majors[fromJSON(inputs.bindings-package).cuda_variant].needs_build }}
BUILD_CUDA_PYTHON: ${{ fromJSON(inputs.workplan).modules.python.package_roots[fromJSON(inputs.bindings-package).package_root].needs_build }}
PATHFINDER_SOURCE: ${{ fromJSON(inputs.workplan).sources.pathfinder }}
timeout-minutes: 60
runs-on: linux-amd64-cpu8
steps:
Expand All @@ -54,8 +58,14 @@ jobs:
- name: Harden pip
uses: ./.github/actions/harden-pip

- name: Install build tools
run: python -m pip install build
- name: Install build and CI tools
run: python -m pip install build -e ./ci

- name: Prepare local maintenance SCM milestone
if: ${{ fromJSON(inputs.bindings-package).release_status == 'maintenance' }}
run: |
python -m ci.tools.bindings_scm_version \
--package-root "${BINDINGS_ROOT}" --sha "${{ github.sha }}"

# Pure Python packages -- no CTK needed.
- name: Build cuda.pathfinder sdist and wheel-from-sdist
Expand All @@ -65,13 +75,14 @@ jobs:
pip wheel --no-deps --wheel-dir cuda_pathfinder/dist cuda_pathfinder/dist/*.tar.gz

- name: Build cuda-python sdist and wheel-from-sdist
if: ${{ env.BUILD_PYTHON == 'true' }}
if: ${{ env.BUILD_CUDA_PYTHON == 'true' }}
run: |
python -m build --sdist cuda_python/
pip wheel --no-deps --wheel-dir cuda_python/dist cuda_python/dist/*.tar.gz

- name: Download cuda.pathfinder wheel
if: ${{ env.BUILD_PATHFINDER != 'true' && (env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true') }}
if: ${{ env.BUILD_PATHFINDER != 'true' && (env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true') &&
env.PATHFINDER_SOURCE == 'artifact' }}
uses: ./.github/actions/download-artifact-retry
with:
name: cuda-pathfinder-wheel
Expand All @@ -81,11 +92,21 @@ jobs:
if: ${{ env.BUILD_BINDINGS == 'true' }}
run: |
pathfinder_wheels=(cuda_pathfinder/dist/cuda_pathfinder-*.whl)
test "${#pathfinder_wheels[@]}" -eq 1
test -f "${pathfinder_wheels[0]}"
mkdir -p wheel-constraints
pathfinder_uri="file://$(realpath "${pathfinder_wheels[0]}")"
printf 'cuda-pathfinder @ %s\n' "${pathfinder_uri}" | tee wheel-constraints/cuda-bindings.txt
if [[ "${PATHFINDER_SOURCE}" == "artifact" ]]; then
if [[ "${#pathfinder_wheels[@]}" -ne 1 || ! -f "${pathfinder_wheels[0]}" ]]; then
echo "Expected exactly one cuda-pathfinder wheel in cuda_pathfinder/dist" >&2
exit 1
fi
pathfinder_uri="file://$(realpath "${pathfinder_wheels[0]}")"
printf 'cuda-pathfinder @ %s\n' "${pathfinder_uri}" > wheel-constraints/cuda-bindings.txt
elif [[ "${PATHFINDER_SOURCE}" == "published" ]]; then
: > wheel-constraints/cuda-bindings.txt
else
echo "Error: PATHFINDER_SOURCE must be artifact or published, got ${PATHFINDER_SOURCE}" >&2
exit 1
fi
cat wheel-constraints/cuda-bindings.txt

# Cython packages need CTK + sccache.
# The env vars ACTIONS_CACHE_SERVICE_V2, ACTIONS_RESULTS_URL, and ACTIONS_RUNTIME_TOKEN
Expand All @@ -110,7 +131,7 @@ jobs:
continue-on-error: false
with:
host-platform: ${{ inputs.host-platform }}
cuda-version: ${{ inputs.cuda-version }}
cuda-version: ${{ fromJSON(inputs.bindings-package).toolkit_version }}

# cuda_bindings_13/setup.py parses CUDA headers at import time, so CUDA_PATH
# (set by fetch_ctk) must be available for both sdist and wheel builds.
Expand All @@ -122,22 +143,22 @@ jobs:
export CXX="sccache c++"
export PIP_BUILD_CONSTRAINT="$(pwd)/wheel-constraints/cuda-bindings.txt"
export PIP_CONSTRAINT="${PIP_BUILD_CONSTRAINT}"
python -m build --sdist cuda_bindings_13/
pip wheel --no-deps --wheel-dir cuda_bindings_13/dist cuda_bindings_13/dist/*.tar.gz
python -m build --sdist "${BINDINGS_ROOT}/"
pip wheel --no-deps --wheel-dir "${BINDINGS_ROOT}/dist" "${BINDINGS_ROOT}"/dist/*.tar.gz

- name: Download cuda.bindings wheel
if: ${{ env.BUILD_BINDINGS != 'true' && env.BUILD_CORE == 'true' }}
uses: ./.github/actions/download-artifact-retry
with:
name: cuda-bindings-python312-cuda${{ inputs.cuda-version }}-${{ inputs.host-platform }}-${{ github.sha }}
path: cuda_bindings_13/dist
name: cuda-bindings-python312-cuda${{ fromJSON(inputs.bindings-package).toolkit_version }}-${{ inputs.host-platform }}-${{ github.sha }}
path: ${{ env.BINDINGS_ROOT }}/dist

- name: Constrain cuda.core to the local cuda.bindings wheel
if: ${{ env.BUILD_CORE == 'true' }}
run: |
CUDA_MAJOR="$(echo '${{ inputs.cuda-version }}' | cut -d. -f1)"
CUDA_MAJOR='${{ fromJSON(inputs.bindings-package).cuda_major }}'
pathfinder_wheels=(cuda_pathfinder/dist/cuda_pathfinder-*.whl)
bindings_wheels=(cuda_bindings_13/dist/cuda_bindings-"${CUDA_MAJOR}".*.whl)
bindings_wheels=("${BINDINGS_ROOT}"/dist/cuda_bindings-"${CUDA_MAJOR}".*.whl)
test "${#pathfinder_wheels[@]}" -eq 1
test "${#bindings_wheels[@]}" -eq 1
test -f "${pathfinder_wheels[0]}"
Expand All @@ -157,7 +178,7 @@ jobs:
if: ${{ env.BUILD_CORE == 'true' }}
run: |
export CUDA_PYTHON_PARALLEL_LEVEL=$(nproc)
export CUDA_CORE_BUILD_MAJOR="$(echo '${{ inputs.cuda-version }}' | cut -d. -f1)"
export CUDA_CORE_BUILD_MAJOR='${{ fromJSON(inputs.bindings-package).cuda_major }}'
export CC="sccache cc"
export CXX="sccache c++"
export PIP_BUILD_CONSTRAINT="$(pwd)/wheel-constraints/cuda-core.txt"
Expand Down
74 changes: 48 additions & 26 deletions .github/workflows/test-sdist-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ on:
host-platform:
required: true
type: string
cuda-version:
bindings-package:
description: Normalized CUDA bindings package JSON.
required: true
type: string
workplan:
description: JSON workplan. An empty value builds everything.
required: false
default: ""
description: JSON workplan.
required: true
type: string

defaults:
Expand All @@ -33,13 +33,17 @@ permissions:

jobs:
test-sdist:
name: Test sdist builds
if: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).jobs.sdist_tests }}
name: Sdist ${{ fromJSON(inputs.workplan).labels.sdist[fromJSON(inputs.bindings-package).package_root] }}
if: ${{ fromJSON(inputs.workplan).jobs.sdist_package_roots[fromJSON(inputs.bindings-package).package_root] }}
env:
BUILD_PATHFINDER: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.pathfinder.needs_build }}
BUILD_BINDINGS: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.bindings.needs_build }}
BUILD_CORE: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.core.needs_build }}
BUILD_PYTHON: ${{ inputs.workplan == '' || fromJSON(inputs.workplan).modules.python.needs_build }}
BINDINGS_ROOT: ${{ fromJSON(inputs.bindings-package).package_root }}
CUDA_BUILD_VERSION: ${{ fromJSON(inputs.bindings-package).toolkit_version }}
CUDA_PYTHON_BUILD_MAJOR: ${{ fromJSON(inputs.bindings-package).cuda_major }}
BUILD_PATHFINDER: ${{ fromJSON(inputs.workplan).modules.pathfinder.needs_build }}
BUILD_BINDINGS: ${{ fromJSON(inputs.workplan).modules.bindings.package_roots[fromJSON(inputs.bindings-package).package_root].needs_build }}
BUILD_CORE: ${{ fromJSON(inputs.workplan).modules.core.cuda_majors[fromJSON(inputs.bindings-package).cuda_variant].needs_build }}
BUILD_CUDA_PYTHON: ${{ fromJSON(inputs.workplan).modules.python.package_roots[fromJSON(inputs.bindings-package).package_root].needs_build }}
PATHFINDER_SOURCE: ${{ fromJSON(inputs.workplan).sources.pathfinder }}
timeout-minutes: 60
runs-on: windows-2022
steps:
Expand Down Expand Up @@ -67,8 +71,15 @@ jobs:
if: ${{ env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true' }}
uses: step-security/msvc-dev-cmd@22c98154b708dbd743e6f27a933cf6ceba3305c4 # v1.13.1

- name: Install build tools
run: python -m pip install build
- name: Install build and CI tools
run: python -m pip install build -e ./ci

- name: Prepare local maintenance SCM milestone
if: ${{ fromJSON(inputs.bindings-package).release_status == 'maintenance' }}
shell: bash --noprofile --norc -xeuo pipefail {0}
run: |
python -m ci.tools.bindings_scm_version \
--package-root "${BINDINGS_ROOT}" --sha "${{ github.sha }}"

# Pure Python packages -- no CTK needed.
- name: Build cuda.pathfinder sdist and wheel-from-sdist
Expand All @@ -78,13 +89,14 @@ jobs:
pip wheel --no-deps --wheel-dir cuda_pathfinder/dist cuda_pathfinder/dist/*.tar.gz

- name: Build cuda-python sdist and wheel-from-sdist
if: ${{ env.BUILD_PYTHON == 'true' }}
if: ${{ env.BUILD_CUDA_PYTHON == 'true' }}
run: |
python -m build --sdist cuda_python/
pip wheel --no-deps --wheel-dir cuda_python/dist cuda_python/dist/*.tar.gz

- name: Download cuda.pathfinder wheel
if: ${{ env.BUILD_PATHFINDER != 'true' && (env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true') }}
if: ${{ env.BUILD_PATHFINDER != 'true' && (env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true') &&
env.PATHFINDER_SOURCE == 'artifact' }}
uses: ./.github/actions/download-artifact-retry
with:
name: cuda-pathfinder-wheel
Expand All @@ -94,11 +106,21 @@ jobs:
if: ${{ env.BUILD_BINDINGS == 'true' }}
run: |
pathfinder_wheels=(cuda_pathfinder/dist/cuda_pathfinder-*.whl)
test "${#pathfinder_wheels[@]}" -eq 1
test -f "${pathfinder_wheels[0]}"
mkdir -p wheel-constraints
pathfinder_uri="file:///$(cygpath -am "${pathfinder_wheels[0]}")"
printf 'cuda-pathfinder @ %s\n' "${pathfinder_uri}" | tee wheel-constraints/cuda-bindings.txt
if [[ "${PATHFINDER_SOURCE}" == "artifact" ]]; then
if [[ "${#pathfinder_wheels[@]}" -ne 1 || ! -f "${pathfinder_wheels[0]}" ]]; then
echo "Expected exactly one cuda-pathfinder wheel in cuda_pathfinder/dist" >&2
exit 1
fi
pathfinder_uri="file:///$(cygpath -am "${pathfinder_wheels[0]}")"
printf 'cuda-pathfinder @ %s\n' "${pathfinder_uri}" > wheel-constraints/cuda-bindings.txt
elif [[ "${PATHFINDER_SOURCE}" == "published" ]]; then
: > wheel-constraints/cuda-bindings.txt
else
echo "Error: PATHFINDER_SOURCE must be artifact or published, got ${PATHFINDER_SOURCE}" >&2
exit 1
fi
cat wheel-constraints/cuda-bindings.txt

# Cython packages need CTK. No sccache on Windows (this is a correctness
# smoke test, not a production build; see build-wheel.yml which also
Expand All @@ -109,7 +131,7 @@ jobs:
continue-on-error: false
with:
host-platform: ${{ inputs.host-platform }}
cuda-version: ${{ inputs.cuda-version }}
cuda-version: ${{ fromJSON(inputs.bindings-package).toolkit_version }}

# cuda_bindings_13/setup.py parses CUDA headers at import time, so CUDA_PATH
# (set by fetch_ctk) must be available for both sdist and wheel builds.
Expand All @@ -121,22 +143,22 @@ jobs:
export CUDA_PYTHON_PARALLEL_LEVEL=$(nproc)
export PIP_BUILD_CONSTRAINT="$(cygpath -w "$(pwd)/wheel-constraints/cuda-bindings.txt")"
export PIP_CONSTRAINT="${PIP_BUILD_CONSTRAINT}"
python -m build --sdist cuda_bindings_13/
pip wheel --no-deps --wheel-dir cuda_bindings_13/dist cuda_bindings_13/dist/*.tar.gz
python -m build --sdist "${BINDINGS_ROOT}/"
pip wheel --no-deps --wheel-dir "${BINDINGS_ROOT}/dist" "${BINDINGS_ROOT}"/dist/*.tar.gz

- name: Download cuda.bindings wheel
if: ${{ env.BUILD_BINDINGS != 'true' && env.BUILD_CORE == 'true' }}
uses: ./.github/actions/download-artifact-retry
with:
name: cuda-bindings-python312-cuda${{ inputs.cuda-version }}-${{ inputs.host-platform }}-${{ github.sha }}
path: cuda_bindings_13/dist
name: cuda-bindings-python312-cuda${{ fromJSON(inputs.bindings-package).toolkit_version }}-${{ inputs.host-platform }}-${{ github.sha }}
path: ${{ env.BINDINGS_ROOT }}/dist

- name: Constrain cuda.core to the local cuda.bindings wheel
if: ${{ env.BUILD_CORE == 'true' }}
run: |
CUDA_MAJOR="$(echo '${{ inputs.cuda-version }}' | cut -d. -f1)"
CUDA_MAJOR='${{ fromJSON(inputs.bindings-package).cuda_major }}'
pathfinder_wheels=(cuda_pathfinder/dist/cuda_pathfinder-*.whl)
bindings_wheels=(cuda_bindings_13/dist/cuda_bindings-"${CUDA_MAJOR}".*.whl)
bindings_wheels=("${BINDINGS_ROOT}"/dist/cuda_bindings-"${CUDA_MAJOR}".*.whl)
test "${#pathfinder_wheels[@]}" -eq 1
test "${#bindings_wheels[@]}" -eq 1
test -f "${pathfinder_wheels[0]}"
Expand All @@ -156,7 +178,7 @@ jobs:
if: ${{ env.BUILD_CORE == 'true' }}
run: |
export CUDA_PYTHON_PARALLEL_LEVEL=$(nproc)
export CUDA_CORE_BUILD_MAJOR="$(echo '${{ inputs.cuda-version }}' | cut -d. -f1)"
export CUDA_CORE_BUILD_MAJOR='${{ fromJSON(inputs.bindings-package).cuda_major }}'
export PIP_BUILD_CONSTRAINT="$(cygpath -w "$(pwd)/wheel-constraints/cuda-core.txt")"
export PIP_CONSTRAINT="${PIP_BUILD_CONSTRAINT}"
python -m build --sdist cuda_core/
Expand Down
9 changes: 9 additions & 0 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,16 @@ Copying maintenance sources does not make their later branch tags ancestors of
release. Follow the [Git-derived version lifecycle](../AGENTS.md#git-derived-version-lifecycle)
and keep temporary preview tags local to an independent disposable clone;
worktrees share tags with their repository.
CI uses `ci.tools.bindings_scm_version` in disposable build checkouts until an
appropriate maintenance milestone is reachable. It creates a local preview tag
at a validated ancestor only when required; existing suitable tags govern the
version through standard setuptools-scm. It never pushes or moves tags.
For a local maintenance preview, use an independent disposable clone (not a
linked worktree), install the CI tools, and run from its root:

```console
python -m ci.tools.bindings_scm_version --package-root cuda_bindings_12 --sha "$(git rev-parse HEAD)"
```

### SCM Milestones and Bootstrap Targets

Expand Down
Loading
Loading