[jit_kernel] Move JIT kernels into namespace sglang - #33400
Merged
Merged
Conversation
DarkSharpness
requested review from
BBuf,
HydraQYH,
JustinTong0323,
Qiaolin-Yu,
celve,
hnyls2002,
kpham-sgl,
mickqian,
sogalin,
wisclmy0611,
yingluosanqian,
yuan-luo and
zijiexia
as code owners
August 3, 2026 14:47
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
DarkSharpness
force-pushed
the
jit-namespace-sglang
branch
from
August 3, 2026 14:54
30feda7 to
6db28a2
Compare
All JIT C++ under python/sglang/kernels/jit/ now lives in `namespace sglang`: device kernels, traits and the host wrapper together, plus the shared include/sgl_kernel/ headers, so `host::` / `device::` resolve unqualified. - `load_jit` emits TVM_FFI_DLL_EXPORT_TYPED_FUNC inside the namespace, so the Python-side `kernel_name` is written without a `sglang::` prefix. - Dropped the 5 `using namespace sglang;` and every redundant `sglang::` qualification. The `sglang_<kernel>` pseudo-namespaces in csrc/diffusion/ become real nesting (`sglang::norm_scale_shift`, ...). - Removed 102 now-redundant top-level anonymous namespaces: `namespace sglang` already scopes these names and each header-only module compiles exactly one root source. - Fixed `::arrive_barrier` in gemm/dsv3_fused_a_gemm.cuh, which resolved to global scope. nvcc defers lookup of non-dependent names in template bodies to instantiation, so a header-include compile did not catch it. Left at global scope on purpose: near-verbatim vendored ports with no sgl_kernel dependency (moe/tvm_ffi_utils.h from FlashInfer, fast-hadamard-transform/, sparse_mla_q8kv8_prefill_sm90/, which needs a global `using namespace cute;` before mid-file includes), and attention/kda_prefill.cu, which builds via torch.utils.cpp_extension rather than load_jit. Two test fixes for pre-existing failures this sweep surfaced on B200: activation drops the hidden=8 shapes the kernel rejects when kMaxVecBytes is 32, and fused_add_rmsnorm's fp32-reference path gets rtol=1.5e-2, since bf16's 1 ulp is 2^-8 and rtol=1e-2 could only express 1.28 ulp. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DarkSharpness
force-pushed
the
jit-namespace-sglang
branch
from
August 4, 2026 16:02
6db28a2 to
979e7c5
Compare
Collaborator
Author
|
/rerun-failed-ci |
b8zhong
added a commit
that referenced
this pull request
Aug 8, 2026
…aled-mm Two upstream changes needed carrying into the JIT port: - #33469 (scalar scale A support for fp8_gemm) landed in the AOT fp8_gemm_kernel.cu that this branch deletes. Ported into the JIT tree: JitGemmFp8RowwiseC3x gains a ScalarA parameter selecting Sm90ScalarBroadcast over Sm90ColBroadcast (one change here covers SM100 and SM120, which upstream had to patch separately), the sm100/sm120 dispatchers branch on scales_a.numel() == 1, SM90 goes back to Sm90ColOrScalarBroadcast with its runtime flag, and the entry point carries upstream's two validation checks. Its tests come along too. - #33400 (move JIT kernels into namespace sglang) postdates these files, so the seven new fp8_per_tensor headers are now wrapped in namespace sglang; without it host:: no longer resolves. Verified on SM103: 1024 passed, 1 skipped (SM89-only test).
This was referenced Aug 10, 2026
Xia-Weiwen
pushed a commit
to Xia-Weiwen/sglang
that referenced
this pull request
Aug 10, 2026
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
saturn-acc
pushed a commit
to saturn-acc/sglang
that referenced
this pull request
Aug 16, 2026
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 18, 2026
jakki-amd
pushed a commit
to jakki-amd/sglang
that referenced
this pull request
Sep 9, 2026
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Atituiset
pushed a commit
to Atituiset/sglang
that referenced
this pull request
Sep 10, 2026
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Motivation
Every JIT kernel used to sit in the global namespace (or an anonymous one), with a handful of files having already started on
namespace sglangand reaching back out viausing namespace sglang;/sglang::. This unifies that: all JIT C++ underpython/sglang/kernels/jit/now lives innamespace sglang, and nosglang::qualification is needed anywhere inside it.Modifications
namespace sglangeverywhere — device kernels, traits and the host wrapper together, plus the sharedinclude/sgl_kernel/headers, sohost::/device::resolve unqualified. 166 C++ files.load_jitemits the export inside the namespace —_make_sourceswrapsTVM_FFI_DLL_EXPORT_TYPED_FUNCinnamespace sglang { ... }, so the Python-sidekernel_nameis written without a prefix (Add3Kernel<...>::launch, notsglang::Add3Kernel<...>::launch).using namespace sglang;and every redundantsglang::. Thesglang_<kernel>pseudo-namespaces undercsrc/diffusion/become real nesting (sglang::norm_scale_shift,sglang::usp_relayout, ...), with the Python wrapper names updated to match.namespace sglangalready scopes these names, symbols are not interposed across separatelydlopened modules, and each header-only module compiles exactly one root source. One consequence needed handling:gemm/per_token_group_quant.cuh's file-localdetailsbecame ambiguous withdevice::detailsonce the anonymous namespace stopped isolating it, so it is nowdetail.::arrive_barrieringemm/dsv3_fused_a_gemm.cuh— it resolved to global scope while the function moved intonamespace sglang. See the note below on why this one was easy to miss.add-jit-kernelskill note the namespace convention.Deliberately left at global scope
csrc/moe/tvm_ffi_utils.hsgl_kerneldependencycsrc/fast-hadamard-transform/*.hcsrc/sparse_mla_q8kv8_prefill_sm90/*(7 files)kernel.cuhneeds a globalusing namespace cute;before mid-file#includes of thedense_fp8headers, which cannot survive wrapping. Only itsentry.cuhhost wrapper moved in.csrc/attention/kda_prefill.cutorch.utils.cpp_extension, notload_jitcsrc/moe/expert_specialization/*(4 files)load_jitcall — the live path is the AOT twin inaot/csrc/expert_specialization/Accuracy Tests
All 137 kernel test files were run on 8x B200, one test per GPU across 7 cards.
The sweep caught a real bug.
::arrive_barrierbroketest_dsv3_fused_a_gemm(192 failed), and a header-include-only compile did not catch it: nvcc defers lookup of non-dependent names inside template bodies until instantiation. After the fix it is 192 passed. I then scanned every::identifierin the tree — the rest are genuinely global (cuda*,atomicAdd,min/max/abs,TVMFFI*) ordecltype(...)::valuefalse hits.Multi-GPU (via each file's own torchrun entry point, world sizes <= 6):
test_custom_all_reduce --num-gpu 2,4test_tp_qknorm --num-gpu 2,4test_symm_mem_all_gather --num-gpu 4,6kimi_k3/test_collectives --num-gpu 4test_dcp_lse_combineRemaining failures were each re-run against
HEADin a separate worktree and are pre-existing with identical failure sets:test_per_token_group_quant_8bit_v2(66, JIT-vs-AOT bit-exactness on B200),test_qknorm_rope(1/1249 bf16 rounding),test_dsa_indexer(MockModelRunnermissing an attribute),test_kernels_namespace(assert 'CLEAN' in 'DIRTY', local env),test_varlen_uspattn_equivalence(localflash_attnmissingflash_attn_varlen_func), and the two CP parity tests (need multi-GPU).Two pre-existing test failures fixed along the way
Both are B200-only, because the JIT kernel CI runs on H100/H200 and never exercises the Blackwell branch of
kMaxVecBytes = SGL_ARCH_BLACKWELL_OR_GREATER ? 32 : 16:test_activation— the(7, 16)/(3, 5, 16)shapes givehidden=8, which the kernel rejects outright when the fp16/bf16 vector is 16 elements wide. Dropped rather than made arch-conditional; every remaining shape is 16-aligned. 24 failed -> 451 passed (97 in CI mode).test_fused_add_rmsnorm— bf16's 1 ulp is2^-8 ~= 7.8e-3, sortol=1e-2expressed only 1.28 ulp while the fp32 reference (which rounds in a different order than the kernel) disagrees by up to 1.75 ulp. The fp32-reference path now usesrtol=1.5e-2, the tightest bound that clears the noise — it still catches a systematic 0.75% deviation, whereas2e-2would let 1% through. No cases removed: 2 failed / 558 passed -> 560 passed.Checklist
pre-commit runclean on the diff (incl. pinned clang-format 20.1.7, CI-registry validation)#ifbranch in every fileCI States
Latest PR Test (Base): ❌ Run #30927242724
Latest PR Test (Extra): ❌ Run #30927233275