Skip to content

[build] #1171 part 1: default multi-arch CUDA build does emit sm_80 SASS on master — mechanism needs re-diagnosis, and CI never covers the default path #1177

Description

@yingjerkao

Split out from part 1 of #1171 (part 2 — unchecked kernel launches — is fixed by
#1175). Filing this as its own issue because the mechanism #1171 proposed does
not reproduce on current master, so "part 1" needs re-diagnosis before
anyone changes the architecture default.

#1171 was explicit that section 1 was a hypothesis rather than a diagnosis, and
that two variables changed between the failing and passing builds. This is that
verification.

What #1171 part 1 claimed

Neither CUDA_SEPARABLE_COMPILATION nor CUDA_RESOLVE_DEVICE_SYMBOLS is set
anywhere in the repo, so the lto_XX IR is never linked into SASS. The result
is a binary containing, for sm_80, neither SASS nor PTX — nothing the driver
can run.

What actually happens on master

1. Device symbol resolution has been enabled since 2023.
CytnxBKNDCMakeLists.cmake:252-255 sets both properties on the cytnx target:

set_target_properties(cytnx PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(cytnx PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)

Added in ec9af22f (2023-09-10), so this predates #1171 rather than being a
recent fix.

2. The device-link step is generated. A stock default-architecture configure
(-DUSE_CUDA=ON -DBUILD_PYTHON=OFF -DCMAKE_BUILD_TYPE=Debug, no arch override)
produces CMakeFiles/cytnx.dir/dlink.txt containing:

-dlink -dlto
--generate-code=arch=compute_75,code=[sm_75]
--generate-code=arch=compute_80,code=[sm_80]
--generate-code=arch=compute_86,code=[sm_86]
--generate-code=arch=compute_89,code=[sm_89]
--generate-code=arch=compute_90,code=[compute_90,sm_90]

Note code=[sm_XX] — real SASS, not lto_XX.

3. That step really does produce per-architecture SASS. Compiling a kernel
with the exact lto_XX flags CMake emits, then device-linking with the exact
dlink.txt flags:

$ nvcc -dc --generate-code=arch=compute_75,code=[lto_75] ... -c t.cu -o t.o
$ nvcc -dlink -dlto --generate-code=arch=compute_75,code=[sm_75] ... t.o -o t_dlink.o
$ cuobjdump -lelf t_dlink.o
ELF file    1: lto.sm_75.cubin
ELF file    2: lto.sm_80.cubin
ELF file    3: lto.sm_86.cubin
ELF file    4: lto.sm_89.cubin
ELF file    5: lto.sm_90.cubin

sm_80 SASS is present. The "neither SASS nor PTX for sm_80" mechanism does
not hold here.

Environment: CUDA 13.0.88 (same major as #1171), CMake 4.0.2, RTX 4070 Ti
SUPER. #1171 used CMake 3.28.3 on A100 — see the open question below.

The cache observation is real but benign

CMAKE_CUDA_ARCHITECTURES:STRING=75 in the cache is reproducible, but it is
intended and harmless:

  • enable_language(CUDA) (CMakeLists.txt:270) writes CMake's own toolchain-aware
    default into the cache. The comment at :265-269 explains why that call has to
    come first.
  • CMakeLists.txt:280 then sets a normal variable that shadows the cache for
    the directory scope, which is what reaches the compile line.
  • Nothing in the repo consumes the cache entry — CytnxConfig.cmake.in does not
    reference architectures, and the only other reader is ci-gpu_tests.yml, which
    passes its own -D.

So it misleads someone inspecting CMakeCache.txt by hand, but it does not affect
what is built. Worth at most a clarifying comment, not a fix.

What is confirmed actionable

Section 3 of #1171 stands, and is the part worth doing:
ci-gpu_tests.yml:49,82 pins GPU_CUDA_ARCH: ${{ vars.GPU_CUDA_ARCH || '89' }}
and builds with -DCMAKE_CUDA_ARCHITECTURES="$GPU_CUDA_ARCH", so CI never
exercises the default multi-arch path that ordinary users get.
Adding a job (or
a periodic one, since the full fat-binary build is slow) that configures with no
architecture override and at minimum checks the emitted codegen would catch a
regression here automatically — and would have settled this question without
anyone reproducing by hand.

Open question

The failure in #1171 was real: every GPU kernel returned zeros on sm_80, and
-DCMAKE_CUDA_ARCHITECTURES=80 fixed it. That still wants an explanation, since
the proposed mechanism does not survive the check above. Remaining candidate
variables:

Please do not "fix" this by changing the architecture default

Changing CMAKE_CUDA_ARCHITECTURES at CMakeLists.txt:280 alters which SASS
ships to every user, and the current list is deliberate (the CUDA 13 sm_75 floor
at :275-278 is load-bearing). Until the mechanism is confirmed, a change there
would be a guess with wide blast radius.

Suggested order of work

  1. Reproduce on CMake 3.28.3 — check whether dlink.txt is generated at all.
  2. If it is not, raise cmake_minimum_required and close this out.
  3. Independently, add the CI job that builds the default multi-arch path.

Reproducing the check above

cmake -S . -B /tmp/archtest -DUSE_CUDA=ON -DUSE_CUTENSOR=OFF -DUSE_CUQUANTUM=OFF \
      -DBUILD_PYTHON=OFF -DUSE_HPTT=OFF -DCMAKE_BUILD_TYPE=Debug
cat /tmp/archtest/CMakeFiles/cytnx.dir/dlink.txt   # expect code=[sm_XX]

Relates to #1171 (part 1); part 2 fixed by #1175.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    CI/CDCI/CD related issuescompile/buildissues related to compiling/building processesgpu

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions