Skip to content

Commit dcb56ec

Browse files
authored
Merge branch 'main' into nvbug6084457-2
2 parents bcc1c90 + 51141c8 commit dcb56ec

72 files changed

Lines changed: 3446 additions & 1448 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
name: griffe API check
6+
7+
description: >-
8+
Check a package's public API (as defined by `__all__`) for changes using
9+
griffe.
10+
11+
inputs:
12+
package-name:
13+
description: "Importable package name to check, e.g. cuda.core"
14+
required: true
15+
package-dir:
16+
description: "Directory to search for the package sources, e.g. cuda_core"
17+
required: true
18+
merge-base:
19+
description: >-
20+
Git ref/sha to compare the current code against, typically the PR's
21+
merge-base with its target branch.
22+
required: true
23+
24+
runs:
25+
using: composite
26+
steps:
27+
- name: Install uv
28+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
29+
with:
30+
enable-cache: false
31+
32+
- name: Check API
33+
shell: bash --noprofile --norc -euo pipefail {0}
34+
env:
35+
PACKAGE_NAME: ${{ inputs.package-name }}
36+
PACKAGE_DIR: ${{ inputs.package-dir }}
37+
MERGE_BASE: ${{ inputs.merge-base }}
38+
run: |
39+
uvx griffe check "$PACKAGE_NAME" \
40+
--search "$PACKAGE_DIR" \
41+
--find-stubs-packages \
42+
--against "$MERGE_BASE" \
43+
--format github \
44+
2>&1

‎.github/workflows/build-wheel.yml‎

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ jobs:
166166
cuda-version: ${{ inputs.cuda-version }}
167167

168168
- name: Build cuda.bindings wheel
169-
uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
169+
uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
170170
with:
171171
package-dir: ./cuda_bindings/
172172
output-dir: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}
@@ -234,7 +234,7 @@ jobs:
234234
if-no-files-found: error
235235

236236
- name: Build cuda.core wheel
237-
uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
237+
uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
238238
with:
239239
package-dir: ./cuda_core/
240240
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
@@ -338,13 +338,16 @@ jobs:
338338
id: setup-python2
339339
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
340340
with:
341-
# TODO: Pin beta.2 precisely until cibuildwheel catches up (b4 broke ABI for Cython);
342-
# this precise pin requires the explicit `freethreaded`.
343-
# When 3.15 is officially supported we can also remove the `allow-prereleases` override.
344-
python-version: ${{ startsWith(matrix.python-version, '3.15') && '3.15.0-beta.2' || matrix.python-version }}
345-
freethreaded: ${{ endsWith(matrix.python-version, 't') }}
341+
python-version: ${{ matrix.python-version }}
342+
# TODO: remove allow-prereleases once 3.15 is officially supported
346343
allow-prereleases: ${{ startsWith(matrix.python-version, '3.15') }}
347344

