Skip to content

Follow standard CMake semantics for CUDA architecture suffixes#29601

Open
Sammy-Dabbas wants to merge 2 commits into
microsoft:mainfrom
Sammy-Dabbas:fix/cuda-arch-suffix-semantics
Open

Follow standard CMake semantics for CUDA architecture suffixes#29601
Sammy-Dabbas wants to merge 2 commits into
microsoft:mainfrom
Sammy-Dabbas:fix/cuda-arch-suffix-semantics

Conversation

@Sammy-Dabbas

Copy link
Copy Markdown
Contributor

Description

setup_cuda_architectures in cmake/external/cuda_configuration.cmake was non-standard in two ways (#29598): only the last -virtual entry was kept, so 86-virtual;120-virtual dropped PTX for 8.6; and a suffix-less arch like 86 became 86-real only, dropping its virtual arch.

This tracks real and virtual architectures in separate lists. A suffix-less arch enables both (standard CMake: 86 gives 86-real and 86-virtual), -real/-virtual entries are kept as given, and all -virtual entries are preserved. The accelerated a and family-code f handling apply to both, and CMAKE_CUDA_ARCHITECTURES_ORIG is the deduplicated union.

Motivation and Context

Fixes #29598. Thanks @cschreib-ibex for the reference patch; this builds on it, fixing that its -virtual regex only matched even digit counts (so 100-virtual/120-virtual fatal-errored) and predated the f family branch. Verified the list logic with a cmake -P harness; nvcc compilation should be confirmed by CI.

setup_cuda_architectures kept only the last -virtual entry and dropped
PTX for suffix-less architectures, so 86-virtual;120-virtual embedded
PTX for 12.0 only and bare 86 became 86-real without a virtual arch.
Track real and virtual architectures in separate lists: a suffix-less
arch enables both real and virtual (standard CMake), every -virtual
entry is preserved, and the accelerated (a) and family-code (f) handling
apply to both. CMAKE_CUDA_ARCHITECTURES_ORIG becomes the deduplicated
union so PTX-enabled archs also get their SM-specific kernels.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes ONNX Runtime’s CUDA architecture normalization in setup_cuda_architectures to follow standard CMake semantics, ensuring both SASS (-real) and PTX (-virtual) handling is correct and that multiple -virtual entries are preserved (fixing #29598).

Changes:

  • Split normalization into separate “real” and “virtual” cleaned lists so multiple -virtual entries are retained.
  • Make suffix-less architectures (e.g., 86) enable both 86-real and 86-virtual as standard CMake does.
  • Normalize accelerated (a) and family (f) handling across both real and virtual variants and expose the deduplicated union via CMAKE_CUDA_ARCHITECTURES_ORIG.

Comment thread cmake/external/cuda_configuration.cmake Outdated
set(CMAKE_CUDA_ARCHITECTURES_LAST_VIRTUAL ${CUDA_ARCH})
if(CUDA_ARCH MATCHES "^(([1-9])([0-9])+[af]?)-virtual$")
list(APPEND CMAKE_CUDA_ARCHITECTURES_VIRTUAL_CLEAN ${CMAKE_MATCH_1})
elseif(CUDA_ARCH MATCHES "^(([1-9])([0-9])+)[af]?-real$")
endif()
endforeach()

set(CMAKE_CUDA_ARCHITECTURES ${CMAKE_CUDA_ARCHITECTURES_NORMALIZED})
@cschreib-ibex

Copy link
Copy Markdown
Contributor

Thanks for writing the PR.

FYI I also discovered today that the logic of forcing all "accelerated" archs (90, 100, 101, 110, 120) to the *a-virtual/*a-real architecture family, which is also non-standard, can be problematic because these architectures are not forward compatible. See CUDA docs:

Application binaries that include PTX version of kernels with architecture conditional features using sm_100a or compute_100a in order to take full advantage of Blackwell GPU architecture, are not forward or backward compatible. For example, PTX compiled for compute_90a (Hopper) are not supported on the Blackwell architecture.

So for example, if you select 120-virtual in CMake, this will be turned into 120a-virtual for onnxruntime, and the embedded PTX will not be forward compatible with newer GPUs. If this is the only virtual architecture in the list, effectively this means the resulting binaries will not work on newer GPUs.

At present this can be circumvented by adding at least one "non-accelerated" virtual architecture (e.g., 89-virtual) to the list.

The setup_cuda_architectures macro forced the accelerated `a` suffix
onto virtual (PTX) architectures. Architecture-conditional PTX built
as compute_XXa is not forward compatible, so a selected 120-virtual
became 120a-virtual and its embedded PTX would not JIT onto newer
GPUs. Drop the accel branch in the virtual normalization loop so
virtual archs keep the user-specified variant. Real (SASS)
architectures still use the `a` suffix because the ORT kernels need
the accelerated features such as WGMMA and TMA, and SASS never JITs
forward regardless, so this costs no forward compatibility.

Fix the -real regex so the optional family or accel suffix sits
inside the capture group. The previous pattern left [af] outside the
group, so 100f-real captured only 100 and was rewritten to
100a-real, silently dropping the family code. It now mirrors the
-virtual branch and yields 100f.

Deduplicate the normalized architecture list. A suffix-less family
code such as 100f is pushed onto both the real and virtual clean
lists, and both loops emit a bare 100f, which produced a duplicate
in the final output.
@Sammy-Dabbas

Copy link
Copy Markdown
Contributor Author

Thanks for catching this. The a-forcing on virtual architectures was introduced by this PR through the new virtual normalization loop, I have removed it, so a plain 120-virtual stays a 120-virtual and its compute_120 PTX remains forward compatible via JIT on newer GPUs. The a-forcing on real architectures is kept because the ORT kernels need the accelerated SASS features such as WGMMA and TMA, and SASS is architecture specific anyway, so this does not cost any forward compatibility that PTX would otherwise provide. The fix only stops auto adding the a suffix. An explicit Xa-virtual is preserved unchanged, so the accelerated PTX variant is still available when it's requested directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Build] CMake variable CMAKE_CUDA_ARCH interpretation is not standard

3 participants