Skip to content

Commit 9d762dd

Browse files
committed
Add Windows-on-ARM support
1 parent 8f75d26 commit 9d762dd

4 files changed

Lines changed: 98 additions & 16 deletions

File tree

‎.github/actions/fetch_ctk/action.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ runs:
7979
function extract() {
8080
tar -xvf $1 -C $CACHE_TMP_DIR --strip-components=1
8181
}
82-
elif [[ "${{ inputs.host-platform }}" == "win-64" ]]; then
82+
elif [[ "${{ inputs.host-platform }}" == win* ]]; then
8383
function extract() {
8484
_TEMP_DIR_=$(mktemp -d)
8585
unzip $1 -d $_TEMP_DIR_

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ on:
1919
required: false
2020
type: string
2121
default: ""
22+
single-cuda-major:
23+
description: "Build wheels for only the current CUDA major; skip the prior-major build and wheel merge"
24+
required: false
25+
type: boolean
26+
default: false
2227

2328
defaults:
2429
run:
@@ -54,7 +59,8 @@ jobs:
5459
name: py${{ matrix.python-version }}
5560
runs-on: ${{ (inputs.host-platform == 'linux-64' && 'linux-amd64-cpu8') ||
5661
(inputs.host-platform == 'linux-aarch64' && 'linux-arm64-cpu8') ||
57-
(inputs.host-platform == 'win-64' && 'windows-2022') }}
62+
(inputs.host-platform == 'win-64' && 'windows-2022') ||
63+
(inputs.host-platform == 'win-arm64' && 'windows-11-arm') }}
5864
steps:
5965
- name: Checkout ${{ github.event.repository.name }}
6066
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -87,7 +93,7 @@ jobs:
8793
uses: nv-gha-runners/setup-proxy-cache@main
8894
continue-on-error: true
8995
# Skip cache on GitHub-hosted Windows runners.
90-
if: ${{ inputs.host-platform != 'win-64' }}
96+
if: ${{ !startsWith(inputs.host-platform, 'win') }}
9197
with:
9298
enable-apt: true
9399

@@ -98,22 +104,26 @@ jobs:
98104
# WAR: setup-python is not relocatable, and cibuildwheel hard-wires to 3.12...
99105
# see https://github.com/actions/setup-python/issues/871
100106
python-version: "3.12"
107+
architecture: ${{ ((inputs.host-platform == 'linux-aarch64' || inputs.host-platform == 'win-arm64') && 'arm64') || 'x64' }}
101108