345+
- name: Enable Scientific Python Nightly Wheels for Python 3.15
346+
if: ${{ startsWith(matrix.python-version, '3.15') }}
347+
run: |
348+
echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV"
349+
echo "PIP_ONLY_BINARY=numpy" >> "$GITHUB_ENV"
350+
348351
- name: verify free-threaded build
349352
if: endsWith(matrix.python-version, 't')
350353
run: python -c 'import sys; assert not sys._is_gil_enabled()'
@@ -370,64 +373,6 @@ jobs:
370373
mv "/c/Program Files/Git/usr/bin/link.exe" "/c/Program Files/Git/usr/bin/link.exe.bak"
371374
fi
372375
373-
# TODO: remove the numpy pre-build steps once 3.15 is officially supported
374-
# (numpy will publish pre-built 3.15 wheels at that point)
375-
- name: Download and patch numpy sdist (pre-release Python)
376-
if: ${{ startsWith(matrix.python-version, '3.15') }}
377-
run: |
378-
pip download --no-binary numpy --no-deps "numpy>=1.21.1" -d numpy-sdist/
379-
cd numpy-sdist && tar xf numpy-*.tar.gz && rm numpy-*.tar.gz
380-
# WAR: numpy 2.4.x ships [tool.cibuildwheel] config that is
381-
# incompatible with cibuildwheel v4.0 (cpython-freethreading enable
382-
# group, OpenBLAS before-build scripts, etc.). Strip the cibuildwheel
383-
# sections but preserve [tool.meson-python] (vendored meson path).
384-
python -c "
385-
import glob
386-
for f in glob.glob('numpy-*/pyproject.toml'):
387-
lines, skip = open(f).readlines(), False
388-
out = []
389-
for line in lines:
390-
hdr = line.strip()
391-
if hdr.startswith('[tool.cibuildwheel') or hdr.startswith('[[tool.cibuildwheel'):
392-
skip = True
393-
continue
394-
if skip and hdr.startswith('[') and 'cibuildwheel' not in hdr:
395-
skip = False
396-
if not skip:
397-
out.append(line)
398-
open(f, 'w').writelines(out)
399-
"
400-
echo "NUMPY_SRC_DIR=$(pwd)/$(ls -d numpy-*/)" >> $GITHUB_ENV
401-
402-
- name: Build numpy wheel (pre-release Python)
403-
if: ${{ startsWith(matrix.python-version, '3.15') }}
404-
uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
405-
env:
406-
CIBW_BUILD: ${{ env.CIBW_BUILD }}
407-
CIBW_SKIP: "*-musllinux* *-win32"
408-
CIBW_ARCHS_LINUX: "native"
409-
CIBW_BUILD_VERBOSITY: 1
410-
CIBW_CONFIG_SETTINGS: "setup-args=-Dallow-noblas=true"
411-
CIBW_CONFIG_SETTINGS_WINDOWS: "setup-args=--vsenv setup-args=-Dallow-noblas=true"
412-
CIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel"
413-
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair -w {dest_dir} {wheel}"
414-
CIBW_ENABLE: "cpython-prerelease"
415-
with:
416-
package-dir: ${{ env.NUMPY_SRC_DIR }}
417-
output-dir: numpy-wheel/
418-
419-
- name: Upload numpy wheel
420-
if: ${{ startsWith(matrix.python-version, '3.15') }}
421-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
422-
with:
423-
name: numpy-python${{ env.PYTHON_VERSION_FORMATTED }}-${{ inputs.host-platform }}
424-
path: numpy-wheel/*.whl
425-
if-no-files-found: error
426-
427-
- name: Install numpy wheel
428-
if: ${{ startsWith(matrix.python-version, '3.15') }}
429-
run: pip install numpy-wheel/*.whl
430-
431376
- name: Build cuda.bindings Cython tests
432377
run: |
433378
pip install ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}/*.whl --group ./cuda_bindings/pyproject.toml:test
@@ -508,7 +453,7 @@ jobs:
508453
rmdir $OLD_BASENAME
509454
510455
- name: Build cuda.core wheel
511-
uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
456+
uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
512457
with:
513458
package-dir: ./cuda_core/
514459
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}

‎.github/workflows/ci.yml‎

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ jobs:
103103
test_bindings: ${{ steps.compose.outputs.test_bindings }}
104104
test_core: ${{ steps.compose.outputs.test_core }}
105105
test_pathfinder: ${{ steps.compose.outputs.test_pathfinder }}
106+
pr_merge_base: ${{ steps.filter.outputs.merge_base }}
106107
steps:
107108
- name: Checkout repository
108109
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
@@ -156,6 +157,7 @@ jobs:
156157
echo "python_meta=$(has_match '^cuda_python/')"
157158
echo "test_helpers=$(has_match '^cuda_python_test_helpers/')"
158159
echo "shared=$(has_match '^(\.github/|ci/|scripts/|toolshed/|conftest\.py$|pyproject\.toml$|pixi\.(toml|lock)$|pytest\.ini$|ruff\.toml$)')"
160+
echo "merge_base=${base}"
159161
} >> "$GITHUB_OUTPUT"
160162
161163
- name: Compose gating outputs
@@ -228,6 +230,89 @@ jobs:
228230
echo "test_pathfinder=${test_pathfinder}"
229231
} >> "$GITHUB_OUTPUT"
230232
233+
api-check-core-vs-release:
234+
name: API check (cuda_core vs. latest release)
235+
if: >-
236+
${{ !fromJSON(needs.should-skip.outputs.skip) &&
237+
fromJSON(needs.detect-changes.outputs.core) }}
238+
runs-on: ubuntu-latest
239+
needs:
240+
- should-skip
241+
- detect-changes
242+
permissions:
243+
contents: read
244+
steps:
245+
- name: Checkout repository
246+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
247+
with:
248+
fetch-depth: 1
249+
filter: blob:none
250+
251+
- name: Find latest release tag
252+
id: latest-tag
253+
shell: bash --noprofile --norc -euo pipefail {0}
254+
env:
255+
GH_TOKEN: ${{ github.token }}
256+
run: |
257+
# --paginate fetches all pages; jq outputs one name per line per page;
258+
# sed prints the first (newest) match while consuming all pages, so
259+
# gh can complete without SIGPIPE. Fails if no cuda-core-v* tag is found.
260+
tag="$(gh api "repos/$GITHUB_REPOSITORY/tags" --paginate \
261+
--jq '.[] | select(.name | startswith("cuda-core-v")) | .name' \
262+
| sed -n '1p')"
263+
if [[ -z "${tag}" ]]; then
264+
echo "::error::No cuda-core-v* tag found in the repository." >&2
265+
exit 1
266+
fi
267+
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
268+
269+
- name: Fetch release tag
270+
shell: bash --noprofile --norc -euo pipefail {0}
271+
run: |
272+
git fetch --depth=1 --filter=blob:none origin \
273+
"refs/tags/${{ steps.latest-tag.outputs.tag }}:refs/tags/${{ steps.latest-tag.outputs.tag }}"
274+
275+
- name: Check cuda_core public API
276+
id: griffe
277+
uses: ./.github/actions/griffe-api-check
278+
with:
279+
package-name: cuda.core
280+
package-dir: cuda_core
281+
merge-base: ${{ steps.latest-tag.outputs.tag }}
282+
283+
api-check-core-vs-base:
284+
name: API check (cuda_core vs. merge base)
285+
if: >-
286+
${{ startsWith(github.ref_name, 'pull-request/') &&
287+
!fromJSON(needs.should-skip.outputs.skip) &&
288+
fromJSON(needs.detect-changes.outputs.core) }}
289+
runs-on: ubuntu-latest
290+
needs:
291+
- should-skip
292+
- detect-changes
293+
permissions:
294+
contents: read
295+
steps:
296+
- name: Checkout repository
297+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
298+
with:
299+
fetch-depth: 1
300+
filter: blob:none
301+
302+
- name: Fetch merge base commit
303+
shell: bash --noprofile --norc -euo pipefail {0}
304+
run: |
305+
git fetch --depth=1 --filter=blob:none origin \
306+
"${{ needs.detect-changes.outputs.pr_merge_base }}"
307+
308+
- name: Check cuda_core public API
309+
id: griffe
310+
uses: ./.github/actions/griffe-api-check
311+
with:
312+
package-name: cuda.core
313+
package-dir: cuda_core
314+
merge-base: ${{ needs.detect-changes.outputs.pr_merge_base }}
315+
231316
# NOTE: Build jobs are intentionally split by platform rather than using a single
232317
# matrix. This allows each test job to depend only on its corresponding build,
233318
# so faster platforms can proceed through build & test without waiting for slower
@@ -416,6 +501,38 @@ jobs:
416501
with:
417502
is-release: ${{ github.ref_type == 'tag' }}
418503

504+
precommit-windows:
505+
name: Pre-commit on Windows
506+
runs-on: windows-latest
507+
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
508+
needs:
509+
- should-skip
510+
permissions:
511+
contents: read
512+
steps:
513+
- name: Checkout repository
514+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
515+
with:
516+
fetch-depth: 1
517+
persist-credentials: false
518+
519+
- name: Set up Python
520+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
521+
with:
522+
python-version: '3.13'
523+
524+
- name: Install pre-commit
525+
shell: bash
526+
run: |
527+
set -euxo pipefail
528+
python -m pip install --upgrade pip pre-commit
529+
530+
- name: Run pre-commit
531+
shell: bash
532+
run: |
533+
set -euxo pipefail
534+
SKIP=lychee pre-commit run --all-files
535+
419536
checks:
420537
name: Check job status
421538
if: always()
@@ -429,6 +546,7 @@ jobs:
429546
- test-linux-aarch64
430547
- test-windows
431548
- doc
549+
- precommit-windows
432550
steps:
433551
- name: Exit
434552
run: |
@@ -461,6 +579,7 @@ jobs:
461579
check_result "should-skip" "success" "${{ needs.should-skip.result }}"
462580
check_result "detect-changes" "success" "${{ needs.detect-changes.result }}"
463581
check_result "doc" "success" "${{ needs.doc.result }}"
582+
check_result "precommit-windows" "success" "${{ needs.precommit-windows.result }}"
464583
465584
# [doc-only] flips these from 'success' to 'skipped'
466585
if [[ "$doc_only" == "true" ]]; then expected="skipped"; else expected="success"; fi

‎.github/workflows/test-wheel-linux.yml‎

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -296,16 +296,19 @@ jobs:
296296
- name: Set up Python ${{ matrix.PY_VER }}
297297
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
298298
with:
299-
# TODO: Pin beta.2 precisely until cibuildwheel catches up (b4 broke ABI for Cython)
300-
# this precise pin requires the explicit `freethreaded`.
301-
# When 3.15 is officially supported we can also remove the `allow-prereleases` override.
302-
python-version: ${{ startsWith(matrix.PY_VER, '3.15') && '3.15.0-beta.2' || matrix.PY_VER }}
303-
freethreaded: ${{ endsWith(matrix.PY_VER, 't') }}
299+
python-version: ${{ matrix.PY_VER }}
300+
# TODO: remove allow-prereleases once 3.15 is officially supported
304301
allow-prereleases: ${{ startsWith(matrix.PY_VER, '3.15') }}
305302
env:
306303
# we use self-hosted runners on which setup-python behaves weirdly (Python include can't be found)...
307304
AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache"
308305

306+
- name: Enable Scientific Python Nightly Wheels for Python 3.15
307+
if: ${{ startsWith(matrix.PY_VER, '3.15') }}
308+
run: |
309+
echo "PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" >> "$GITHUB_ENV"
310+
echo "PIP_ONLY_BINARY=numpy" >> "$GITHUB_ENV"
311+
309312
- name: Set up mini CTK
310313
if: ${{ matrix.LOCAL_CTK == '1' }}
311314
uses: ./.github/actions/fetch_ctk
@@ -314,18 +317,6 @@ jobs:
314317
host-platform: ${{ inputs.host-platform }}
315318
cuda-version: ${{ matrix.CUDA_VER }}
316319

317-
# TODO: remove the numpy wheel steps once 3.15 is officially supported
318-
- name: Download numpy wheel (pre-release Python)
319-
if: ${{ startsWith(matrix.PY_VER, '3.15') }}
320-
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
321-
with:
322-
name: numpy-python${{ env.PYTHON_VERSION_FORMATTED }}-${{ inputs.host-platform }}
323-
path: numpy-wheel
324-
325-
- name: Install numpy wheel (pre-release Python)
326-
if: ${{ startsWith(matrix.PY_VER, '3.15') }}
327-
run: pip install numpy-wheel/*.whl
328-
329320
- name: Set up latest cuda_sanitizer_api
330321
if: ${{ env.SETUP_SANITIZER == '1' }}
331322
uses: ./.github/actions/fetch_ctk

0 commit comments

Comments
 (0)