Skip to content

[blackwell] sm100 kernel port — integration (sub-tasks 1–8, #204) - #250

Draft
Andrewxu313 wants to merge 23 commits into
mainfrom
tairan/blackwell-02-integration
Draft

[blackwell] sm100 kernel port — integration (sub-tasks 1–8, #204)#250
Andrewxu313 wants to merge 23 commits into
mainfrom
tairan/blackwell-02-integration

Conversation

@Andrewxu313

Copy link
Copy Markdown
Contributor

Aggregates the 8 Blackwell (sm_100a / B200) kernel-port sub-tasks of #204 into one integration branch. Individual PRs: #232#239.

What

Fills the SM100 placeholders in batchgen_kernels by porting the Hopper SM90a WGMMA/TMA kernels to pure-Triton or torch._scaled_mm (no torch.matmul/F.linear).

# Sub-task Path
1 setup.py _sm100_extensions infra batchgen_kernels/setup.py
2 recompile 9 generic-CUDA kernels for sm100 batchgen_kernels/setup.py
3 FP8 blockwise GEMM → row-wise _scaled_mm emulation batchgen/moe/grouped_fp8_blockwise_moe.py
4 MXFP4 expert+grouped dispatch → Triton batchgen/moe/fused_wgmma_*.py, gpt_oss_120b model.py
5 QKV projection + RoPE → Triton batchgen_kernels/triton/qkv_proj_rope.py
6 Router GEMM → Triton batchgen_kernels/triton/fused_router_gemm.py
7 INT4 (W4A16) grouped GEMM → Triton batchgen_kernels/triton/int4_grouped_gemm.py
8 Fused INT4 + SiLU → Triton batchgen_kernels/triton/fused_int4_grouped_silu.py

Verified on B200 (torch 2.9.0+cu129, sm_100)

Combined integration smoke: all Triton exports import together; is_int4_grouped_wgmma_available() / is_qkv_wgmma_available() return True without loading any _C_* extension; FP8 grouped path produces finite output. Per-sub-task accuracy (vs torch reference): FP8 rel 0.0039, MXFP4 grouped bit-exact, router ~5e-5, INT4 ~0.3%, INT4+SiLU ~0.5%.

Notes

  • Sub-task 3: cuBLAS in torch 2.9+cu129 rejects 1x128/128x128 blockwise FP8 on sm100 (CUBLAS_STATUS_NOT_SUPPORTED); the shipped path emulates blockwise exactly via per-128-K-block row-wise _scaled_mm + fp32 accumulation, CUDA-graph compatible. See spec § Sub-task 3.
  • Spec + progress tracker: batchgen_design/blackwell/blackwell-kernel-port-v1.md (metadata repo).

Closes #204 once merged.

v-tairan Copilot user and others added 23 commits May 30, 2026 09:24
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Placeholder commit for draft PR. Implementation tracked in:
batchgen-agent-metadata/batchgen_design/blackwell/blackwell-kernel-port-v1.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ic kernels

setup.py:
- Add _sm100_flags (-arch=sm_100a, -O3, --use_fast_math) and _sm100_extensions
  list containing the 8 generic-CUDA / SM80-mma.sync extensions that are
  SM100-portable (no SM90a WGMMA/TMA): marlin_grouped_gemm (carries
  -DUSE_BF16_COMPUTE), fp8_blockwise_ops, marlin_transform, _C_routing
  (generic kernels only), dispatch_scatter_3d, fused_kv_norm_rope,
  fused_q_absorb, fused_q_split.
- Wire assembly: if _build_sm90a / elif _build_sm100 / always _sm80.
- WGMMA sources (fused_gate.cu, qkv_wgmma.cu, glm5 uses generic so kept)
  are excluded from the SM100 routing bundle; glm5_router_gemm.cu is generic
  CUDA (warp-shuffle only) and retained.

routing_extension.cc:
- Guard the WGMMA-backed fused_gate_* pybind bindings behind
  #ifdef BATCHGEN_HAS_FUSED_GATE so the SM100 build (which omits fused_gate.cu)
  does not emit an undefined-symbol import error. SM90a build defines the macro.

Verified: BUILD_ARCH=sm100 builds all 8 extensions; all load on B200 (sm_100).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fills the SM100 placeholder for the fused QKV WGMMA kernel. On Blackwell
the WGMMA .cu is not built, so cuda_qkv_wgmma() dispatches to a pure-Triton
GEMM+split kernel with a standard rotate_half RoPE epilogue matching the
SM90a CUDA convention (out[n1]=x1*c-x2*s, out[n2]=x2*c+x1*s).

- batchgen_kernels/triton/qkv_proj_rope.py: qkv_proj_split, apply_rope_qk,
  qkv_proj_rope
- qkv_wgmma.py: sm100 dispatch branch + availability via Triton
- triton/__init__.py: export new kernels

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On Blackwell the Hopper WGMMA/TMA MXFP4 .cu kernels are not built. Route
both MXFP4 MoE paths to the existing pure-Triton fused_mxfp4_gemm kernels:

- fused_wgmma_expert.py: is_wgmma_available() returns True on sm100 without
  loading _C; fused_mxfp4_expert_forward() dispatches to fused_mxfp4_mlp_forward
- fused_wgmma_grouped.py: is_grouped_wgmma_available() True on sm100;
  new fused_mxfp4_grouped_moe_forward_triton() does a per-expert masked loop
  with fp32 accumulation and slot-specific routing-weight reduction
- model.py _grouped_forward: sm100 branch uses the stacked per-expert weight
  tensors (device-pointer arrays can't be reversed) via the Triton helper

Verified on B200: grouped output bit-exact vs per-token reference; expert
path matches direct Triton call; no _C_*_mxfp4_wgmma import on sm100.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On Blackwell the WGMMA fused-gate .cu is not built. Provide the router
logits GEMM as a pure-Triton kernel and route FusedGateContext through it:

- batchgen_kernels/triton/fused_router_gemm.py: router_gemm_bias(hidden,
  weight, bias) -> logits [N,E] FP32 (FP32 tensor-core accumulation)
- triton/__init__.py: export router_gemm_bias
- cuda_routing.py: FusedGateContext is sm100-aware — stores weight/bias in
  Python, warmup() no-op, forward() runs router_gemm_bias + the generic-CUDA
  gate_topk_softmax (compiled for sm100 in sub-task 2)

Verified on B200: logits FP32, max_abs_err ~5e-5 vs float32 reference;
FusedGateContext top-k indices match reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pure-Triton port of the Hopper WGMMA INT4 grouped MoE GEMM building block.
Matches the SM90a .cu weight layout: w_packed [N, K//2] uint8 (low nibble =
even-K, high nibble = odd-K), scale [N, K//32] bf16, group_size=32, dequant
(nibble-8)*scale. GEMM via even/odd column split + two bf16 tl.dot with FP32
accumulation (avoids in-kernel nibble interleave).

- batchgen_kernels/triton/int4_grouped_gemm.py: int4_grouped_gemm (single
  expert) + int4_moe_grouped_gemm (per-expert sorted-token dispatch)
- triton/__init__.py: export both

Verified on B200: max_abs_err 0.07-0.18 (rel ~0.3%) vs dequant reference,
well under the 0.5 INT4-noise threshold; grouped path matches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lackwell-02-08-int4-fused-silu

# Conflicts:
#	docs/BLACKWELL_KERNELS_WIP.md
Completes the SM100 INT4 MoE expert path on top of sub-task 7's GEMM:

- batchgen_kernels/triton/fused_int4_grouped_silu.py:
  * silu_mul epilogue (silu(gate)*up, FP32 math) matching the SM90a stage-1
  * fused_int4_grouped_silu (stage-1 SwiGLU activation)
  * int4_expert_mlp (full gate+up+SiLU+down expert)
  * int4_grouped_moe_forward (per-expert masked loop, fp32 accumulation,
    slot-specific routing-weight reduction)
- int4_single_expert_wgmma.py: single_expert_int4_forward dispatches to the
  Triton int4_expert_mlp on sm100 (no _C load)
- fused_int4_wgmma_grouped.py: is_int4_grouped_wgmma_available() True on sm100
  via Triton without loading the Hopper _C extension
- triton/__init__.py: export the new kernels

Verified on B200: silu_mul/expert_mlp rel err ~0.4-0.6%; single-expert sm100
dispatch matches int4_expert_mlp; grouped MoE matches per-token reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The compiled SM90a CuTe FP8 blockwise kernel is unavailable on Blackwell,
and cuBLAS in torch 2.9+cu129 rejects 1x128/128x128 blockwise FP8 scaling
(heuristic returns CUBLAS_STATUS_NOT_SUPPORTED; fast-accum unsupported for
1x128). Only row-wise/tensor-wise FP8 GEMM is available.

Add an sm100 branch in grouped_fp8_blockwise_gemm() that emulates deepseek
blockwise scaling exactly: split the K contraction into 128-wide blocks and
issue one row-wise torch._scaled_mm per block, accumulating partials in fp32.
Within a K-block the act scale is constant per row (1x128) and the weight
scale is constant per 128-output-row block (128x128, expanded to per-column),
so the row-wise GEMM is numerically identical to true blockwise for that block.

- Processes the full uniform mtp reserved rows per expert -> static control
  flow, CUDA-graph compatible (no host sync on seqlens, no data-dependent
  shapes). Padding-row outputs are ignored by downstream gather.
- Covers s1 (gate+up), s3 (down) and fused_s1 automatically since all route
  through grouped_fp8_blockwise_gemm (fused_s1 falls back to s1_silu on sm100
  as its _C kernel is absent).
- Dim asserts (K,N multiples of 128; scale shapes) guard silent mis-scaling.

Verified on B200 (GLM-5 / MiniMax-M2.5 style dims, E=4, mtp=64, K=2048,
N=1536, incl. a zero-token expert): GEMM max rel 0.0039, S1+SiLU 0.0056,
fused_s1 matches s1_silu (< 1e-2 acceptance).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lackwell-02-integration

# Conflicts:
#	docs/BLACKWELL_KERNELS_WIP.md
…blackwell-02-integration

# Conflicts:
#	batchgen_kernels/triton/__init__.py
…ckwell-02-integration

# Conflicts:
#	batchgen_kernels/triton/__init__.py
@github-actions github-actions Bot added the ci:run Trigger build + GPU regression on H20 label May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run Trigger build + GPU regression on H20

Projects

None yet

Development

Successfully merging this pull request may close these issues.

blackwell: phase 2 — batchgen_kernels SM100 build path

1 participant