Migrate norms and softmax kernels to NVRTC - #3156
Conversation
4e8d10a to
5235723
Compare
|
/te-ci pytorch |
Greptile SummaryThis PR migrates norm (LayerNorm / RMSNorm) and softmax kernels from ahead-of-time NVCC compilation to JIT compilation via NVRTC, reducing the
Confidence Score: 5/5Safe to merge — the migration is well-contained, the thread-safety model is sound, and the static fallback escape hatches provide a reliable rollback path. The KernelManager locking upgrade is correctly implemented and resolves the prior TOCTOU concern. All dispatch paths correctly handle the NVRTC-disabled case. The only finding is a dead needs_cooperative capture in register_launcher, which has no behavioral impact. transformer_engine/common/normalization/rtc_dispatch.cpp — the register_launcher helper carries a dead needs_cooperative parameter/capture that can be cleaned up, but does not affect correctness. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Kernel dispatch call] --> B{NVRTC enabled?}
B -- No --> C{Static fallback registered?}
C -- Yes --> D[Call static fallback fn ptr]
C -- No --> E[NVTE_ERROR: rebuild with NVTE_BUILD_LEGACY_STATIC_NORM]
B -- Yes --> F[KernelManager::is_compiled? shared_lock]
F -- No --> G[KernelManager::compile unique_lock + double-check]
G --> H[nvrtcCreateProgram with extra_headers]
H --> I[nvrtcCompileProgram with extra_options]
I --> J[Cache Kernel in kernel_cache_]
F -- Yes --> K[configure_params?]
J --> K
K -- Yes --> L[occupancy_max_active_blocks_per_sm shared_lock]
L --> M[Set ctas_per_col, barrier_bytes, workspace_bytes]
K -- No --> N{ctas_per_row == 1?}
N -- Yes --> O[launch shared_lock cuLaunchKernel]
N -- No --> P[launch_cooperative shared_lock cuLaunchCooperativeKernel]
P --> Q[For bwd: also launch finalize kernel]
O --> Q
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Kernel dispatch call] --> B{NVRTC enabled?}
B -- No --> C{Static fallback registered?}
C -- Yes --> D[Call static fallback fn ptr]
C -- No --> E[NVTE_ERROR: rebuild with NVTE_BUILD_LEGACY_STATIC_NORM]
B -- Yes --> F[KernelManager::is_compiled? shared_lock]
F -- No --> G[KernelManager::compile unique_lock + double-check]
G --> H[nvrtcCreateProgram with extra_headers]
H --> I[nvrtcCompileProgram with extra_options]
I --> J[Cache Kernel in kernel_cache_]
F -- Yes --> K[configure_params?]
J --> K
K -- Yes --> L[occupancy_max_active_blocks_per_sm shared_lock]
L --> M[Set ctas_per_col, barrier_bytes, workspace_bytes]
K -- No --> N{ctas_per_row == 1?}
N -- Yes --> O[launch shared_lock cuLaunchKernel]
N -- No --> P[launch_cooperative shared_lock cuLaunchCooperativeKernel]
P --> Q[For bwd: also launch finalize kernel]
O --> Q
Reviews (9): Last reviewed commit: "Merge branch 'main' into cgomes/nvrtc-ph..." | Re-trigger Greptile |
700a1eb to
b909589
Compare
|
/te-ci pytorch |
ptrendx
left a comment
There was a problem hiding this comment.
Generally OK. One general comment is that with this move to NVRTC we could actually expand the tuned kernel coverage not just to those predetermined cases, but also to other row lengths (previously we did not want to do that just because of the binary size and the compilation time). This should give a good benefit, since the general kernel is not very efficient compared with the tuned one. I'm not sure even if there is even a need for the general kernel (apart from the very long row lengths that would not fit) in that case.
I did consider this, but we also rely on the registration for the optimal launch parameters, for different shapes / archs right? I think its a cool idea but would probably defer it to a separate PR |
|
/te-ci |
|
Generally speaking the tuning should not be difficult, but I agree that this can be done in a subsequent PR. |
5da6586 to
9772be5
Compare
|
/te-ci |
|
/te-ci |
Move the fused-softmax and LayerNorm/RMSNorm kernels from build-time template
instantiation to runtime NVRTC compilation, with full coverage of the existing
kernel set so the NVRTC path is the default.
Fused softmax:
- RTC compile/launch path for scaled / scaled-masked / scaled-upper-triangular /
scaled-aligned-causal softmax, keyed by dtype, shape and mask/causal mode.
- NVTE_BUILD_LEGACY_STATIC_FUSED_SOFTMAX (default OFF) restores the static
template dispatch.
Normalization (LayerNorm + RMSNorm, forward + backward):
- Replace the static REGISTER_NORM_LAUNCHER template fanout with an NVRTC
registry that compiles the selected (norm type, direction, dtypes, hidden size,
CTA config) kernel on first use and caches it.
- NVTE_BUILD_LEGACY_STATIC_NORM (default OFF) restores the static launchers.
- NVRTC-safe kernel sources: kernel sources/headers avoid common.h under
__CUDACC_RTC__; add the dtype aliases and a minimal std::is_same/conditional_t
in the RTC build, and replace a zero-length padding array (a GNU extension nvcc
accepts but NVRTC rejects) with a no-padding union specialization.
KernelManager (util/rtc.{h,cpp}) gains occupancy / function-attribute /
cooperative-launch helpers needed by the norm launchers.
Validated on sm_89 (RTX 6000 Ada): full normalization operator suite 192/192,
softmax + NVRTC unit tests pass; libtransformer_engine.so shrinks ~72 MB -> ~65 MB.
On sm_100a the NVRTC norm forward kernel builds where the static instantiation
crashed the compiler.
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
for more information, see https://pre-commit.ci
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
for more information, see https://pre-commit.ci
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
595286d to
c7d875a
Compare
|
/te-ci |
|
/te-ci |
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
Description
Enables JIT compilation through NVRTC for Norm and Softmax kernels.
Reduces TE binary size by 36%, sequential build time by 5% (measured in cpu_user total time, hard to measure real impact due to parallelization, machine specs)
This is the first chunk of work related to #3054 .
The softmax kernels were chosen as they seemed like one of the simplest to migrate, for my understanding of the system.
The norm kernels include
normalization/layernorm/ln_fwd_cuda_kernel.cu, which is one of the heaviest kernel compilations in the build.It is still possible to enable nvcc static compilation through
NVTE_BUILD_LEGACY_STATIC_FUSED_SOFTMAXandNVTE_BUILD_LEGACY_STATIC_NORM, which then allow forNVTE_DISABLE_NVRTC=1to be used during runtime.Build time results:
Measured on RTX 6000 Ada, CUDA 12.8, single arch sm_89, 32-core host. AOT = -DNVTE_BUILD_LEGACY_STATIC_{FUSED_SOFTMAX,NORM}=ON (old behavior); NVRTC = default.
Per TU build time
scaled_masked_softmax.cuscaled_upper_triang_masked_softmax.cuscaled_aligned_causal_masked_softmax.culn_fwd_cuda_kernel.culn_bwd_semi_cuda_kernel.curmsnorm_fwd_cuda_kernel.curmsnorm_bwd_semi_cuda_kernel.cuBinary size
libtransformer_engine.soTotal build time
JIT compilation cost
layernorm_fwdlayernorm_bwdrmsnorm_fwdrmsnorm_bwdscaled_masked_softmax_fwdscaled_masked_softmax_bwdscaled_upper_triang_softmax_fwdscaled_upper_triang_softmax_bwdscaled_aligned_causal_softmax_fwdFixes # (issue)
Type of change
Changes
Please list the changes introduced in this PR:
rtc_dispatch.cppto allow NVRTC to work with the registry used by norms. This is the largest chunk of new code.Checklist: