Split from #12426, per @tdavidovicNV's request there (comment). This is deliverable [2].
Ask
Add the missing _cuda_sm_x_y capability atoms so Slang can name current CUDA architectures. The set reported by a recent NVRTC (12.6, cross-checked against nvcc --list-gpu-arch) but not representable today: 7.2, 7.5, 8.6, 8.7, 8.9, 10.0, 10.3, 11.0, 12.0, 12.1 (plus 5.2, 5.3, 6.1, 6.2 for completeness — see note). Today source/slang/slang-capabilities.capdef defines 11 _cuda_sm_* atoms.
⚠️ Fold in a pre-existing bug that lives in the same code path
There is a latent bug that must be fixed in the same change, because adding atoms without fixing it reproduces the bug at every new atom:
The atom→arch mapping is a second table, CASE(CUDASM, ...) in source/slang/slang-code-gen.cpp:627-636, which currently has only 9 rows against the 11 defined atoms — _cuda_sm_3_5 and _cuda_sm_8_9 have no row. Because _cuda_sm_8_9 : _cuda_sm_8_0, a request for _cuda_sm_8_9 silently falls back to the _cuda_sm_8_0 row:
slangc … -capability cuda_sm_8_9 → .target sm_80 (want sm_89)
No diagnostic. Verified byte-identical to the cuda_sm_8_0 output; cuda_sm_9_0 correctly gives sm_90, so the mapping does discriminate — 8_9 genuinely resolves to 8_0. Every atom added in this issue needs its matching CASE row, or it silently degrades the same way.
Regression test to add (the coverage gap that let this hide)
Of the ~90 tests that pass -capability cuda_sm_*, none asserts anything about the emitted -arch / .target, which is why the 8_9 mis-map went unnoticed. Add a test that pins the emitted .target from a bare -capability on a shader with no cooperative-matrix / FP8 content.
That last constraint matters: the existing tests/cooperative-matrix/fp8-cuda.slang emits sm_89 via a different producer — slang-emit-cuda.cpp calls requireSMVersion(8,9) for FP8 elements, bypassing the CASE table entirely. Removing -capability from that test leaves the output byte-identical, so it does not guard this path. The regression test must exercise the CASE-table path, not the emit-tracker path.
One open design question (maintainers)
Capability atom enum values are assigned by declaration order (tools/slang-capability-generator/capability-generator-main.cpp), and atoms are serialized into .slang-module files as bit positions in that ordering (via UIntSetVal). So inserting new atoms mid-list changes the meaning of bytes in existing modules. Decision needed: append-only placement, or accept module invalidation on renumber? (The only unconditional cross-version guard today is a single flat kSupportedSerializationVersion; the build-tag digest is opt-in.)
Note on completeness
The originally-listed set omits 5.2 / 5.3 / 6.1 / 6.2, which that same NVRTC also reports; worth adding for the "complete vocabulary" goal. Newer entries (8.8, 10.0, 10.3, 11.0, 12.0, 12.1) can't be validated against NVRTC 12.6 locally — expected, they're newer architectures.
🤖 Filed by an automated Slang coworker at @tdavidovicNV's request on #12426 — a human maintainer should verify.
Split from #12426, per @tdavidovicNV's request there (comment). This is deliverable [2].
Ask
Add the missing
_cuda_sm_x_ycapability atoms so Slang can name current CUDA architectures. The set reported by a recent NVRTC (12.6, cross-checked againstnvcc --list-gpu-arch) but not representable today: 7.2, 7.5, 8.6, 8.7, 8.9, 10.0, 10.3, 11.0, 12.0, 12.1 (plus 5.2, 5.3, 6.1, 6.2 for completeness — see note). Todaysource/slang/slang-capabilities.capdefdefines 11_cuda_sm_*atoms.There is a latent bug that must be fixed in the same change, because adding atoms without fixing it reproduces the bug at every new atom:
The atom→arch mapping is a second table,
CASE(CUDASM, ...)insource/slang/slang-code-gen.cpp:627-636, which currently has only 9 rows against the 11 defined atoms —_cuda_sm_3_5and_cuda_sm_8_9have no row. Because_cuda_sm_8_9 : _cuda_sm_8_0, a request for_cuda_sm_8_9silently falls back to the_cuda_sm_8_0row:No diagnostic. Verified byte-identical to the
cuda_sm_8_0output;cuda_sm_9_0correctly givessm_90, so the mapping does discriminate —8_9genuinely resolves to8_0. Every atom added in this issue needs its matchingCASErow, or it silently degrades the same way.Regression test to add (the coverage gap that let this hide)
Of the ~90 tests that pass
-capability cuda_sm_*, none asserts anything about the emitted-arch/.target, which is why the8_9mis-map went unnoticed. Add a test that pins the emitted.targetfrom a bare-capabilityon a shader with no cooperative-matrix / FP8 content.That last constraint matters: the existing
tests/cooperative-matrix/fp8-cuda.slangemitssm_89via a different producer —slang-emit-cuda.cppcallsrequireSMVersion(8,9)for FP8 elements, bypassing theCASEtable entirely. Removing-capabilityfrom that test leaves the output byte-identical, so it does not guard this path. The regression test must exercise theCASE-table path, not the emit-tracker path.One open design question (maintainers)
Capability atom enum values are assigned by declaration order (
tools/slang-capability-generator/capability-generator-main.cpp), and atoms are serialized into.slang-modulefiles as bit positions in that ordering (viaUIntSetVal). So inserting new atoms mid-list changes the meaning of bytes in existing modules. Decision needed: append-only placement, or accept module invalidation on renumber? (The only unconditional cross-version guard today is a single flatkSupportedSerializationVersion; the build-tag digest is opt-in.)Note on completeness
The originally-listed set omits 5.2 / 5.3 / 6.1 / 6.2, which that same NVRTC also reports; worth adding for the "complete vocabulary" goal. Newer entries (8.8, 10.0, 10.3, 11.0, 12.0, 12.1) can't be validated against NVRTC 12.6 locally — expected, they're newer architectures.
🤖 Filed by an automated Slang coworker at @tdavidovicNV's request on #12426 — a human maintainer should verify.