Skip to content

Commit 279c943

Browse files
leofangcpcloud
andauthored
Cythonize cuda.core (#1041)
* set up build system for targeting different cuda-bindings major verions * defer cythonization until cuda-bindings is installed * cythonize stream module * nit: move dlpack.h to the include dir * purge cu11 * check in a working merger script * support loading from the versioned module if any exists * fix linter errors * set up double-build CI workflow * ensure CUDA_PATH is honored by the build backend * try to reuse cuda-bindings wheels for 3.13t/3.14/3.14t * disable building/testing 313t/314/314t for now * deprecate PY39 as per #846 * also turn on parallel cythonization * cythonize event * fix error handling * Revert "disable building/testing 313t/314/314t for now" This reverts commit 1180ab6. * fix artifact location * cythonize device * making the linter happy, again * fix uuid handling * update release notes to note about compatibility requirement * fix env vars being passed twice * fix uuid handling, again * Apply suggestions from code review Co-authored-by: Phillip Cloud <417981+cpcloud@users.noreply.github.com> * address review comments * switch to use FutureWarning --------- Co-authored-by: Phillip Cloud <417981+cpcloud@users.noreply.github.com>
1 parent 0ea67b5 commit 279c943

File tree

22 files changed

+746
-220
lines changed

22 files changed

+746
-220
lines changed

.github/actions/fetch_ctk/action.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ inputs:
1818
required: false
1919
type: string
2020
default: "cuda_nvcc,cuda_cudart,cuda_crt,libnvvm,cuda_nvrtc,cuda_profiler_api,cuda_cccl,libnvjitlink,libcufile"
21+
cuda-path:
22+
description: "where the CTK components will be installed to, relative to $PWD"
23+
required: false
24+
type: string
25+
default: "./cuda_toolkit"
2126

2227
runs:
2328
using: composite
@@ -159,18 +164,24 @@ runs:
159164
exit 1
160165
fi
161166
167+
- name: Move CTK to the specified location
168+
if: ${{ inputs.cuda-path != './cuda_toolkit' }}
169+
shell: bash --noprofile --norc -xeuo pipefail {0}
170+
run: |
171+
mv ./cuda_toolkit ${{ inputs.cuda-path }}
172+
162173
- name: Set output environment variables
163174
shell: bash --noprofile --norc -xeuo pipefail {0}
164175
run: |
165176
# mimics actual CTK installation
166177
if [[ "${{ inputs.host-platform }}" == linux* ]]; then
167-
CUDA_PATH=$(realpath "./cuda_toolkit")
168-
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-}:${CUDA_PATH}/lib" >> $GITHUB_ENV
178+
CUDA_PATH=$(realpath "${{ inputs.cuda-path }}")
179+
echo "LD_LIBRARY_PATH=${CUDA_PATH}/lib:${LD_LIBRARY_PATH:-}" >> $GITHUB_ENV
169180
elif [[ "${{ inputs.host-platform }}" == win* ]]; then
170181
function normpath() {
171182
echo "$(echo $(cygpath -w $1) | sed 's/\\/\\\\/g')"
172183
}
173-
CUDA_PATH=$(normpath $(realpath "./cuda_toolkit"))
184+
CUDA_PATH=$(normpath $(realpath "${{ inputs.cuda-path }}"))
174185
echo "$(normpath ${CUDA_PATH}/bin)" >> $GITHUB_PATH
175186
fi
176187
echo "CUDA_PATH=${CUDA_PATH}" >> $GITHUB_ENV

.github/workflows/build-wheel.yml

Lines changed: 158 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ on:
1111
cuda-version:
1212
required: true
1313
type: string
14+
prev-cuda-version:
15+
required: true
16+
type: string
1417

1518
defaults:
1619
run:
@@ -109,33 +112,6 @@ jobs:
109112
path: cuda_pathfinder/*.whl
110113
if-no-files-found: error
111114

112-
- name: Build cuda.core wheel
113-
uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0
114-
with:
115-
package-dir: ./cuda_core/
116-
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
117-
118-
- name: List the cuda.core artifacts directory
119-
run: |
120-
if [[ "${{ inputs.host-platform }}" == win* ]]; then
121-
export CHOWN=chown
122-
else
123-
export CHOWN="sudo chown"
124-
fi
125-
$CHOWN -R $(whoami) ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
126-
ls -lahR ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
127-
128-
- name: Check cuda.core wheel
129-
run: |
130-
twine check --strict ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl
131-
132-
- name: Upload cuda.core build artifacts
133-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
134-
with:
135-
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}
136-
path: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl
137-
if-no-files-found: error
138-
139115
- name: Set up mini CTK
140116
uses: ./.github/actions/fetch_ctk
141117
continue-on-error: false
@@ -148,6 +124,15 @@ jobs:
148124
with:
149125
package-dir: ./cuda_bindings/
150126
output-dir: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}
127+
env:
128+
CIBW_BUILD: ${{ env.CIBW_BUILD }}
129+
# CIBW mounts the host filesystem under /host
130+
CIBW_ENVIRONMENT_LINUX: >
131+
CUDA_PATH=/host/${{ env.CUDA_PATH }}
132+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
133+
CIBW_ENVIRONMENT_WINDOWS: >
134+
CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})"
135+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
151136
152137
- name: List the cuda.bindings artifacts directory
153138
run: |
@@ -170,6 +155,47 @@ jobs:
170155
path: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}/*.whl
171156
if-no-files-found: error
172157

158+
- name: Build cuda.core wheel
159+
uses: pypa/cibuildwheel@c923d83ad9c1bc00211c5041d0c3f73294ff88f6 # v3.1.4
160+
with:
161+
package-dir: ./cuda_core/
162+
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
163+
env:
164+
CIBW_BUILD: ${{ env.CIBW_BUILD }}
165+
# CIBW mounts the host filesystem under /host
166+
CIBW_ENVIRONMENT_LINUX: >
167+
CUDA_PATH=/host/${{ env.CUDA_PATH }}
168+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
169+
CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }}
170+
PIP_FIND_LINKS=/host/${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}
171+
CIBW_ENVIRONMENT_WINDOWS: >
172+
CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})"
173+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
174+
CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_CUDA_MAJOR }}
175+
PIP_FIND_LINKS="$(cygpath -w ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }})"
176+
177+
- name: List the cuda.core artifacts directory and rename
178+
run: |
179+
if [[ "${{ inputs.host-platform }}" == win* ]]; then
180+
export CHOWN=chown
181+
else
182+
export CHOWN="sudo chown"
183+
fi
184+
$CHOWN -R $(whoami) ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
185+
186+
# Rename wheel to include CUDA version suffix
187+
mkdir -p "${{ env.CUDA_CORE_ARTIFACTS_DIR }}/cu${BUILD_CUDA_MAJOR}"
188+
for wheel in ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl; do
189+
if [[ -f "${wheel}" ]]; then
190+
base_name=$(basename "${wheel}" .whl)
191+
new_name="${base_name}.cu${BUILD_CUDA_MAJOR}.whl"
192+
mv "${wheel}" "${{ env.CUDA_CORE_ARTIFACTS_DIR }}/cu${BUILD_CUDA_MAJOR}/${new_name}"
193+
echo "Renamed wheel to: ${new_name}"
194+
fi
195+
done
196+
197+
ls -lahR ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
198+
173199
# We only need/want a single pure python wheel, pick linux-64 index 0.
174200
- name: Build and check cuda-python wheel
175201
if: ${{ strategy.job-index == 0 && inputs.host-platform == 'linux-64' }}
@@ -241,7 +267,7 @@ jobs:
241267

242268
- name: Build cuda.core Cython tests
243269
run: |
244-
pip install ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl --group ./cuda_core/pyproject.toml:test
270+
pip install ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/"cu${BUILD_CUDA_MAJOR}"/*.whl --group ./cuda_core/pyproject.toml:test
245271
pushd ${{ env.CUDA_CORE_CYTHON_TESTS_DIR }}
246272
bash build_tests.sh
247273
popd
@@ -252,3 +278,107 @@ jobs:
252278
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-tests
253279
path: ${{ env.CUDA_CORE_CYTHON_TESTS_DIR }}/test_*${{ env.PY_EXT_SUFFIX }}
254280
if-no-files-found: error
281+
282+
# Note: This overwrites CUDA_PATH etc
283+
- name: Set up mini CTK
284+
uses: ./.github/actions/fetch_ctk
285+
continue-on-error: false
286+
with:
287+
host-platform: ${{ inputs.host-platform }}
288+
cuda-version: ${{ inputs.prev-cuda-version }}
289+
cuda-path: "./cuda_toolkit_prev"
290+
291+
- name: Download cuda.bindings build artifacts from the prior branch
292+
if: ${{ matrix.python-version == '3.13t'
293+
|| matrix.python-version == '3.14'
294+
|| matrix.python-version == '3.14t' }}
295+
env:
296+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
297+
run: |
298+
if ! (command -v gh 2>&1 >/dev/null); then
299+
# See https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt.
300+
# gh is needed for artifact fetching.
301+
mkdir -p -m 755 /etc/apt/keyrings \
302+
&& out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
303+
&& cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
304+
&& chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
305+
&& 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 \
306+
&& apt update \
307+
&& apt install gh -y
308+
fi
309+
310+
OLD_BRANCH=$(cat .github/BACKPORT_BRANCH)
311+
OLD_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}*"
312+
LATEST_PRIOR_RUN_ID=$(gh run list -b ${OLD_BRANCH} -L 1 -w "ci.yml" -s completed -R NVIDIA/cuda-python --json databaseId | jq '.[]| .databaseId')
313+
if [[ "$LATEST_PRIOR_RUN_ID" == "" ]]; then
314+
echo "LATEST_PRIOR_RUN_ID not found!"
315+
exit 1
316+
fi
317+
318+
gh run download $LATEST_PRIOR_RUN_ID -p ${OLD_BASENAME} -R NVIDIA/cuda-python
319+
rm -rf ${OLD_BASENAME}-tests # exclude cython test artifacts
320+
ls -al $OLD_BASENAME
321+
mkdir -p "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
322+
mv $OLD_BASENAME/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
323+
rmdir $OLD_BASENAME
324+
325+
- name: Build cuda.core wheel
326+
uses: pypa/cibuildwheel@c923d83ad9c1bc00211c5041d0c3f73294ff88f6 # v3.1.4
327+
with:
328+
package-dir: ./cuda_core/
329+
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
330+
env:
331+
CIBW_BUILD: ${{ env.CIBW_BUILD }}
332+
# CIBW mounts the host filesystem under /host
333+
CIBW_ENVIRONMENT_LINUX: >
334+
CUDA_PATH=/host/${{ env.CUDA_PATH }}
335+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
336+
CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }}
337+
PIP_FIND_LINKS=/host/${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}
338+
CIBW_ENVIRONMENT_WINDOWS: >
339+
CUDA_PATH="$(cygpath -w ${{ env.CUDA_PATH }})"
340+
CUDA_PYTHON_PARALLEL_LEVEL=${{ env.CUDA_PYTHON_PARALLEL_LEVEL }}
341+
CUDA_CORE_BUILD_MAJOR=${{ env.BUILD_PREV_CUDA_MAJOR }}
342+
PIP_FIND_LINKS="$(cygpath -w ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }})"
343+
344+
- name: List the cuda.core artifacts directory and rename
345+
run: |
346+
if [[ "${{ inputs.host-platform }}" == win* ]]; then
347+
export CHOWN=chown
348+
else
349+
export CHOWN="sudo chown"
350+
fi
351+
$CHOWN -R $(whoami) ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
352+
ls -lahR ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
353+
354+
# Rename wheel to include CUDA version suffix
355+
mkdir -p "${{ env.CUDA_CORE_ARTIFACTS_DIR }}/cu${BUILD_PREV_CUDA_MAJOR}"
356+
for wheel in ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl; do
357+
if [[ -f "${wheel}" ]]; then
358+
base_name=$(basename "${wheel}" .whl)
359+
new_name="${base_name}.cu${BUILD_PREV_CUDA_MAJOR}.whl"
360+
mv "${wheel}" "${{ env.CUDA_CORE_ARTIFACTS_DIR }}/cu${BUILD_PREV_CUDA_MAJOR}/${new_name}"
361+
echo "Renamed wheel to: ${new_name}"
362+
fi
363+
done
364+
365+
ls -lahR ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
366+
367+
- name: Merge cuda.core wheels
368+
run: |
369+
pip install wheel
370+
python ci/tools/merge_cuda_core_wheels.py \
371+
"${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_CUDA_MAJOR}"/cuda_core*.whl \
372+
"${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_PREV_CUDA_MAJOR}"/cuda_core*.whl \
373+
--output-dir "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"
374+
375+
- name: Check cuda.core wheel
376+
run: |
377+
twine check --strict ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl
378+
379+
- name: Upload cuda.core build artifacts
380+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
381+
with:
382+
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}
383+
path: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl
384+
if-no-files-found: error

.github/workflows/ci.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,21 @@ jobs:
2121
runs-on: ubuntu-latest
2222
outputs:
2323
CUDA_BUILD_VER: ${{ steps.get-vars.outputs.cuda_build_ver }}
24+
CUDA_PREV_BUILD_VER: ${{ steps.get-vars.outputs.cuda_prev_build_ver }}
2425
steps:
2526
- name: Checkout repository
2627
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
2728
with:
2829
fetch-depth: 0
29-
- name: Get CUDA build version
30+
- name: Get CUDA build versions
3031
id: get-vars
3132
run: |
3233
cuda_build_ver=$(jq -r .cuda.build.version ci/versions.json)
3334
echo "cuda_build_ver=$cuda_build_ver" >> $GITHUB_OUTPUT
3435
36+
cuda_prev_build_ver=$(jq -r .cuda.prev_build.version ci/versions.json)
37+
echo "cuda_prev_build_ver=$cuda_prev_build_ver" >> $GITHUB_OUTPUT
38+
3539
should-skip:
3640
runs-on: ubuntu-latest
3741
outputs:
@@ -69,6 +73,7 @@ jobs:
6973
with:
7074
host-platform: ${{ matrix.host-platform }}
7175
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
76+
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
7277

7378
# WARNING: make sure all of the build jobs are in sync
7479
build-linux-aarch64:
@@ -87,6 +92,7 @@ jobs:
8792
with:
8893
host-platform: ${{ matrix.host-platform }}
8994
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
95+
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
9096

9197
# WARNING: make sure all of the build jobs are in sync
9298
build-windows:
@@ -105,6 +111,7 @@ jobs:
105111
with:
106112
host-platform: ${{ matrix.host-platform }}
107113
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
114+
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
108115

109116
# WARNING: make sure both Linux test jobs are in sync
110117
test-linux-64:

.spdx-ignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ requirements*.txt
1010
cuda_bindings/examples/*
1111

1212
# Vendored
13-
cuda_core/cuda/core/experimental/dlpack.h
13+
cuda_core/cuda/core/experimental/include/dlpack.h

ci/tools/env-vars

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ if [[ "${1}" == "build" ]]; then
4141
# platform is handled by the default value of platform (`auto`) in cibuildwheel
4242
# here we only need to specify the python version we want
4343
echo "CIBW_BUILD=cp${PYTHON_VERSION_FORMATTED}-*" >> $GITHUB_ENV
44+
BUILD_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${CUDA_VER})"
45+
echo "BUILD_CUDA_MAJOR=${BUILD_CUDA_MAJOR}" >> $GITHUB_ENV
46+
echo "BUILD_PREV_CUDA_MAJOR=$((${BUILD_CUDA_MAJOR} - 1))" >> $GITHUB_ENV
4447
CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${CUDA_VER}-${HOST_PLATFORM}"
4548
elif [[ "${1}" == "test" ]]; then
4649
BUILD_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${BUILD_CUDA_VER})"

0 commit comments

Comments
 (0)