Repository navigation
[Common] Add launch bounds to multi-tensor swizzle kernels - #3622
Merged
Merged
Conversation
The multi-tensor swizzle and unswizzle kernels launch with TB_DIM x TB_DIM (1024) threads but, unlike the other swizzle kernels, had no __launch_bounds__. ptxas could then use more than 64 registers per thread (up to 99 for the int4 variants), which makes the launch fail with "too many resources requested for launch". Which variants fail depends on the target arch and CUDA version. Add __launch_bounds__(TB_DIM * TB_DIM) to the four kernels and add test shapes that reach the rowwise int2 and columnwise int4 variants. Fixes NVIDIA#3621 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Ravi M <ravitejamajeti@gmail.com>
ravimajeti
marked this pull request as ready for review
October 4, 2026 01:52
Contributor
|
ptrendx
approved these changes
Oct 5, 2026
Member
|
/te-ci core |
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
The multi-tensor swizzle and unswizzle kernels in
common/swizzle/swizzle.culaunch withTB_DIM x TB_DIM(1024) threads per block. Every other swizzle kernel has__launch_bounds__(TB_DIM * TB_DIM), added in #2076, but these four don't. Without the bound, ptxas doesn't cap registers at 64 per thread, and some variants use up to 99. 1024 threads x more than 64 registers is more than a block can have, so the launch fails withtoo many resources requested for launch.Which variants fail depends on the target arch and the CUDA version, because the register count does. Measured with
cuobjdump --dump-resource-usage(registers per thread; more than 64 can't launch with 1024 threads):multi_tensor_swizzle_row_scaling_kernel<int4>multi_tensor_swizzle_row_scaling_kernel<int2>multi_tensor_swizzle_col_scaling_kernel<int4>With this PR, every multi-tensor (un)swizzle variant is at most 64 registers on all six configurations, with no spills (
STACK:0,LOCAL:0).Fixes #3621
Type of change
Changes
common/swizzle/swizzle.cu: add__launch_bounds__(TB_DIM* TB_DIM)tomulti_tensor_swizzle_{row,col}_scaling_kernelandmulti_tensor_unswizzle_{row,col}_scaling_kernel, matching the other swizzle kernels.tests/cpp/operator/test_multi_swizzle.cu: add two shapes tomulti_tensor_test_cases, which is shared by the swizzle, unswizzle and roundtrip suites. Before this, no test reached therow<int2>orcol<int4>variants:{2, 128, 4352, true}: rowwisenum_tiles_k = 34, which selectsvec_load_size = 2.{2, 512, 4096, false}: columnwisenum_tiles_k = 4, which selectsvec_load_size = 4.num_tiles_m = 32, so it isn't the narrow-M path.Testing
RTX 5090 (SM 12.0), CUDA 12.8,
NVTE_FRAMEWORK=pytorch NVTE_CUDA_ARCHS=120,main@ 5759fa0:main+ new teststest_operator --gtest_filter='*wizzle*'too many resources requested for launch)tests/pytorch/test_weight_swizzle_in_layers.pyThe 5 failures on
mainaren2_M128_K1024_row,n3_M256_K4096_rowandn2_M128_K8192_row, which already exist, plus the two new shapes.n2_M128_K1024_rowis meant to cover the narrow-K kernel. It needs 128 KB of shared memory, so on a GPU with 99 KiB the dispatcher falls back to the regular multi-tensor kernel, which then fails to launch.The register numbers for sm_90 and sm_100 are from compile-only builds of
swizzle.cuwith the TE build flags. I don't have an H100 or B200, so I haven't run the tests there. Based on the register counts, a CUDA 12.8 build on those GPUs should fail the existingK4096/K8192rowwise cases.pre-commit passes on both changed files.
Performance
RTX 5090, CUDA 12.8. I benchmarked two copies of
libtransformer_engine.so(mainand this PR) with the same binary that callsnvte_multi_tensor_{,un}swizzle_scaling_factors, alternating between them for 3 rounds each. GPU time is 200 calls captured in a CUDA graph and replayed, divided by 200, taking the median of 7 repeats. Run-to-run spread is ≤ 0.01 µs.mainGPU µsrow<int>row<int>row<int2>row<int4>col<int>col<int2>col<int2>col<int4>row<int>row<int4>col<int2>col<int4>For variants that already launched, GPU time changes by −1.4% to +2.7% (at most 0.13 µs), in both directions. With host launch overhead included (back-to-back calls without a graph), each call takes 4–8 µs and is unchanged. The scales stay in L2 across repeated calls, so these are L2-resident timings. Clocks were not locked.
Checklist:
🤖 Generated with Claude Code