[CUDA] Add win-arm64 packaging and size options to plugin pipeline - #31635
Merged
Tianlei Wu (tianleiwu) merged 6 commits intoAug 5, 2026
Merged
Conversation
Baiju Meswani (baijumeswani)
previously approved these changes
Aug 4, 2026
Baiju Meswani (baijumeswani)
approved these changes
Aug 5, 2026
Tianlei Wu (tianleiwu)
enabled auto-merge (squash)
August 5, 2026 01:15
Tianlei Wu (tianleiwu)
added a commit
that referenced
this pull request
Aug 5, 2026
…ugin_pipeline_update
Tianlei Wu (tianleiwu)
deleted the
tlwu/20260804/cuda_plugin_pipeline_update
branch
August 5, 2026 21:00
This was referenced Aug 12, 2026
This was referenced Aug 17, 2026
Open
Closed
This was referenced Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Extends the CUDA plugin EP packaging pipeline with Windows ARM64 support, replaces the shared x64/ARM64 architecture lists with per-platform lists that reflect the GPUs each package actually targets, and adds two build-time knobs for controlling binary size. The plugin
.so/.dllis currently very large (~720 MB uncompressed on the CUDA 12.8 Linux leg, ~90% of which is.nv_fatbin), and the architecture list is the single biggest lever on that number, so it needs to be tuned per platform rather than shared.Summary of Changes
Windows ARM64 packaging
plugin-cuda-pipeline.ymlbuild_windows_arm64; renameinvalidAArch64ConfigtoinvalidArm64Configand extend it to cover Windows ARM64, since NVIDIA only ships Windows-on-ARM CUDA for 13.xplugin-cuda-packaging-stage.ymlbuild_windows_arm64andarm64_cuda_version(13.1), wire the ARM64 stage and its artifacts into NuGet and Foundry Local zip packagingplugin-win-cuda-stage.ymlarm64arch path: ARM64 agent pool,win-arm64/CUDA SDK blob prefix, separate cuDNN folder, native ARM64 toolsetPer-platform CUDA architecture lists
cmake_x64_cuda_archs/cmake_arm64_cuda_archsare split into four independent lists, since Windows x64, Linux x64, Windows ARM64, and Linux aarch64 serve very different GPU populations:cmake_windows_x64_cuda_archs61,75,86,89,12075,80,86,89,120cmake_windows_arm64_cuda_archs120,121cmake_linux_x64_cuda_archs75,80,86,89,90,12075,80,86,89,90,120cmake_linux_aarch64_cuda_archs89,90,100,103,120,121Notable decisions:
120-virtualdropped everywhere. Thecompute_120PTX measured 176 MB, 27% of the entire.nv_fatbin— by far the most expensive single entry. It also cannot carry the NVFP4 kernels, which are only valid as realsm_120a(cuobjdump -ptx | grep -c e2m1x2returns 0), so it was paying full price for partial coverage.90), GB200 (100), GB300 (103), DGX Spark GB10 (121), plus discrete cards in ARM chassis (89,120).103is required alongside100because ORT normalizes100to100a-real, andatargets are locked to their exact SM.75dropped from Linux aarch64 — Turing was never paired with an ARM host in practice.CUDA architecture normalization
cmake/external/cuda_configuration.cmakeARCHITECTURES_WITH_ACCEL: add103and121, drop101(removed by NVIDIA after CUDA 12.9). Without this,103and121would be built as plain targets and would silently lose the CUTLASS block-scaled/TMA kernels, which are gated on__CUDA_ARCH_FEAT_SM1xx_ALL.Build size controls
Two new pipeline parameters, both plumbed through the packaging stage to all four platform stages:
enable_cuda_fatbin_size_compressionfalseonnxruntime_CUDA_FATBIN_COMPRESS_SIZEcmake option, forcing-Xfatbin=-compress-all -compress-mode=sizeon the CUDA 12.8 leg. CUDA >= 13.0 already does this unconditionally, so the parameter only changes 12.8.enable_fpa_intb_gemmtrueonnxruntime_USE_FPA_INTB_GEMMcmake option. fpA_intB GEMV/GEMM is ~141 MB of device code (22% of.nv_fatbin), second only to flash attention.onnxruntime_CUDA_FATBIN_COMPRESS_SIZEfails configuration on CUDA < 12.8 rather than silently passing an unsupported flag to nvcc.Windows composes these via
FatbinCompressOption/FpaIntBGemmOptionjob variables appended to thebuild.pyinvocations, mirroring the existing$(TelemetryOption)pattern. Linux composes them intoEXTRA_CMAKE_DEFINES, whichbuild_cuda_plugin_package.shalready forwards.Packaged binary hardening and verification
cmake/onnxruntime_providers_cuda_plugin.cmakeonnxruntime_providers_cuda.rcinto the plugin DLL on Windows so the packaged binary carries version info; setSKIP_BUILD_RPATHon Linux so the build machine's CUDA path is not embedded in a binary that ships as-isplugin-linux-cuda-stage.yml.sohas an emptyRPATH/RUNPATHcomponent or a hard-coded CUDA pathplugin-win-cuda-stage.ymlTesting
Pipeline changes are validated by running the CUDA plugin packaging pipeline. Both new parameters default to current behavior (
enable_cuda_fatbin_size_compression: false,enable_fpa_intb_gemm: true), so a default run produces the same build flags as before this PR aside from the architecture list changes.The cmake
-compress-modeselection logic was verified in isolation across four combinations:-Xfatbin=-compress-all-Xfatbin=-compress-all -compress-mode=size-Xfatbin=-compress-all -compress-mode=sizeThe new RPATH and DLL version-info checks are self-verifying: they fail the packaging stage rather than publishing a bad artifact.
Motivation and Context
The primary consumer is Foundry Local (vision, audio, and mostly LLM models), which ships this plugin to end-user machines, so download size matters directly.
Trade-offs worth flagging for reviewers:
-compress-mode=sizeraises the minimum driver to the CUDA 12.4 level (Linux >= 550.54.14, Windows >= 551.61); older drivers cannot decompress the fatbin at all. It also increases module load time (measured ~0.8 ms to ~4.3 ms for a ~6.5 MB SASS module) and adds a few percent to nvcc time. This is why the parameter defaults tofalseand is opt-in per run.-realwith no virtual entry, so any GPU whose compute capability is not explicitly listed getscudaErrorNoKernelImageForDevice(209) instead of falling back to JIT. This is deliberate given the PTX cost, but it means new architectures must be added explicitly.enable_fpa_intb_gemm: falseis not yet validated end to end. The fpA_intB path is opt-in at run time viaORT_FPA_INTB_GEMM/ep.cuda.fpa_intb_gemm, butmatmul_nbits.ccforces it on whenever weights are prepacked, independent of that flag. The fallback path should be exercised before shipping a package built with this off.Checklist