102109
- name: Set up MSVC
103110
if: ${{ startsWith(inputs.host-platform, 'win') && (env.BUILD_BINDINGS == 'true' || env.BUILD_CORE == 'true' || env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true') }}
104111
uses: step-security/msvc-dev-cmd@22c98154b708dbd743e6f27a933cf6ceba3305c4 # v1.13.1
112+
with:
113+
arch: ${{ (inputs.host-platform == 'win-arm64' && 'arm64') || 'x64' }}
105114

106115
- name: Set up yq
107116
# GitHub made an unprofessional decision to not provide it in their Windows VMs,
108117
# see https://github.com/actions/runner-images/issues/7443.
109118
if: ${{ startsWith(inputs.host-platform, 'win') && env.BUILD_CORE == 'true' }}
110119
env:
111120
YQ_VERSION: v4.52.5
112-
YQ_SHA256: 47594981f3848a4b4447494adeca9555f908f7cf0a89c4da3fd0243a4631da1c
121+
YQ_ARCH: ${{ (inputs.host-platform == 'win-arm64' && 'arm64') || 'amd64' }}
122+
YQ_SHA256: ${{ (inputs.host-platform == 'win-arm64' && '236867affa7f18701d4c763cf16b6df962cf4f7e89a8570a5954cf94a38f41c7') || '47594981f3848a4b4447494adeca9555f908f7cf0a89c4da3fd0243a4631da1c' }}
113123
YQ_DIR: yq
114124
shell: pwsh -command ". '{0}'"
115125
run: |
116-
$yqUrl = "https://github.com/mikefarah/yq/releases/download/${env:YQ_VERSION}/yq_windows_amd64.exe"
126+
$yqUrl = "https://github.com/mikefarah/yq/releases/download/${env:YQ_VERSION}/yq_windows_${env:YQ_ARCH}.exe"
117127
mkdir -Force -ErrorAction SilentlyContinue "${env:YQ_DIR}" | Out-Null
118128
Invoke-WebRequest -UseBasicParsing -OutFile "${env:YQ_DIR}/yq.exe" -Uri "$yqUrl"
119129
$hash = (Get-FileHash -Algorithm SHA256 "${env:YQ_DIR}/yq.exe").Hash.ToLower()
@@ -253,7 +263,7 @@ jobs:
253263
echo "ok!"
254264
255265
- name: Report sccache stats (cuda.bindings)
256-
if: ${{ env.BUILD_BINDINGS == 'true' && inputs.host-platform != 'win-64' }}
266+
if: ${{ env.BUILD_BINDINGS == 'true' && !startsWith(inputs.host-platform, 'win') }}
257267
uses: ./.github/actions/sccache-summary
258268
with:
259269
json-file: sccache_bindings.json
@@ -362,7 +372,7 @@ jobs:
362372
echo "ok!"
363373
364374
- name: Report sccache stats (cuda.core)
365-
if: ${{ env.BUILD_CORE == 'true' && inputs.host-platform != 'win-64' }}
375+
if: ${{ env.BUILD_CORE == 'true' && !startsWith(inputs.host-platform, 'win') }}
366376
uses: ./.github/actions/sccache-summary
367377
with:
368378
json-file: sccache_core.json
@@ -524,7 +534,7 @@ jobs:
524534

525535
# Note: This overwrites CUDA_PATH etc
526536
- name: Set up mini CTK
527-
if: ${{ env.BUILD_CORE == 'true' || env.TEST_CORE == 'true' }}
537+
if: ${{ !inputs.single-cuda-major && (env.BUILD_CORE == 'true' || env.TEST_CORE == 'true') }}
528538
uses: ./.github/actions/fetch_ctk
529539
continue-on-error: false
530540
with:
@@ -533,13 +543,13 @@ jobs:
533543
cuda-path: "./cuda_toolkit_prev"
534544

535545
- name: Build cuda.core test binaries
536-
if: ${{ env.TEST_CORE == 'true' }}
546+
if: ${{ !inputs.single-cuda-major && env.TEST_CORE == 'true' }}
537547
run: |
538548
nvcc --version
539549
python "${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/build_test_binaries.py"
540550
541551
- name: Upload cuda.core test binaries
542-
if: ${{ env.TEST_CORE == 'true' }}
552+
if: ${{ !inputs.single-cuda-major && env.TEST_CORE == 'true' }}
543553
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
544554
with:
545555
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-test-binaries
@@ -550,7 +560,7 @@ jobs:
550560
if-no-files-found: error
551561

552562
- name: Download cuda.bindings build artifacts from the prior branch
553-
if: ${{ env.BUILD_CORE == 'true' }}
563+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
554564
env:
555565
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
556566
run: |
@@ -586,7 +596,7 @@ jobs:
586596
rmdir "${OLD_ARTIFACT_DIR}"
587597
588598
- name: Constrain previous cuda.core to the downloaded cuda.bindings wheel
589-
if: ${{ env.BUILD_CORE == 'true' }}
599+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
590600
run: |
591601
pathfinder_wheels=(cuda_pathfinder/cuda_pathfinder-*.whl)
592602
bindings_wheels=(cuda_bindings/dist-prev/cuda_bindings-"${BUILD_PREV_CUDA_MAJOR}".*.whl)
@@ -608,7 +618,7 @@ jobs:
608618
} | tee wheel-constraints/cuda-core-prev.txt
609619
610620
- name: Build cuda.core wheel
611-
if: ${{ env.BUILD_CORE == 'true' }}
621+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
612622
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
613623
with:
614624
package-dir: ./cuda_core/
@@ -656,15 +666,15 @@ jobs:
656666
echo "ok!"
657667
658668
- name: Report sccache stats (cuda.core prev)
659-
if: ${{ env.BUILD_CORE == 'true' && inputs.host-platform != 'win-64' }}
669+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' && !startsWith(inputs.host-platform, 'win') }}
660670
uses: ./.github/actions/sccache-summary
661671
with:
662672
json-file: sccache_core_prev.json
663673
label: "cuda.core (prev CTK)"
664674
build-step: "Build cuda.core wheel"
665675

666676
- name: List the cuda.core artifacts directory and rename
667-
if: ${{ env.BUILD_CORE == 'true' }}
677+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
668678
run: |
669679
if [[ "${{ inputs.host-platform }}" == win* ]]; then
670680
export CHOWN=chown
@@ -688,14 +698,23 @@ jobs:
688698
ls -lahR ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
689699
690700
- name: Merge cuda.core wheels
691-
if: ${{ env.BUILD_CORE == 'true' }}
701+
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
692702
run: |
693703
pip install wheel
694704
python ci/tools/merge_cuda_core_wheels.py \
695705
"${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_CUDA_MAJOR}"/cuda_core*.whl \
696706
"${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_PREV_CUDA_MAJOR}"/cuda_core*.whl \
697707
--output-dir "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"
698708
709+
- name: Finalize single-major cuda.core wheel
710+
if: ${{ inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
711+
run: |
712+
for wheel in "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_CUDA_MAJOR}"/*.cu"${BUILD_CUDA_MAJOR}".whl; do
713+
base_name=$(basename "${wheel}" ".cu${BUILD_CUDA_MAJOR}.whl")
714+
mv "${wheel}" "${{ env.CUDA_CORE_ARTIFACTS_DIR }}/${base_name}.whl"
715+
done
716+
ls -lahR "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"
717+
699718
- name: Check cuda.core wheel
700719
if: ${{ env.BUILD_CORE == 'true' }}
701720
run: |

‎.github/workflows/ci.yml‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ jobs:
3333
outputs:
3434
CUDA_BUILD_VER: ${{ steps.get-vars.outputs.cuda_build_ver }}
3535
CUDA_PREV_BUILD_VER: ${{ steps.get-vars.outputs.cuda_prev_build_ver }}
36+
WINDOWS_ARM64_SUPPORTED: ${{ steps.get-vars.outputs.windows_arm64_supported }}
37+
WINDOWS_ARM64_SINGLE_CUDA_MAJOR: ${{ steps.get-vars.outputs.windows_arm64_single_cuda_major }}
3638
steps:
3739
- name: Checkout repository
3840
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -47,6 +49,33 @@ jobs:
4749
cuda_prev_build_ver=$(yq '.cuda.prev_build.version' ci/versions.yml)
4850
echo "cuda_prev_build_ver=$cuda_prev_build_ver" >> $GITHUB_OUTPUT
4951
52+
# Windows ARM64 is available starting with CUDA 13.4.
53+
if [[ "$cuda_build_ver" =~ ^([0-9]+)\.([0-9]+)(\.|$) ]]; then
54+
cuda_build_major="${BASH_REMATCH[1]}"
55+
cuda_build_minor="${BASH_REMATCH[2]}"
56+
else
57+
echo "Invalid CUDA build version: $cuda_build_ver" >&2
58+
exit 1
59+
fi
60+
if (( cuda_build_major > 13 || (cuda_build_major == 13 && cuda_build_minor >= 4) )); then
61+
windows_arm64_supported=true
62+
else
63+
windows_arm64_supported=false
64+
fi
65+
echo "windows_arm64_supported=$windows_arm64_supported" >> $GITHUB_OUTPUT
66+
67+
# No CUDA 13 windows-arm64 toolkit exists for a major other than the
68+
# current one (windows-arm64 support started mid-way through the 13.x
69+
# series), so cuda.core can only be built against a single CUDA major
70+
# while the build major is still 13. Once the build major advances to
71+
# 14, a CUDA 13 windows-arm64 toolkit will exist as the prior major.
72+
if [[ "$cuda_build_major" == "13" ]]; then
73+
windows_arm64_single_cuda_major=true
74+
else
75+
windows_arm64_single_cuda_major=false
76+
fi
77+
echo "windows_arm64_single_cuda_major=$windows_arm64_single_cuda_major" >> $GITHUB_OUTPUT
78+
5079
should-skip:
5180
if: ${{ github.repository_owner == 'nvidia' }}
5281
runs-on: ubuntu-latest
@@ -414,6 +443,31 @@ jobs:
414443
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
415444
workplan: ${{ needs.detect-changes.outputs.workplan }}
416445

446+
# Windows ARM64 is available starting with CUDA 13.4. Build only the current
447+
# CUDA major because no prior-major toolkit or wheel artifacts exist.
448+
build-windows-arm64:
449+
needs:
450+
- ci-vars
451+
- should-skip
452+
- detect-changes
453+
name: Build win-arm64, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
454+
if: ${{ github.repository_owner == 'nvidia' &&
455+
!fromJSON(needs.should-skip.outputs.skip) &&
456+
!fromJSON(needs.should-skip.outputs.doc-only) &&
457+
needs.ci-vars.outputs.WINDOWS_ARM64_SUPPORTED == 'true' &&
458+
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.windows }}
459+
permissions:
460+
actions: read
461+
contents: read
462+
secrets: inherit
463+
uses: ./.github/workflows/build-wheel.yml
464+
with:
465+
host-platform: win-arm64
466+
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
467+
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
468+
workplan: ${{ needs.detect-changes.outputs.workplan }}
469+
single-cuda-major: ${{ needs.ci-vars.outputs.WINDOWS_ARM64_SINGLE_CUDA_MAJOR == 'true' }}
470+
417471
# NOTE: test-sdist jobs are split by platform (mirroring build-* and test-wheel-*)
418472
# so platform-specific sources (e.g. cuda_bindings/*_windows.pyx selected by
419473
# build_hooks.py) are exercised on their target OS. Keep these job definitions
@@ -613,6 +667,7 @@ jobs:
613667
- build-linux-64
614668
- build-linux-aarch64
615669
- build-windows
670+
- build-windows-arm64
616671
- test-sdist-linux
617672
- test-sdist-windows
618673
- test-linux-64
@@ -644,6 +699,7 @@ jobs:
644699
doc_only="${{ needs.should-skip.outputs.doc-only }}"
645700
linux_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.linux || false }}"
646701
windows_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.windows || false }}"
702+
windows_arm64_supported="${{ needs.ci-vars.outputs.WINDOWS_ARM64_SUPPORTED }}"
647703
build_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.sdist_tests || false }}"
648704
run_core_api_check="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.core_api_checks || false }}"
649705
is_pr="${{ startsWith(github.ref_name, 'pull-request/') }}"
@@ -679,6 +735,12 @@ jobs:
679735
check_result "build-linux-aarch64" "$linux_expected"
680736
check_result "build-windows" "$windows_expected"
681737
738+
windows_arm64_expected="skipped"
739+
if [[ "$windows_arm64_supported" == "true" ]]; then
740+
windows_arm64_expected="$windows_expected"
741+
fi
742+
check_result "build-windows-arm64" "$windows_arm64_expected"
743+
682744
# Sdist tests follow build selection; wheel tests follow the platform plan.
683745
expected="skipped"
684746
if [[ "$doc_only" != "true" && "$build_selected" == "true" ]]; then

‎ci/tools/fetch_ctk_redistrib.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"linux-64": "linux-x86_64",
2222
"linux-aarch64": "linux-sbsa",
2323
"win-64": "windows-x86_64",
24+
"win-arm64": "windows-arm64",
2425
}
2526

2627
# CTK 13.3.0 renamed the redistrib key from cuda_cccl to cccl.

0 commit comments

Comments
 (0)