瀏覽代碼

fix: sync overlay with madeby561/vllm-glm52-nvfp4-nf3-hybrid:v3

- hybrid_loader.py: v3 (1214 lines, MXFP4 kept tier, stream/bf16 fusion)
- nf3_kernel/replan/nvfp4_kernel/mxfp8_tier.json: unchanged (match v3)
- b12x/moe/fused/w4a16/{kernel,prepare,host}.py: add from v3 (NF3 types)
- b12x/cute/fp4.py: add from v3
- vllm/*/mla/indexer.py: add from v3 (NF3-compatible MLA)
- hybrid.pth: add from overlay
- Remove 3 invalid patches (404 HTML placeholders)
- Keep only b12x-prewarm-tolerance.patch (identical to XanuNetworks)
Alexander Korolev 3 月之前
父節點
當前提交
d8048a2b1d

+ 12 - 6
docker-images/glm52-nf3-hybrid/Dockerfile

@@ -139,12 +139,18 @@ RUN rm -f /usr/local/lib/python3.12/dist-packages/nvidia/nccl/lib/libnccl.so.2 \
       /usr/local/lib/python3.12/dist-packages/nvidia/nccl/lib/libnccl.so.2
 
 # NF3 hybrid overlay
-COPY overlay/hybrid_loader.py  /usr/local/lib/python3.12/dist-packages/hybrid_loader.py
-COPY overlay/nf3_kernel.py     /usr/local/lib/python3.12/dist-packages/nf3_kernel.py
-COPY overlay/nvfp4_kernel.py   /usr/local/lib/python3.12/dist-packages/nvfp4_kernel.py
-COPY overlay/nf3_replan.py     /usr/local/lib/python3.12/dist-packages/nf3_replan.py
-COPY overlay/mxfp8_tier.json   /usr/local/lib/python3.12/dist-packages/mxfp8_tier.json
-RUN python3 -c "open('/usr/local/lib/python3.12/dist-packages/hybrid_loader.pth','w').write('import hybrid_loader\n')"
+COPY overlay/hybrid_loader.py              /usr/local/lib/python3.12/dist-packages/hybrid_loader.py
+COPY overlay/hybrid.pth                    /usr/local/lib/python3.12/dist-packages/hybrid.pth
+COPY overlay/nf3_kernel.py                 /usr/local/lib/python3.12/dist-packages/nf3_kernel.py
+COPY overlay/nvfp4_kernel.py               /usr/local/lib/python3.12/dist-packages/nvfp4_kernel.py
+COPY overlay/nf3_replan.py                 /usr/local/lib/python3.12/dist-packages/nf3_replan.py
+COPY overlay/mxfp8_tier.json               /usr/local/lib/python3.12/dist-packages/mxfp8_tier.json
+COPY overlay/b12x/moe/fused/w4a16/kernel.py  /usr/local/lib/python3.12/dist-packages/b12x/moe/fused/w4a16/kernel.py
+COPY overlay/b12x/moe/fused/w4a16/prepare.py /usr/local/lib/python3.12/dist-packages/b12x/moe/fused/w4a16/prepare.py
+COPY overlay/b12x/moe/fused/w4a16/host.py    /usr/local/lib/python3.12/dist-packages/b12x/moe/fused/w4a16/host.py
+COPY overlay/b12x/cute/fp4.py                 /usr/local/lib/python3.12/dist-packages/b12x/cute/fp4.py
+COPY overlay/vllm/v1/attention/backends/mla/indexer.py \
+      /usr/local/lib/python3.12/dist-packages/vllm/v1/attention/backends/mla/indexer.py
 
 ENTRYPOINT []
 CMD ["bash"]

+ 5524 - 0
docker-images/glm52-nf3-hybrid/overlay/b12x/cute/fp4.py

@@ -0,0 +1,5524 @@
+"""
+Copyright (c) 2025 by FlashInfer team.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Common utilities for FP4 quantization kernels.
+
+This module contains shared PTX intrinsics, helper functions, and reduction
+utilities used by the fused frontend kernels.
+"""
+
+import functools
+import math
+import operator
+from typing import Callable, Tuple
+
+import cutlass
+import cutlass.cute as cute
+import torch
+import torch.nn.functional as F
+from cutlass import Float32, Int32, Int64, Uint8, Uint16, Uint32, Uint64
+from cutlass.cutlass_dsl import T, dsl_user_op
+from cutlass._mlir import ir
+from cutlass._mlir.dialects import llvm
+
+
+# =============================================================================
+# Constants
+# =============================================================================
+
+FLOAT4_E2M1_MAX = 6.0  # Maximum value representable in FP4 E2M1
+FLOAT8_E4M3_MAX = 448.0  # Maximum value representable in FP8 E4M3
+SF_VEC_SIZE = 16  # Elements per scale factor block
+COPY_BITS = 128  # 128-bit vectorized loads
+_FP4_MAG_LUT = (0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0)
+
+
+def align_up(value: int, alignment: int) -> int:
+    return ((value + alignment - 1) // alignment) * alignment
+
+
+def make_swizzle_indices(rows_padded: int, cols_padded: int, device: torch.device) -> torch.Tensor:
+    """Pre-compute swizzle gather indices for FP8 block-scale factors."""
+    numel = rows_padded * cols_padded
+    idx = torch.arange(numel, device=device)
+    idx_5d = idx.reshape(rows_padded // 128, 4, 32, cols_padded // 4, 4)
+    return idx_5d.permute(0, 3, 2, 1, 4).contiguous().reshape(-1)
+
+
+def swizzle_block_scale(scale: torch.Tensor) -> torch.Tensor:
+    if scale.ndim == 2:
+        scale = scale.unsqueeze(0)
+        squeeze_batch = True
+    elif scale.ndim == 3:
+        squeeze_batch = False
+    else:
+        raise ValueError(f"scale must be 2D or 3D, got {tuple(scale.shape)}")
+
+    batch, rows, cols = scale.shape
+    rows_padded = align_up(rows, 128)
+    cols_padded = align_up(cols, 4)
+
+    padded = torch.zeros((batch, rows_padded, cols_padded), dtype=scale.dtype, device=scale.device)
+    padded[:, :rows, :cols] = scale
+    swizzled = padded.reshape(batch, rows_padded // 128, 4, 32, cols_padded // 4, 4)
+    swizzled = swizzled.permute(0, 1, 4, 3, 2, 5).contiguous()
+    swizzled = swizzled.reshape(batch, rows_padded, cols_padded)
+    return swizzled[0] if squeeze_batch else swizzled
+
+
+def as_grouped_scale_view(scale_storage: torch.Tensor, rows: int, cols: int) -> torch.Tensor:
+    batch = scale_storage.shape[0]
+    rows_padded = align_up(rows, 128)
+    cols_padded = align_up(cols // SF_VEC_SIZE, 4)
+    sf = scale_storage.view(torch.float8_e4m3fn)
+    sf = sf.view(batch, rows_padded // 128, cols_padded // 4, 32, 4, 4)
+    return sf.permute(3, 4, 1, 5, 2, 0)
+
+
+def as_grouped_scale_view_mx(scale_storage: torch.Tensor, rows: int, cols: int) -> torch.Tensor:
+    """Grouped UE8M0 scale view for vec32 (MXFP8 w4a8) block scales."""
+    batch = scale_storage.shape[0]
+    rows_padded = align_up(rows, 128)
+    cols_padded = align_up(cols // 32, 4)
+    sf = scale_storage.view(torch.float8_e8m0fnu)
+    sf = sf.view(batch, rows_padded // 128, cols_padded // 4, 32, 4, 4)
+    return sf.permute(3, 4, 1, 5, 2, 0)
+
+
+def _fp4_quantize_values(x: torch.Tensor) -> torch.Tensor:
+    sign = torch.sign(x)
+    x = torch.abs(x.clone())
+    x[(x >= 0.0) & (x <= 0.25)] = 0.0
+    x[(x > 0.25) & (x < 0.75)] = 0.5
+    x[(x >= 0.75) & (x <= 1.25)] = 1.0
+    x[(x > 1.25) & (x < 1.75)] = 1.5
+    x[(x >= 1.75) & (x <= 2.5)] = 2.0
+    x[(x > 2.5) & (x < 3.5)] = 3.0
+    x[(x >= 3.5) & (x <= 5.0)] = 4.0
+    x[x > 5.0] = 6.0
+    return x * sign
+
+
+def fp4_quantize_values_torch(x: torch.Tensor) -> torch.Tensor:
+    """Pure-Torch FP4 E2M1 quantization with kernel-matching tie-breaking."""
+    return _fp4_quantize_values(x)
+
+
+def _fp4_encode_nibbles(values: torch.Tensor) -> torch.Tensor:
+    mags = values.abs()
+    idx = torch.zeros_like(values, dtype=torch.uint8)
+    for code, mag in enumerate(_FP4_MAG_LUT):
+        idx = torch.where(mags == mag, torch.full_like(idx, code), idx)
+    sign_bit = (values < 0).to(torch.uint8) << 3
+    return idx | sign_bit
+
+
+def pack_grouped_fp4_values(values: torch.Tensor) -> torch.Tensor:
+    """Pack grouped FP4 values `[G, R, C]` into uint8 `[R, C/2, G]`."""
+    nibbles = _fp4_encode_nibbles(values)
+    packed = nibbles.view(values.shape[0], values.shape[1], values.shape[2] // 2, 2)
+    packed = packed[..., 0] | (packed[..., 1] << 4)
+    return packed.permute(1, 2, 0).contiguous()
+
+
+def quantize_grouped_nvfp4_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+    global_scale: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    """Pure-Torch grouped NVFP4 quantization with reciprocal global scales."""
+    num_groups, rows, cols = input_tensor.shape
+    if cols % SF_VEC_SIZE != 0:
+        raise ValueError(f"cols must be divisible by {SF_VEC_SIZE}, got {cols}")
+    if global_scale.numel() == 1:
+        global_scale = global_scale.expand(num_groups).contiguous()
+
+    quantized = torch.zeros((num_groups, rows, cols), dtype=torch.float32, device=input_tensor.device)
+    scales = torch.zeros((num_groups, rows, cols // SF_VEC_SIZE), dtype=torch.float32, device=input_tensor.device)
+    for group_idx in range(num_groups):
+        valid_rows = int(row_counts[group_idx].item())
+        if valid_rows == 0:
+            continue
+        x = input_tensor[group_idx, :valid_rows].float()
+        sliced = x.view(valid_rows, cols // SF_VEC_SIZE, SF_VEC_SIZE)
+        block_max = sliced.abs().amax(dim=-1, keepdim=True).to(torch.float32)
+        scale = (global_scale[group_idx] * (block_max / FLOAT4_E2M1_MAX)).to(torch.float8_e4m3fn).to(torch.float32)
+        output_scale = 1.0 / (scale * (1.0 / global_scale[group_idx]))
+        clipped = torch.clamp(sliced * output_scale, -FLOAT4_E2M1_MAX, FLOAT4_E2M1_MAX).view(valid_rows, cols)
+        quantized[group_idx, :valid_rows] = _fp4_quantize_values(clipped)
+        scales[group_idx, :valid_rows] = scale.squeeze(-1)
+
+    packed = pack_grouped_fp4_values(quantized)
+    swizzled = swizzle_block_scale(scales.to(torch.float8_e4m3fn))
+    scale_view = as_grouped_scale_view(swizzled.view(torch.uint8), rows, cols)
+    return packed, scale_view
+
+
+def silu_mul_quantize_grouped_nvfp4_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+    global_scale: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    cols = input_tensor.shape[-1] // 2
+    left = input_tensor[..., :cols].float()
+    right = input_tensor[..., cols:].float()
+    activated = (F.silu(left) * right).to(input_tensor.dtype).to(torch.float32)
+    return quantize_grouped_nvfp4_torch(activated, row_counts, global_scale)
+
+
+def relu2_quantize_grouped_nvfp4_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+    global_scale: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    """Pure-Torch grouped NVFP4 quantization for ReLU^2 FC1 outputs."""
+    activated = torch.square(F.relu(input_tensor.float()))
+    activated = activated.to(input_tensor.dtype).to(torch.float32)
+    return quantize_grouped_nvfp4_torch(activated, row_counts, global_scale)
+
+
+MX_SF_VEC_SIZE = 32  # Elements per UE8M0 scale block (MXFP8 w4a8 activations)
+_INV_FLOAT8_E4M3_MAX = 1.0 / FLOAT8_E4M3_MAX
+
+
+def pow2_ceil_ue8m0_torch(scale: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
+    """Bit-exact Torch replica of the ``pow2_ceil_ue8m0`` device intrinsic.
+
+    Rounds positive fp32 scales UP to a power of two by bumping the exponent
+    whenever the mantissa is nonzero.  Returns ``(rounded_fp32, ue8m0_u8)``;
+    a zero scale maps to (0.0, byte 0).
+    """
+    bits = scale.to(torch.float32).contiguous().view(torch.int32)
+    mant = bits & 0x007FFFFF
+    bumped = torch.where(mant != 0, (bits + 0x00800000) & 0x7F800000, bits)
+    rounded = bumped.view(torch.float32)
+    byte = ((bumped >> 23) & 0xFF).to(torch.uint8)
+    return rounded, byte
+
+
+def _ue8m0_output_scale_torch(byte: torch.Tensor) -> torch.Tensor:
+    """Torch replica of ``ue8m0_to_output_scale``: 2^(127-byte), 0 for byte 0."""
+    inv_bits = (254 - byte.to(torch.int32)).clamp(min=0) << 23
+    inv = inv_bits.view(torch.float32)
+    return torch.where(byte == 0, torch.zeros_like(inv), inv)
+
+
+def quant_dequant_mxfp8_torch(x: torch.Tensor) -> torch.Tensor:
+    """Per-32-block MXFP8 quantize-dequantize roundtrip (oracle helper).
+
+    Matches the in-kernel ``quantize_block_fp8_mx`` numerics bit-for-bit:
+    UE8M0 ceil block scale, E4M3 RN-saturating payload.
+    """
+    orig_shape = x.shape
+    cols = orig_shape[-1]
+    if cols % MX_SF_VEC_SIZE != 0:
+        raise ValueError(f"last dim must be divisible by {MX_SF_VEC_SIZE}, got {cols}")
+    blocked = x.to(torch.float32).reshape(-1, cols // MX_SF_VEC_SIZE, MX_SF_VEC_SIZE)
+    block_max = blocked.abs().amax(dim=-1, keepdim=True)
+    rounded, byte = pow2_ceil_ue8m0_torch(block_max * _INV_FLOAT8_E4M3_MAX)
+    inv = _ue8m0_output_scale_torch(byte)
+    payload = (
+        (blocked * inv)
+        .clamp(-FLOAT8_E4M3_MAX, FLOAT8_E4M3_MAX)
+        .to(torch.float8_e4m3fn)
+        .to(torch.float32)
+    )
+    return (payload * rounded).reshape(orig_shape)
+
+
+def quantize_grouped_mxfp8_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    """Pure-Torch grouped MXFP8 quantization (no global scale).
+
+    Mirrors ``quantize_grouped_nvfp4_torch`` for the w4a8 activation path:
+    returns ``(payload, scale_view)`` where ``payload`` is E4M3 bytes in
+    ``[R, C, G]`` order and ``scale_view`` is the swizzled UE8M0 grouped
+    view (vec32 columns).
+    """
+    num_groups, rows, cols = input_tensor.shape
+    if cols % MX_SF_VEC_SIZE != 0:
+        raise ValueError(f"cols must be divisible by {MX_SF_VEC_SIZE}, got {cols}")
+
+    payload = torch.zeros((num_groups, rows, cols), dtype=torch.uint8, device=input_tensor.device)
+    scales = torch.zeros(
+        (num_groups, rows, cols // MX_SF_VEC_SIZE), dtype=torch.uint8, device=input_tensor.device
+    )
+    for group_idx in range(num_groups):
+        valid_rows = int(row_counts[group_idx].item())
+        if valid_rows == 0:
+            continue
+        x = input_tensor[group_idx, :valid_rows].float()
+        blocked = x.view(valid_rows, cols // MX_SF_VEC_SIZE, MX_SF_VEC_SIZE)
+        block_max = blocked.abs().amax(dim=-1, keepdim=True)
+        rounded, byte = pow2_ceil_ue8m0_torch(block_max * _INV_FLOAT8_E4M3_MAX)
+        inv = _ue8m0_output_scale_torch(byte)
+        q = (
+            (blocked * inv)
+            .clamp(-FLOAT8_E4M3_MAX, FLOAT8_E4M3_MAX)
+            .to(torch.float8_e4m3fn)
+            .view(torch.uint8)
+            .view(valid_rows, cols)
+        )
+        payload[group_idx, :valid_rows] = q
+        scales[group_idx, :valid_rows] = byte.squeeze(-1)
+
+    payload_view = payload.permute(1, 2, 0).contiguous()
+    swizzled = swizzle_block_scale(scales)
+    scale_view = as_grouped_scale_view_mx(swizzled, rows, cols)
+    return payload_view, scale_view
+
+
+def silu_mul_quantize_grouped_mxfp8_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    """SiLU(left)*right then grouped MXFP8 quantization (w4a8 FC2 input)."""
+    cols = input_tensor.shape[-1] // 2
+    left = input_tensor[..., :cols].float()
+    right = input_tensor[..., cols:].float()
+    activated = (F.silu(left) * right).to(input_tensor.dtype).to(torch.float32)
+    return quantize_grouped_mxfp8_torch(activated, row_counts)
+
+
+def relu2_quantize_grouped_mxfp8_torch(
+    input_tensor: torch.Tensor,
+    row_counts: torch.Tensor,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    """ReLU^2 then grouped MXFP8 quantization (w4a8 FC2 input, non-gated)."""
+    activated = torch.square(F.relu(input_tensor.float()))
+    activated = activated.to(input_tensor.dtype).to(torch.float32)
+    return quantize_grouped_mxfp8_torch(activated, row_counts)
+
+
+# =============================================================================
+# Architecture Detection
+# =============================================================================
+
+
+@functools.lru_cache(maxsize=16)
+def get_sm_version(device: int | torch.device | str | None = None) -> int:
+    """Get the SM version of a CUDA device.
+
+    Args:
+        device: CUDA device to query. Can be an int (device index), torch.device,
+            device string (e.g., 'cuda:0'), or None to use current device.
+
+    Returns:
+        SM version as an integer (e.g., 120 on the current target).
+    """
+    if not torch.cuda.is_available():
+        return 80
+    if device is None:
+        device = torch.cuda.current_device()
+    props = torch.cuda.get_device_properties(device)
+    return props.major * 10 + props.minor
+
+
+# =============================================================================
+# PTX Intrinsics - Cluster Operations
+# =============================================================================
+
+
+@dsl_user_op
+def set_block_rank(
+    smem_ptr: cute.Pointer, peer_cta_rank_in_cluster: Int32, *, loc=None, ip=None
+) -> Int32:
+    """Map smem pointer to address at another CTA rank in the cluster."""
+    smem_ptr_i32 = smem_ptr.toint(loc=loc, ip=ip).ir_value()
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [smem_ptr_i32, peer_cta_rank_in_cluster.ir_value()],
+            "mapa.shared::cluster.u32 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def store_shared_remote(
+    val: Float32,
+    smem_ptr: cute.Pointer,
+    mbar_ptr: cute.Pointer,
+    peer_cta_rank_in_cluster: Int32,
+    *,
+    loc=None,
+    ip=None,
+) -> None:
+    """Store Float32 value to shared memory on a remote CTA in the cluster."""
+    remote_smem_ptr_i32 = set_block_rank(
+        smem_ptr, peer_cta_rank_in_cluster, loc=loc, ip=ip
+    ).ir_value()
+    remote_mbar_ptr_i32 = set_block_rank(
+        mbar_ptr, peer_cta_rank_in_cluster, loc=loc, ip=ip
+    ).ir_value()
+    llvm.inline_asm(
+        None,
+        [remote_smem_ptr_i32, val.ir_value(loc=loc, ip=ip), remote_mbar_ptr_i32],
+        "st.async.shared::cluster.mbarrier::complete_tx::bytes.f32 [$0], $1, [$2];",
+        "r,f,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def elem_pointer(x: cute.Tensor, coord, *, loc=None, ip=None) -> cute.Pointer:
+    """Get pointer to element at coordinate in tensor."""
+    return x.iterator + cute.crd2idx(coord, x.layout, loc=loc, ip=ip)
+
+
+# =============================================================================
+# PTX Intrinsics - 128-bit Vectorized Global Loads/Stores
+# =============================================================================
+
+
+@dsl_user_op
+def ld_global_v4_u32(
+    base_ptr: Int64, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Load 128 bits (4 x uint32) from global memory."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32(), T.i32(), T.i32()]),
+        [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+        "ld.global.v4.u32 {$0, $1, $2, $3}, [$4];",
+        "=r,=r,=r,=r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+    v0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    v1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    v2 = llvm.extractvalue(T.i32(), result, [2], loc=loc, ip=ip)
+    v3 = llvm.extractvalue(T.i32(), result, [3], loc=loc, ip=ip)
+
+    return Uint32(v0), Uint32(v1), Uint32(v2), Uint32(v3)
+
+
+# =============================================================================
+# PTX Intrinsics - Non-Coherent Global Loads
+# =============================================================================
+
+
+@dsl_user_op
+def ld_global_nc_u32(base_ptr: Int64, *, loc=None, ip=None) -> Uint32:
+    """Load 32 bits from global memory via non-coherent cache (.nc)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+            "ld.global.nc.u32 $0, [$1];",
+            "=r,l",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_global_b16(base_ptr: Int64, *, loc=None, ip=None) -> Uint32:
+    """Load one 16-bit global-memory payload into a 32-bit register.
+
+    PTX permits a bit-typed load into a wider bit register.  This is the form
+    emitted by FlashInfer for the DSV4 RoPE gather and avoids rounding the
+    address down to a word followed by a runtime halfword select.
+    """
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+            "ld.global.b16 $0, [$1];",
+            "=r,l",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def prefetch_global_l2(base_ptr: Int64, *, loc=None, ip=None) -> None:
+    """Prefetch a global memory line into L2."""
+    llvm.inline_asm(
+        None,
+        [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+        "prefetch.global.L2 [$0];",
+        "l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def ld_global_nc_v2_u32(
+    base_ptr: Int64, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """Load 64 bits (2 x uint32) from global memory via non-coherent cache (.nc)."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+        "ld.global.nc.v2.u32 {$0, $1}, [$2];",
+        "=r,=r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Uint32(llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def ld_global_nc_v4_u32(
+    base_ptr: Int64, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Load 128 bits (4 x uint32) from global memory via non-coherent cache (.nc)."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32(), T.i32(), T.i32()]),
+        [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+        "ld.global.nc.v4.u32 {$0, $1, $2, $3}, [$4];",
+        "=r,=r,=r,=r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Uint32(llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), result, [2], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), result, [3], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def st_global_u64(base_ptr: Int64, value: Uint64, *, loc=None, ip=None):
+    """Store 64 bits to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Uint64(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.u64 [$0], $1;",
+        "l,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_global_u8(base_ptr: Int64, value: Uint8, *, loc=None, ip=None):
+    """Store 8 bits to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Uint8(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.u8 [$0], $1;",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_global_f32(base_ptr: Int64, value: Float32, *, loc=None, ip=None):
+    """Store 32-bit float to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Float32(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.f32 [$0], $1;",
+        "l,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_global_v2_f32(base_ptr: Int64, v0: Float32, v1: Float32, *, loc=None, ip=None):
+    """Store 64 bits (2 x float32) to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Float32(v0).ir_value(loc=loc, ip=ip),
+            Float32(v1).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.v2.f32 [$0], {$1, $2};",
+        "l,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_global_v4_f32(
+    base_ptr: Int64,
+    v0: Float32,
+    v1: Float32,
+    v2: Float32,
+    v3: Float32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Store 128 bits (4 x float32) to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Float32(v0).ir_value(loc=loc, ip=ip),
+            Float32(v1).ir_value(loc=loc, ip=ip),
+            Float32(v2).ir_value(loc=loc, ip=ip),
+            Float32(v3).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.v4.f32 [$0], {$1, $2, $3, $4};",
+        "l,f,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def ld_global_v4_f32(
+    base_ptr: Int64,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Load 128 bits (4 x float32) from global memory."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [Int64(base_ptr).ir_value(loc=loc, ip=ip)],
+        "ld.global.v4.f32 {$0, $1, $2, $3}, [$4];",
+        "=f,=f,=f,=f,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def st_global_v4_u32(
+    base_ptr: Int64,
+    v0: Uint32,
+    v1: Uint32,
+    v2: Uint32,
+    v3: Uint32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Store 128 bits (4 x uint32) to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(base_ptr).ir_value(loc=loc, ip=ip),
+            Uint32(v0).ir_value(loc=loc, ip=ip),
+            Uint32(v1).ir_value(loc=loc, ip=ip),
+            Uint32(v2).ir_value(loc=loc, ip=ip),
+            Uint32(v3).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.v4.u32 [$0], {$1, $2, $3, $4};",
+        "l,r,r,r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def smem_ptr_to_addr(ptr: cute.Pointer, *, loc=None, ip=None) -> Int32:
+    """Convert a generic/smem pointer to a shared-memory u32 address for PTX."""
+    generic_addr = llvm.ptrtoint(T.i64(), ptr.llvm_ptr, loc=loc, ip=ip)
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [generic_addr],
+            "cvta.to.shared.u32 $0, $1;",
+            "=r,l",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def shared_ptr_to_u32(ptr: cute.Pointer, *, loc=None, ip=None) -> Int32:
+    """Convert an address-space-3 shared-memory pointer to a u32 address."""
+    return Int32(llvm.ptrtoint(T.i32(), ptr.llvm_ptr, loc=loc, ip=ip))
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Issue `ldmatrix.sync.aligned.m8n8.x4.shared.b16` from a shared-memory byte address."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32(), T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.m8n8.x4.shared.b16 {$0, $1, $2, $3}, [$4];",
+        "=r,=r,=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.i32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.i32(), result, [3], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1), Uint32(r2), Uint32(r3)
+
+
+@dsl_user_op
+def ld_shared_u16_offset(
+    smem_addr: Int32,
+    byte_offset: int,
+    *,
+    loc=None,
+    ip=None,
+) -> Uint16:
+    """Load a shared halfword at a compile-time byte displacement.
+
+    Keeping the result as i16 lets NVVM select a PTX ``%rs`` operand and
+    avoids a redundant ``cvt.u16.u32`` before packed FP8 decode. Embedding the
+    displacement also avoids materializing one address register per unrolled
+    K step.
+    """
+    offset = int(byte_offset)
+    address = f"[$1+{offset}]" if offset else "[$1]"
+    return Uint16(
+        llvm.inline_asm(
+            T.i16(),
+            [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+            f"ld.shared.u16 $0, {address};",
+            "=h,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_shared_u8_offset(
+    smem_addr: Int32,
+    byte_offset: int,
+    *,
+    loc=None,
+    ip=None,
+) -> Uint32:
+    """Load one shared byte at a compile-time displacement, zero-extended.
+
+    This is the native ``ld.shared.u8`` form used for UE8M0 scale tables.  A
+    common row base plus an immediate displacement keeps the unrolled scale
+    cache free of word-alignment, shift, and mask instructions.
+    """
+    offset = int(byte_offset)
+    address = f"[$1+{offset}]" if offset else "[$1]"
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+            f"ld.shared.u8 $0, {address};",
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ldmatrix_m8n8x2_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Issue `ldmatrix.sync.aligned.m8n8.x2.shared.b16` from a shared-memory byte address."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.m8n8.x2.shared.b16 {$0, $1}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_left_half_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Issue `ldmatrix.sync.aligned.m8n8.x4.shared.b16` and return the left half fragment pair."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.m8n8.x4.shared.b16 {$0, _, $1, _}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_right_half_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Issue `ldmatrix.sync.aligned.m8n8.x4.shared.b16` and return the right half fragment pair."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.m8n8.x4.shared.b16 {_, $0, _, $1}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_trans_b16(
+    smem_addr: Int32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Issue `ldmatrix.sync.aligned.trans.m8n8.x4.shared.b16` from a shared-memory byte address."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32(), T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.trans.m8n8.x4.shared.b16 {$0, $1, $2, $3}, [$4];",
+        "=r,=r,=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.i32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.i32(), result, [3], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1), Uint32(r2), Uint32(r3)
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_trans_left_half_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Issue transposed `ldmatrix` and return the left half fragment pair."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.trans.m8n8.x4.shared.b16 {$0, $1, _, _}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def ldmatrix_m8n8x4_trans_right_half_b16(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Issue transposed `ldmatrix` and return the right half fragment pair."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ldmatrix.sync.aligned.trans.m8n8.x4.shared.b16 {_, _, $0, $1}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def ld_shared_v4_u32(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Load 128 bits (4 x uint32) from shared memory. smem_addr is a u32 shared-memory address."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32(), T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ld.shared.v4.u32 {$0, $1, $2, $3}, [$4];",
+        "=r,=r,=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.i32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.i32(), result, [3], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1), Uint32(r2), Uint32(r3)
+
+
+@dsl_user_op
+def ld_shared_v2_u32(smem_addr: Int32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Load 64 bits (2 x uint32) from shared memory."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Int32(smem_addr).ir_value(loc=loc, ip=ip)],
+        "ld.shared.v2.u32 {$0, $1}, [$2];",
+        "=r,=r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(r0), Uint32(r1)
+
+
+@dsl_user_op
+def st_shared_u64(smem_addr: Int32, value: Uint64, *, loc=None, ip=None):
+    """Store 64 bits to shared memory. smem_addr is a u32 shared-memory address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Uint64(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.u64 [$0], $1;",
+        "r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_shared_v4_u32(
+    smem_addr: Int32,
+    v0: Uint32,
+    v1: Uint32,
+    v2: Uint32,
+    v3: Uint32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Store 128 bits (4 x uint32) to shared memory. smem_addr is a u32 shared-memory address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Uint32(v0).ir_value(loc=loc, ip=ip),
+            Uint32(v1).ir_value(loc=loc, ip=ip),
+            Uint32(v2).ir_value(loc=loc, ip=ip),
+            Uint32(v3).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.v4.u32 [$0], {$1, $2, $3, $4};",
+        "r,r,r,r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def cp_async_bulk_g2s_mbar(
+    smem_dst_u32: Int32,
+    gmem_src_i64: Int64,
+    nbytes: Int32,
+    mbar_u32: Int32,
+    *,
+    loc=None,
+    ip=None,
+) -> None:
+    """Emit cp.async.bulk.shared::cta.global.mbarrier::complete_tx::bytes.
+
+    CTA-scope bulk g2s gather completing on a CTA-scope mbarrier. Mirrors
+    FlashInfer cp_async_bulk_g2s (sparse_mla_sm120/arch/cp_async.cuh:64-72)
+    exactly:
+        [$0]=smem dst (u32 shared addr), [$1]=gmem src (i64 generic),
+        $2=bytes (u32), [$3]=mbar (u32 shared addr).
+    Used by the IO warp of the DSV4/GLM sparse-MLA decode port to gather a
+    whole token row (e.g. 656B or 576B+8B) in one transaction.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_dst_u32).ir_value(loc=loc, ip=ip),
+            Int64(gmem_src_i64).ir_value(loc=loc, ip=ip),
+            Int32(nbytes).ir_value(loc=loc, ip=ip),
+            Int32(mbar_u32).ir_value(loc=loc, ip=ip),
+        ],
+        "cp.async.bulk.shared::cta.global.mbarrier::complete_tx::bytes"
+        " [$0], [$1], $2, [$3];",
+        "r,l,r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def create_l2_evict_first_policy(*, loc=None, ip=None) -> Uint64:
+    """Create an L2 evict-first policy for one-pass streaming cache rows."""
+    return Uint64(
+        llvm.inline_asm(
+            T.i64(),
+            [],
+            "createpolicy.fractional.L2::evict_first.b64 $0, 1.0;",
+            "=l",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def cp_async_bulk_g2s_mbar_l2hint(
+    smem_dst_u32: Int32,
+    gmem_src_i64: Int64,
+    nbytes: Int32,
+    mbar_u32: Int32,
+    cache_policy: Uint64,
+    *,
+    loc=None,
+    ip=None,
+) -> None:
+    """Bulk global-to-shared copy with an explicit L2 cache policy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_dst_u32).ir_value(loc=loc, ip=ip),
+            Int64(gmem_src_i64).ir_value(loc=loc, ip=ip),
+            Int32(nbytes).ir_value(loc=loc, ip=ip),
+            Int32(mbar_u32).ir_value(loc=loc, ip=ip),
+            Uint64(cache_policy).ir_value(loc=loc, ip=ip),
+        ],
+        "cp.async.bulk.shared::cta.global.mbarrier::complete_tx::bytes.L2::cache_hint"
+        " [$0], [$1], $2, [$3], $4;",
+        "r,l,r,r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_u8(smem_addr: Int32, value: Uint8, *, loc=None, ip=None):
+    """Store 8 bits to shared memory. smem_addr is a u32 shared-memory address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Uint8(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.u8 [$0], $1;",
+        "r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def st_shared_u16(smem_addr: Int32, value: Uint32, *, loc=None, ip=None):
+    """Store the low 16 bits of a register to shared memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Uint32(value).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.u16 [$0], $1;",
+        "r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def quantize_scaled_store_shared_v2_e4m3(
+    smem_addr: Int32,
+    scaled_value0: Float32,
+    scaled_value1: Float32,
+    inv_scale: Float32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Scale, quantize, and vector-store two contiguous E4M3 bytes.
+
+    ``scaled_value*`` already include the per-candidate V scale used by the
+    preceding atomic-max pass. Keeping that multiplication in ordinary SSA
+    lets LLVM retain/reuse the products across the barrier, as FlashInfer does.
+    The E4M3 results never widen through ``Uint32`` and are written with the
+    same half-register ``st.shared.v2.b8`` form.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Float32(scaled_value0).ir_value(loc=loc, ip=ip),
+            Float32(scaled_value1).ir_value(loc=loc, ip=ip),
+            Float32(inv_scale).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .b16 q0, q1;
+            .reg .f32 zero, tmp;
+            mov.f32 zero, 0f00000000;
+            mul.f32 tmp, $1, $3;
+            cvt.rn.satfinite.e4m3x2.f32 q0, zero, tmp;
+            mul.f32 tmp, $2, $3;
+            cvt.rn.satfinite.e4m3x2.f32 q1, zero, tmp;
+            st.shared.v2.b8 [$0], {q0, q1};
+        }
+        """,
+        "r,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cp_async_u32_shared_global(smem_addr: Int32, gmem_addr: Int64, *, loc=None, ip=None):
+    """4-byte `cp.async.ca.shared.global` copy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Int64(gmem_addr).ir_value(loc=loc, ip=ip),
+        ],
+        "cp.async.ca.shared.global [$0], [$1], 4;",
+        "r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cp_async_u64_shared_global(smem_addr: Int32, gmem_addr: Int64, *, loc=None, ip=None):
+    """8-byte `cp.async.ca.shared.global` copy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Int64(gmem_addr).ir_value(loc=loc, ip=ip),
+        ],
+        "cp.async.ca.shared.global [$0], [$1], 8;",
+        "r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cp_async4_shared_global(smem_addr: Int32, gmem_addr: Int64, *, loc=None, ip=None):
+    """16-byte `cp.async.cg.shared.global` copy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Int64(gmem_addr).ir_value(loc=loc, ip=ip),
+        ],
+        "cp.async.cg.shared.global [$0], [$1], 16;",
+        "r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cp_async4_shared_global_pred(
+    smem_addr: Int32, gmem_addr: Int64, pred: Int32, *, loc=None, ip=None
+):
+    """Predicated 16-byte `cp.async.cg.shared.global` copy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(pred).ir_value(loc=loc, ip=ip),
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Int64(gmem_addr).ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .pred p; setp.ne.b32 p, $0, 0; @p cp.async.cg.shared.global [$1], [$2], 16; }",
+        "r,r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cp_async4_ca_shared_global_pred(
+    smem_addr: Int32, gmem_addr: Int64, pred: Int32, *, loc=None, ip=None
+):
+    """Predicated 16-byte `cp.async.ca.shared.global` copy."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(pred).ir_value(loc=loc, ip=ip),
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Int64(gmem_addr).ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .pred p; setp.ne.b32 p, $0, 0; @p cp.async.ca.shared.global [$1], [$2], 16; }",
+        "r,r,l",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def get_ptr_as_int64(tensor: cute.Tensor, offset, *, loc=None, ip=None) -> Int64:
+    """Get the memory address of tensor[offset] as Int64."""
+    elem_ptr = tensor.iterator + offset
+    ptr_int = llvm.ptrtoint(T.i64(), elem_ptr.llvm_ptr, loc=loc, ip=ip)
+    return Int64(ptr_int)
+
+
+# =============================================================================
+# PTX Intrinsics - Global Atomics
+# =============================================================================
+
+
+@dsl_user_op
+def atomic_add_global_i32(addr: Int64, val: Int32, *, loc=None, ip=None) -> Int32:
+    """Global memory int32 atomic add. Returns old value."""
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Int64(addr).ir_value(loc=loc, ip=ip),
+                Int32(val).ir_value(loc=loc, ip=ip),
+            ],
+            "atom.global.add.s32 $0, [$1], $2;",
+            "=r,l,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def red_add_global_release_i32(addr: Int64, val: Int32, *, loc=None, ip=None):
+    """No-return global int32 add with a GPU-scope release fence."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Int32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "fence.acq_rel.gpu;\n"
+        "red.relaxed.gpu.global.add.s32 [$0], $1;",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def red_add_global_f32(addr: Int64, val: Float32, *, loc=None, ip=None):
+    """No-return global fp32 add reduction (relaxed device scope)."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "red.global.add.f32 [$0], $1;",
+        "l,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def cvt_bf16x2_to_f16x2(packed: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Convert a u32 holding two bf16 (lo, hi) into an f16x2 u32 (lo, hi)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(packed).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 blo, bhi, hlo, hhi;
+                .reg .f32 flo, fhi;
+                mov.b32 {blo, bhi}, $1;
+                cvt.f32.bf16 flo, blo;
+                cvt.f32.bf16 fhi, bhi;
+                cvt.rn.f16.f32 hlo, flo;
+                cvt.rn.f16.f32 hhi, fhi;
+                mov.b32 $0, {hlo, hhi};
+            }
+            """,
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def red_add_global_bf16x2(addr: Int64, packed: Uint32, *, loc=None, ip=None):
+    """No-return global atomic add of a packed bf16x2 value (2 contiguous bf16).
+
+    Used by the W4A16 TC-decode FC2 epilogue to fold the per-route partial
+    outputs into the per-token output without a separate top-k-sum launch.
+    The address must be 4-byte aligned and cover two consecutive bf16 lanes.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Uint32(packed).ir_value(loc=loc, ip=ip),
+        ],
+        "red.relaxed.gpu.global.add.noftz.bf16x2 [$0], $1;",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def red_max_global_f32_nonnegative(addr: Int64, val: Float32, *, loc=None, ip=None):
+    """No-return global max reduction for a non-negative fp32 value.
+
+    Non-negative IEEE-754 float ordering matches unsigned integer bit ordering,
+    so this emits a no-return u32 max reduction on the value's bit pattern.
+    Callers must initialize the destination with a non-negative fp32 value.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .u32 vi; mov.b32 vi, $1; red.relaxed.gpu.global.max.u32 [$0], vi; }",
+        "l,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def atomic_cas_global_i32(addr: Int64, compare: Int32, value: Int32, *, loc=None, ip=None) -> Int32:
+    """Global memory int32 atomic compare-and-swap. Returns old value."""
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Int64(addr).ir_value(loc=loc, ip=ip),
+                Int32(compare).ir_value(loc=loc, ip=ip),
+                Int32(value).ir_value(loc=loc, ip=ip),
+            ],
+            "atom.global.cas.b32 $0, [$1], $2, $3;",
+            "=r,l,r,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def atomic_add_shared_i32(addr: Int32, val: Int32, *, loc=None, ip=None) -> Int32:
+    """Shared-memory int32 atomic add (CTA-scope). Returns old value.
+
+    Uses ``atom.shared.add.s32`` with a 32-bit shared-memory address
+    (the native address width for smem on NVIDIA GPUs).
+    """
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Int32(addr).ir_value(loc=loc, ip=ip),
+                Int32(val).ir_value(loc=loc, ip=ip),
+            ],
+            "atom.shared.add.s32 $0, [$1], $2;",
+            "=r,r,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def atomic_max_shared_f32(smem_addr: Int32, val: Float32, *, loc=None, ip=None):
+    """No-return shared atomic max for a NON-NEGATIVE fp32 ``val``.
+
+    Relies on the IEEE-754 ordering of non-negative floats matching the signed
+    int ordering of their bit patterns, so the smem max can be done with a
+    single s32 reduction. All callers consume the reduced shared slot after a
+    barrier; none needs the old or resulting value in the issuing lane.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "{.reg .s32 vi; mov.b32 vi, $1; red.shared.max.s32 [$0], vi;}",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def atomic_max_shared_f32_offset(
+    smem_addr: Int32,
+    byte_offset: int,
+    val: Float32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """No-return nonnegative FP32 shared max at a constant displacement."""
+    offset = int(byte_offset)
+    address = f"[$0+{offset}]" if offset else "[$0]"
+    llvm.inline_asm(
+        None,
+        [
+            Int32(smem_addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        f"{{.reg .s32 vi; mov.b32 vi, $1; red.shared.max.s32 {address}, vi;}}",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def red_add_shared_i32(addr: Int32, val: Int32, *, loc=None, ip=None):
+    """No-return shared-memory int32 add.
+
+    Use this when the old value is not needed. NVCC lowers equivalent C++
+    histogram increments to cheaper no-return shared atomics.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Int32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "red.shared.add.u32 [$0], $1;",
+        "r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def ld_shared_i32(addr: Int32, *, loc=None, ip=None) -> Int32:
+    """Volatile-style load int32 from shared memory at a 32-bit byte address."""
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            "ld.shared.s32 $0, [$1];",
+            "=r,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_shared_i32_relaxed(addr: Int32, *, loc=None, ip=None) -> Int32:
+    """Load int32 from shared memory at a 32-bit byte address."""
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            "ld.shared.s32 $0, [$1];",
+            "=r,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_shared_u32(addr: Int32, *, loc=None, ip=None) -> Uint32:
+    """Load uint32 from shared memory at a 32-bit byte address."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            "ld.shared.u32 $0, [$1];",
+            "=r,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def st_shared_i32(addr: Int32, val: Int32, *, loc=None, ip=None):
+    """Store int32 to shared memory at a 32-bit byte address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Int32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.s32 [$0], $1;",
+        "r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_u32(addr: Int32, val: Uint32, *, loc=None, ip=None):
+    """Store uint32 to shared memory at a 32-bit byte address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Uint32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.u32 [$0], $1;",
+        "r,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def ld_shared_f32(addr: Int32, *, loc=None, ip=None) -> Float32:
+    """Load float32 from shared memory at a 32-bit byte address."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            "ld.shared.f32 $0, [$1];",
+            "=f,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_shared_f32_offset(
+    addr: Int32,
+    byte_offset: int,
+    *,
+    loc=None,
+    ip=None,
+) -> Float32:
+    """Load shared FP32 using a compile-time displacement."""
+    offset = int(byte_offset)
+    address = f"[$1+{offset}]" if offset else "[$1]"
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            f"ld.shared.f32 $0, {address};",
+            "=f,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def ld_shared_v4_f32(
+    addr: Int32, *, loc=None, ip=None
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Load 128 bits (4 x float32) from shared memory."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [Int32(addr).ir_value(loc=loc, ip=ip)],
+        "ld.shared.v4.f32 {$0, $1, $2, $3}, [$4];",
+        "=f,=f,=f,=f,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+
+@dsl_user_op
+def ld_shared_bf16_to_f32(addr: Int32, *, loc=None, ip=None) -> Float32:
+    """Load a BF16 from shared memory at a 32-bit byte address and convert to FP32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Int32(addr).ir_value(loc=loc, ip=ip)],
+            "{.reg .b16 tmp; ld.shared.b16 tmp, [$1]; cvt.f32.bf16 $0, tmp;}",
+            "=f,r",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def st_shared_f32(addr: Int32, val: Float32, *, loc=None, ip=None):
+    """Store float32 to shared memory at a 32-bit byte address."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.f32 [$0], $1;",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_f32_offset(
+    addr: Int32,
+    byte_offset: int,
+    val: Float32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Store shared FP32 using a compile-time displacement."""
+    offset = int(byte_offset)
+    address = f"[$0+{offset}]" if offset else "[$0]"
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        f"st.shared.f32 {address}, $1;",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_v4_f32(
+    addr: Int32,
+    v0: Float32,
+    v1: Float32,
+    v2: Float32,
+    v3: Float32,
+    *,
+    loc=None,
+    ip=None,
+):
+    """Store 128 bits (4 x float32) to shared memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Float32(v0).ir_value(loc=loc, ip=ip),
+            Float32(v1).ir_value(loc=loc, ip=ip),
+            Float32(v2).ir_value(loc=loc, ip=ip),
+            Float32(v3).ir_value(loc=loc, ip=ip),
+        ],
+        "st.shared.v4.f32 [$0], {$1, $2, $3, $4};",
+        "r,f,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_bf16_from_f32(addr: Int32, val: Float32, *, loc=None, ip=None):
+    """Convert float32 to BF16 and store one 16-bit value to shared memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .b16 tmp; cvt.rn.bf16.f32 tmp, $1; st.shared.b16 [$0], tmp; }",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_shared_f16_from_f32(addr: Int32, val: Float32, *, loc=None, ip=None):
+    """Convert float32 to FP16 and store one 16-bit value to shared memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int32(addr).ir_value(loc=loc, ip=ip),
+            Float32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .b16 tmp; cvt.rn.f16.f32 tmp, $1; st.shared.b16 [$0], tmp; }",
+        "r,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def st_global_i32(addr: Int64, val: Int32, *, loc=None, ip=None):
+    """Store int32 to global memory."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Int32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.s32 [$0], $1;",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+# =============================================================================
+# PTX Intrinsics - Global Memory Barriers
+# =============================================================================
+
+
+@dsl_user_op
+def ld_global_acquire_i32(addr: Int64, *, loc=None, ip=None) -> Int32:
+    """Load int32 from global memory with acquire semantics."""
+    return Int32(
+        llvm.inline_asm(
+            T.i32(),
+            [Int64(addr).ir_value(loc=loc, ip=ip)],
+            "ld.global.acquire.gpu.s32 $0, [$1];",
+            "=r,l",
+            has_side_effects=True,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def st_global_release_i32(addr: Int64, val: Int32, *, loc=None, ip=None):
+    """Store int32 to global memory with release semantics."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Int32(val).ir_value(loc=loc, ip=ip),
+        ],
+        "st.global.release.gpu.s32 [$0], $1;",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def spin_wait_global_eq_i32(addr: Int64, expected: Int32, *, loc=None, ip=None):
+    """Spin-wait until *addr != expected (acquire semantics on load)."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Int32(expected).ir_value(loc=loc, ip=ip),
+        ],
+        "{\n"
+        ".reg .pred %p0;\n"
+        ".reg .s32 %val;\n"
+        "spin_loop:\n"
+        "  ld.global.acquire.gpu.s32 %val, [$0];\n"
+        "  setp.eq.s32 %p0, %val, $1;\n"
+        "  @%p0 bra spin_loop;\n"
+        "}",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def spin_wait_global_ge_i32(addr: Int64, target: Int32, *, loc=None, ip=None):
+    """Spin-wait until *addr >= target using acquire loads."""
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            Int32(target).ir_value(loc=loc, ip=ip),
+        ],
+        "{\n"
+        ".reg .pred %p0;\n"
+        ".reg .s32 %val;\n"
+        "spin_loop_ge:\n"
+        "  ld.global.acquire.gpu.s32 %val, [$0];\n"
+        "  setp.lt.s32 %p0, %val, $1;\n"
+        "  @%p0 bra spin_loop_ge;\n"
+        "}",
+        "l,r",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+@dsl_user_op
+def threadfence(*, loc=None, ip=None):
+    """Emit membar.gl — threadfence across global memory."""
+    llvm.inline_asm(
+        None,
+        [],
+        "membar.gl;",
+        "",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+
+# =============================================================================
+# PTX Intrinsics - Scatter Atomics
+# =============================================================================
+
+
+@dsl_user_op
+def scatter_add_bf16x2(addr: Int64, val0_f32, val1_f32, *, loc=None, ip=None):
+    """BF16x2 atomic reduction add to global memory.
+
+    Packs two f32 values into bf16x2 via cvt.rn.satfinite, then does
+    red.relaxed.gpu.global.add.noftz.bf16x2. Workaround for LLVM NVPTX
+    bug that decomposes vector<2xbf16> into .v2.bf16x2 which ptxas rejects.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            val0_f32.ir_value(loc=loc, ip=ip),
+            val1_f32.ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .b32 packed; cvt.rn.satfinite.bf16x2.f32 packed, $2, $1; red.relaxed.gpu.global.add.noftz.bf16x2 [$0], packed; }",
+        "l,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def scatter_add_bf16(addr: Int64, val_f32, *, loc=None, ip=None):
+    """BF16 atomic reduction add to global memory.
+
+    Converts the f32 input to bf16 inside PTX and atomically accumulates it into
+    one bf16 output lane. This is intended for opt-in approximate reductions.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            val_f32.ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .b16 packed; cvt.rn.satfinite.bf16.f32 packed, $1; red.relaxed.gpu.global.add.noftz.bf16 [$0], packed; }",
+        "l,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+@dsl_user_op
+def scatter_add_v4_bf16x2(addr: Int64, v0, v1, v2, v3, v4, v5, v6, v7, *, loc=None, ip=None):
+    """Vectorized BF16x2 atomic reduction: 8 bf16 values (16 bytes) in one go.
+
+    red.global.add.noftz.v4.bf16x2 [addr], {packed0, packed1, packed2, packed3}
+    Each packed reg contains 2 bf16 values converted from f32 pairs.
+    """
+    llvm.inline_asm(
+        None,
+        [
+            Int64(addr).ir_value(loc=loc, ip=ip),
+            v0.ir_value(loc=loc, ip=ip), v1.ir_value(loc=loc, ip=ip),
+            v2.ir_value(loc=loc, ip=ip), v3.ir_value(loc=loc, ip=ip),
+            v4.ir_value(loc=loc, ip=ip), v5.ir_value(loc=loc, ip=ip),
+            v6.ir_value(loc=loc, ip=ip), v7.ir_value(loc=loc, ip=ip),
+        ],
+        "{ .reg .b32 p0,p1,p2,p3;"
+        " cvt.rn.satfinite.bf16x2.f32 p0, $2, $1;"
+        " cvt.rn.satfinite.bf16x2.f32 p1, $4, $3;"
+        " cvt.rn.satfinite.bf16x2.f32 p2, $6, $5;"
+        " cvt.rn.satfinite.bf16x2.f32 p3, $8, $7;"
+        " red.global.add.noftz.v4.bf16x2 [$0], {p0, p1, p2, p3}; }",
+        "l,f,f,f,f,f,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+    )
+
+
+# =============================================================================
+# PTX Intrinsics - Math Operations
+# =============================================================================
+
+
+@dsl_user_op
+def rcp_approx_ftz(a: Float32, *, loc=None, ip=None) -> Float32:
+    """Fast reciprocal using PTX rcp.approx.ftz.f32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Float32(a).ir_value(loc=loc, ip=ip)],
+            "rcp.approx.ftz.f32 $0, $1;",
+            "=f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def fmin_f32(a: Float32, b: Float32, *, loc=None, ip=None) -> Float32:
+    """Compute min of two float32 values using PTX min.f32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Float32(a).ir_value(loc=loc, ip=ip), Float32(b).ir_value(loc=loc, ip=ip)],
+            "min.f32 $0, $1, $2;",
+            "=f,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def fmax_f32(a: Float32, b: Float32, *, loc=None, ip=None) -> Float32:
+    """Compute max of two float32 values using PTX max.f32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Float32(a).ir_value(loc=loc, ip=ip), Float32(b).ir_value(loc=loc, ip=ip)],
+            "max.f32 $0, $1, $2;",
+            "=f,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def fabs_f32(a: Float32, *, loc=None, ip=None) -> Float32:
+    """Compute absolute value of float32 using PTX abs.f32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Float32(a).ir_value(loc=loc, ip=ip)],
+            "abs.f32 $0, $1;",
+            "=f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+# =============================================================================
+# Half2 SIMD Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def half2_mul(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Multiply two Half2 values element-wise: (a.x*b.x, a.y*b.y)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "mul.f16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def broadcast_f32_to_half2(x: Float32, *, loc=None, ip=None) -> Uint32:
+    """Pack one float32 value into both lanes of an f16x2 register."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(x).ir_value(loc=loc, ip=ip)],
+            "cvt.rn.f16x2.f32 $0, $1, $1;",
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def hadd2(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Add two Half2 values element-wise: (a.x+b.x, a.y+b.y)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "add.f16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def habs2(x: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Half2 absolute value - clears sign bits of both fp16 values."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(x).ir_value(loc=loc, ip=ip)],
+            "and.b32 $0, $1, 0x7FFF7FFF;",
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def hmax2(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Half2 max - element-wise max of 2 fp16 pairs."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "max.f16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def hmax_to_f32(x: Uint32, *, loc=None, ip=None) -> Float32:
+    """Extract max of 2 fp16 values in half2 as float32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(x).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 h0, h1;
+                .reg .f32 f0, f1;
+                mov.b32 {h0, h1}, $1;
+                cvt.f32.f16 f0, h0;
+                cvt.f32.f16 f1, h1;
+                max.f32 $0, f0, f1;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def half2_to_float2_scaled(
+    h2: Uint32, scale: Float32, *, loc=None, ip=None
+) -> Tuple[Float32, Float32]:
+    """Convert half2 to float2 AND multiply by scale."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32()]),
+        [Uint32(h2).ir_value(loc=loc, ip=ip), Float32(scale).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b16 h0, h1;
+            .reg .f32 f0, f1;
+            mov.b32 {h0, h1}, $2;
+            cvt.f32.f16 f0, h0;
+            cvt.f32.f16 f1, h1;
+            mul.f32 $0, f0, $3;
+            mul.f32 $1, f1, $3;
+        }
+        """,
+        "=f,=f,r,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+    f0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    f1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+
+    return Float32(f0), Float32(f1)
+
+
+# =============================================================================
+# BFloat2 SIMD Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def bfloat2_mul(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Multiply two BFloat2 values element-wise: (a.x*b.x, a.y*b.y)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "mul.bf16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def bfloat2_broadcast_lane(x: Uint32, lane: Int32, *, loc=None, ip=None) -> Uint32:
+    """Duplicate one BF16 lane from a packed bf16x2 register into both lanes."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Uint32(x).ir_value(loc=loc, ip=ip),
+                Int32(lane).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .pred p;
+                .reg .b32 lo, hi, val, shifted;
+                and.b32 lo, $1, 0x0000ffff;
+                shr.u32 hi, $1, 16;
+                setp.eq.s32 p, $2, 0;
+                @p  mov.b32 val, lo;
+                @!p mov.b32 val, hi;
+                shl.b32 shifted, val, 16;
+                or.b32 $0, val, shifted;
+            }
+            """,
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def broadcast_f32_to_bfloat2(x: Float32, *, loc=None, ip=None) -> Uint32:
+    """Pack one float32 value into both lanes of a bf16x2 register."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(x).ir_value(loc=loc, ip=ip)],
+            "cvt.rn.satfinite.bf16x2.f32 $0, $1, $1;",
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def pack_f32x2_to_bfloat2(x0: Float32, x1: Float32, *, loc=None, ip=None) -> Uint32:
+    """Pack 2 float32 values into one bf16x2 register."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(x0).ir_value(loc=loc, ip=ip), Float32(x1).ir_value(loc=loc, ip=ip)],
+            "cvt.rn.satfinite.bf16x2.f32 $0, $2, $1;",
+            "=r,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def cvt_bf16x2_to_e4m3x2(src: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Convert packed bf16x2 to packed e4m3x2 in the low 16 bits of a u32."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(src).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 out, zero;
+                cvt.rn.satfinite.e4m3x2.bf16x2 out, $1;
+                mov.u16 zero, 0;
+                mov.b32 $0, {out, zero};
+            }
+            """,
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def cvt_bf16x2x2_to_e4m3x4(lo: Uint32, hi: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Convert two bf16x2 values and pack the e4m3x2 results into one u32."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(lo).ir_value(loc=loc, ip=ip), Uint32(hi).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 out_lo, out_hi;
+                cvt.rn.satfinite.e4m3x2.bf16x2 out_lo, $1;
+                cvt.rn.satfinite.e4m3x2.bf16x2 out_hi, $2;
+                mov.b32 $0, {out_lo, out_hi};
+            }
+            """,
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def bfloat2_add(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Add two BFloat2 values element-wise: (a.x+b.x, a.y+b.y)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "add.bf16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def fp8x4_e4m3_to_bfloat2x2(packed: Uint32, *, loc=None, ip=None) -> Tuple[Uint32, Uint32]:
+    """Widen 4 packed E4M3 bytes into 2 packed bf16x2 registers exactly."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b16 low;
+            .reg .b32 q, out0, out1, sign0, sign1, mant0, mant1, tmp, bias, bias_f32;
+            prmt.b32 q, $2, 0, 0x1302;
+
+            and.b32 sign0, q, 0x80008000;
+            shr.u32 tmp, q, 4;
+            and.b32 mant0, tmp, 0x07F007F0;
+            or.b32 out0, mant0, sign0;
+
+            shl.b32 tmp, q, 8;
+            and.b32 sign1, tmp, 0x80008000;
+            shl.b32 tmp, q, 4;
+            and.b32 mant1, tmp, 0x07F007F0;
+            or.b32 out1, mant1, sign1;
+
+            mov.b32 bias_f32, 0x7B800000;
+            cvt.rn.bf16.f32 low, bias_f32;
+            mov.b32 bias, {low, low};
+
+            mul.bf16x2 $0, out0, bias;
+            mul.bf16x2 $1, out1, bias;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e2m1x4_to_bfloat2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """FE2M1 -> BF16 register dequant for one packed 4-value fragment."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 q, out1, out2, tmp;
+
+            and.b32 out1, $2, 0x80008000;
+            and.b32 tmp, $2, 0x70007000;
+            shr.u32 tmp, tmp, 6;
+            or.b32 out1, out1, tmp;
+
+            shl.b32 q, $2, 4;
+            and.b32 out2, q, 0x80008000;
+            and.b32 tmp, q, 0x70007000;
+            shr.u32 tmp, tmp, 6;
+            or.b32 out2, out2, tmp;
+
+            mov.b32 $0, out2;
+            mov.b32 $1, out1;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e2m1x4_to_half2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """FE2M1 -> FP16 register dequant for one packed 4-value fragment."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 q, out1, out2, tmp;
+
+            and.b32 out1, $2, 0x80008000;
+            and.b32 tmp, $2, 0x70007000;
+            shr.u32 tmp, tmp, 3;
+            or.b32 out1, out1, tmp;
+
+            shl.b32 q, $2, 4;
+            and.b32 out2, q, 0x80008000;
+            and.b32 tmp, q, 0x70007000;
+            shr.u32 tmp, tmp, 3;
+            or.b32 out2, out2, tmp;
+
+            mov.b32 $0, out2;
+            mov.b32 $1, out1;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e4m3x4_to_bfloat2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """FE4M3 scale dequant for one packed 4-value BF16 fragment."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 q, out1, out2, tmp;
+
+            and.b32 tmp, $2, 0x80008000;
+            shr.u32 out1, tmp, 1;
+            and.b32 tmp, $2, 0x7F007F00;
+            shr.u32 tmp, tmp, 4;
+            or.b32 out1, out1, tmp;
+
+            shl.b32 q, $2, 8;
+            and.b32 tmp, q, 0x80008000;
+            shr.u32 out2, tmp, 1;
+            and.b32 tmp, q, 0x7F007F00;
+            shr.u32 tmp, tmp, 4;
+            or.b32 out2, out2, tmp;
+
+            mov.b32 $0, out2;
+            mov.b32 $1, out1;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e4m3x4_to_half2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """FE4M3 scale dequant for one packed 4-value FP16 fragment."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 q, out1, out2;
+
+            and.b32 out1, $2, 0xFF00FF00;
+            shr.u32 out1, out1, 1;
+
+            shl.b32 q, $2, 8;
+            and.b32 out2, q, 0xFF00FF00;
+            shr.u32 out2, out2, 1;
+
+            mov.b32 $0, out2;
+            mov.b32 $1, out1;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e8m0x4_to_bfloat2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """E8M0 compute-scale dequant for one packed 4-value BF16 fragment.
+
+    The W4A16 FP4 unpack path represents E2M1 values scaled by 2^-126.  Match
+    the existing NVFP4 split by materializing E8M0 scales multiplied by 2^7 in
+    the MMA input and applying the remaining compensation in the kernel
+    epilogue.
+    """
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .u32 b0, b1, b2, b3;
+            .reg .u32 h0, h1, h2, h3;
+            .reg .u32 t0, t1;
+
+            and.b32 b0, $2, 0x000000ff;
+            shr.u32 b1, $2, 8;
+            and.b32 b1, b1, 0x000000ff;
+            shr.u32 b2, $2, 16;
+            and.b32 b2, b2, 0x000000ff;
+            shr.u32 b3, $2, 24;
+
+            add.u32 h0, b0, 7;
+            add.u32 h1, b1, 7;
+            add.u32 h2, b2, 7;
+            add.u32 h3, b3, 7;
+            shl.b32 h0, h0, 7;
+            shl.b32 h1, h1, 7;
+            shl.b32 h2, h2, 7;
+            shl.b32 h3, h3, 7;
+
+            shl.b32 t0, h2, 16;
+            or.b32 $0, h0, t0;
+            shl.b32 t1, h3, 16;
+            or.b32 $1, h1, t1;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def packed_dequant_e8m0x4_to_half2x2(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """E8M0 compute-scale dequant for one packed 4-value FP16 fragment."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .pred p0, p1, p2, p3;
+            .reg .u32 b0, b1, b2, b3;
+            .reg .s32 e0, e1, e2, e3;
+            .reg .f32 ef0, ef1, ef2, ef3;
+            .reg .f32 f0, f1, f2, f3;
+            .reg .b16 h0, h1, h2, h3;
+
+            and.b32 b0, $2, 0x000000ff;
+            shr.u32 b1, $2, 8;
+            and.b32 b1, b1, 0x000000ff;
+            shr.u32 b2, $2, 16;
+            and.b32 b2, b2, 0x000000ff;
+            shr.u32 b3, $2, 24;
+
+            setp.eq.u32 p0, b0, 0;
+            setp.eq.u32 p1, b1, 0;
+            setp.eq.u32 p2, b2, 0;
+            setp.eq.u32 p3, b3, 0;
+
+            cvt.s32.u32 e0, b0;
+            cvt.s32.u32 e1, b1;
+            cvt.s32.u32 e2, b2;
+            cvt.s32.u32 e3, b3;
+            sub.s32 e0, e0, 120;
+            sub.s32 e1, e1, 120;
+            sub.s32 e2, e2, 120;
+            sub.s32 e3, e3, 120;
+
+            cvt.rn.f32.s32 ef0, e0;
+            cvt.rn.f32.s32 ef1, e1;
+            cvt.rn.f32.s32 ef2, e2;
+            cvt.rn.f32.s32 ef3, e3;
+            ex2.approx.f32 f0, ef0;
+            ex2.approx.f32 f1, ef1;
+            ex2.approx.f32 f2, ef2;
+            ex2.approx.f32 f3, ef3;
+            selp.f32 f0, 0f00000000, f0, p0;
+            selp.f32 f1, 0f00000000, f1, p1;
+            selp.f32 f2, 0f00000000, f2, p2;
+            selp.f32 f3, 0f00000000, f3, p3;
+
+            cvt.rn.f16.f32 h0, f0;
+            cvt.rn.f16.f32 h1, f1;
+            cvt.rn.f16.f32 h2, f2;
+            cvt.rn.f16.f32 h3, f3;
+
+            setp.eq.u32 p0, b0, 255;
+            setp.eq.u32 p1, b1, 255;
+            setp.eq.u32 p2, b2, 255;
+            setp.eq.u32 p3, b3, 255;
+            selp.b16 h0, 0x7e00, h0, p0;
+            selp.b16 h1, 0x7e00, h1, p1;
+            selp.b16 h2, 0x7e00, h2, p2;
+            selp.b16 h3, 0x7e00, h3, p3;
+
+            mov.b32 $0, {h0, h2};
+            mov.b32 $1, {h1, h3};
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), result, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def bf16_mma_m16n8k16_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Warp MMA helper for `mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32`."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def f32_to_raw_bits(x: Float32, *, loc=None, ip=None) -> Uint32:
+    """Return the raw IEEE-754 bits of one float32 value."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(x).ir_value(loc=loc, ip=ip)],
+            "mov.b32 $0, $1;",
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def f32_to_tf32_bits(x: Float32, *, loc=None, ip=None) -> Uint32:
+    """Round one float32 value to TF32 format and return its 32-bit operand bits."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(x).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b32 tmp;
+                cvt.rna.tf32.f32 tmp, $1;
+                mov.b32 $0, tmp;
+            }
+            """,
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def tf32_mma_m16n8k8_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Warp MMA helper for `mma.sync.aligned.m16n8k8.row.col.f32.tf32.tf32.f32`."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k8.row.col.f32.tf32.tf32.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def f16_mma_m16n8k16_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Warp MMA helper for `mma.sync.aligned.m16n8k16.row.col.f32.f16.f16.f32`."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.f16.f16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def bf16_mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    b0_0: Uint32,
+    b1_0: Uint32,
+    b0_1: Uint32,
+    b1_1: Uint32,
+    a0: Uint32,
+    a1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """BF16 MMA form used by the routed m-block-size-8 path.
+
+    The dequantized RHS fragments feed the hardware A operand, while the
+    routed activation fragment loaded with `ldmatrix.x2` feeds hardware B.
+    """
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(b0_0).ir_value(loc=loc, ip=ip),
+            Uint32(b1_0).ir_value(loc=loc, ip=ip),
+            Uint32(b0_1).ir_value(loc=loc, ip=ip),
+            Uint32(b1_1).ir_value(loc=loc, ip=ip),
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def f16_mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    b0_0: Uint32,
+    b1_0: Uint32,
+    b0_1: Uint32,
+    b1_1: Uint32,
+    a0: Uint32,
+    a1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """FP16 MMA form used by the routed m-block-size-8 path."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(b0_0).ir_value(loc=loc, ip=ip),
+            Uint32(b1_0).ir_value(loc=loc, ip=ip),
+            Uint32(b0_1).ir_value(loc=loc, ip=ip),
+            Uint32(b1_1).ir_value(loc=loc, ip=ip),
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.f16.f16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def bf16_rowsum_m16k16_f32(
+    d0: Float32,
+    d1: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32]:
+    """Row-sum helper matching FlashInfer's m16k16 BF16 rowsum MMA."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(1065369472).ir_value(loc=loc, ip=ip),
+            Uint32(1065369472).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32
+            {$0, _, $1, _},
+            {$2, $3, $4, $5},
+            {$6, $7},
+            {$0, 0., $1, 0.};
+        }
+        """,
+        "=f,=f,r,r,r,r,r,r,0,1",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1)
+
+
+@dsl_user_op
+def bf16_mma_m16n16k16_f32(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    d4: Float32,
+    d5: Float32,
+    d6: Float32,
+    d7: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    b2: Uint32,
+    b3: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32, Float32, Float32, Float32, Float32]:
+    """Warp MMA helper matching FlashInfer's `m16n16k16` BF16/BF16->F32 wrapper."""
+    result0 = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    result1 = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b2).ir_value(loc=loc, ip=ip),
+            Uint32(b3).ir_value(loc=loc, ip=ip),
+            Float32(d4).ir_value(loc=loc, ip=ip),
+            Float32(d5).ir_value(loc=loc, ip=ip),
+            Float32(d6).ir_value(loc=loc, ip=ip),
+            Float32(d7).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$10, $11, $12, $13};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,f,f,f,f",
+        has_side_effects=True,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result0, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result0, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result0, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result0, [3], loc=loc, ip=ip)
+    r4 = llvm.extractvalue(T.f32(), result1, [0], loc=loc, ip=ip)
+    r5 = llvm.extractvalue(T.f32(), result1, [1], loc=loc, ip=ip)
+    r6 = llvm.extractvalue(T.f32(), result1, [2], loc=loc, ip=ip)
+    r7 = llvm.extractvalue(T.f32(), result1, [3], loc=loc, ip=ip)
+    return (
+        Float32(r0),
+        Float32(r1),
+        Float32(r2),
+        Float32(r3),
+        Float32(r4),
+        Float32(r5),
+        Float32(r6),
+        Float32(r7),
+    )
+
+
+@dsl_user_op
+def mxfp8_mma_m16n8k32_f32_e4m3(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    sfa: Uint32,
+    sfb: Uint32,
+    bid_a: int = 0,
+    tid_a: int = 0,
+    bid_b: int = 0,
+    tid_b: int = 0,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Warp MMA helper for SM120 MXFP8 block-scaled `m16n8k32` E4M3/E4M3."""
+    i16_ty = cutlass._mlir.ir.IntegerType.get_signless(16)
+    bid_a_i16 = cutlass._mlir.ir.Operation.create(
+        "llvm.mlir.constant",
+        results=[i16_ty],
+        attributes={"value": cutlass._mlir.ir.IntegerAttr.get(i16_ty, int(bid_a))},
+    ).result
+    tid_a_i16 = cutlass._mlir.ir.Operation.create(
+        "llvm.mlir.constant",
+        results=[i16_ty],
+        attributes={"value": cutlass._mlir.ir.IntegerAttr.get(i16_ty, int(tid_a))},
+    ).result
+    bid_b_i16 = cutlass._mlir.ir.Operation.create(
+        "llvm.mlir.constant",
+        results=[i16_ty],
+        attributes={"value": cutlass._mlir.ir.IntegerAttr.get(i16_ty, int(bid_b))},
+    ).result
+    tid_b_i16 = cutlass._mlir.ir.Operation.create(
+        "llvm.mlir.constant",
+        results=[i16_ty],
+        attributes={"value": cutlass._mlir.ir.IntegerAttr.get(i16_ty, int(tid_b))},
+    ).result
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Uint32(sfa).ir_value(loc=loc, ip=ip),
+            bid_a_i16,
+            tid_a_i16,
+            Uint32(sfb).ir_value(loc=loc, ip=ip),
+            bid_b_i16,
+            tid_b_i16,
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.kind::mxf8f6f4.block_scale.scale_vec::1X.m16n8k32.row.col.f32.e4m3.e4m3.f32.ue8m0
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$0, $1, $2, $3},
+        {$10},
+        {$11, $12},
+        {$13},
+        {$14, $15};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,r,h,h,r,h,h,0,1,2,3",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+@dsl_user_op
+def mxfp8_mma_m16n8k32_f32_e2m1(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    sfa: Uint32,
+    sfb: Uint32,
+    bid_a: int = 0,
+    tid_a: int = 0,
+    bid_b: int = 0,
+    tid_b: int = 0,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """SM120 block-scaled QMMA with E4M3 A and E2M1 B containers."""
+    asm = f"""
+        mma.sync.aligned.kind::mxf8f6f4.block_scale.scale_vec::1X.m16n8k32.row.col.f32.e4m3.e2m1.f32.ue8m0
+        {{$0, $1, $2, $3}},
+        {{$4, $5, $6, $7}},
+        {{$8, $9}},
+        {{$0, $1, $2, $3}},
+        {{$10}},
+        {{{int(bid_a)}, {int(tid_a)}}},
+        {{$11}},
+        {{{int(bid_b)}, {int(tid_b)}}};
+        """
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Uint32(sfa).ir_value(loc=loc, ip=ip),
+            Uint32(sfb).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        asm,
+        "=f,=f,=f,=f,r,r,r,r,r,r,r,r,0,1,2,3",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return tuple(
+        Float32(llvm.extractvalue(T.f32(), result, [i], loc=loc, ip=ip))
+        for i in range(4)
+    )
+
+
+@dsl_user_op
+def mma_m16n8k32_f32_e4m3(
+    d0: Float32,
+    d1: Float32,
+    d2: Float32,
+    d3: Float32,
+    a0: Uint32,
+    a1: Uint32,
+    a2: Uint32,
+    a3: Uint32,
+    b0: Uint32,
+    b1: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Plain (non-block-scaled) SM120 FP8 E4M3 warp MMA `m16n8k32`.
+
+    d{0..3} are the accumulator IN-OUT (C on input, D on output)."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [
+            Uint32(a0).ir_value(loc=loc, ip=ip),
+            Uint32(a1).ir_value(loc=loc, ip=ip),
+            Uint32(a2).ir_value(loc=loc, ip=ip),
+            Uint32(a3).ir_value(loc=loc, ip=ip),
+            Uint32(b0).ir_value(loc=loc, ip=ip),
+            Uint32(b1).ir_value(loc=loc, ip=ip),
+            Float32(d0).ir_value(loc=loc, ip=ip),
+            Float32(d1).ir_value(loc=loc, ip=ip),
+            Float32(d2).ir_value(loc=loc, ip=ip),
+            Float32(d3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        mma.sync.aligned.m16n8k32.row.col.f32.e4m3.e4m3.f32
+        {$0, $1, $2, $3},
+        {$4, $5, $6, $7},
+        {$8, $9},
+        {$0, $1, $2, $3};
+        """,
+        "=f,=f,=f,=f,r,r,r,r,r,r,0,1,2,3",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    r0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    r1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+    r2 = llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)
+    r3 = llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)
+    return Float32(r0), Float32(r1), Float32(r2), Float32(r3)
+
+
+# ``mma_m16n8k16_f32_bf16`` was proven during the SM120 sparse-MLA port to be
+# bit-identical (same signature, same emitted
+# ``mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32``, same constraint
+# string and operand grouping) to the pre-existing ``bf16_mma_m16n8k16_f32``
+# above. Expose it under the port's name as a thin alias so the sparse-MLA
+# kernels can import it without duplicating the inline asm.
+mma_m16n8k16_f32_bf16 = bf16_mma_m16n8k16_f32
+
+
+@dsl_user_op
+def byte_perm(a: Uint32, b: Uint32, selector: Int32, *, loc=None, ip=None) -> Uint32:
+    """PTX byte permutation helper."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Uint32(a).ir_value(loc=loc, ip=ip),
+                Uint32(b).ir_value(loc=loc, ip=ip),
+                Int32(selector).ir_value(loc=loc, ip=ip),
+            ],
+            "prmt.b32 $0, $1, $2, $3;",
+            "=r,r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@cute.jit
+def frag_layout_swizzle_16b_to_8b(x: Uint32) -> Uint32:
+    tmp = cute.arch.shuffle_sync_bfly(x, offset=1)
+    x = byte_perm(x, tmp, Int32(0x5410 if cute.arch.lane_idx() & 0x1 == 0 else 0x3276))
+    tmp = cute.arch.shuffle_sync_bfly(x, offset=2)
+    x = byte_perm(x, tmp, Int32(0x5410 if cute.arch.lane_idx() & 0x2 == 0 else 0x3276))
+    return x
+
+
+@cute.jit
+def frag_layout_swizzle_16b_to_8b_trans(x: Uint32) -> Uint32:
+    tmp = cute.arch.shuffle_sync_bfly(x, offset=4)
+    x = byte_perm(x, tmp, Int32(0x6420 if cute.arch.lane_idx() & 0x4 == 0 else 0x3175))
+    tmp = cute.arch.shuffle_sync_bfly(x, offset=8)
+    x = byte_perm(x, tmp, Int32(0x5410 if cute.arch.lane_idx() & 0x8 == 0 else 0x3276))
+    tmp = cute.arch.shuffle_sync_bfly(x, offset=16)
+    x = byte_perm(x, tmp, Int32(0x5410 if cute.arch.lane_idx() & 0x10 == 0 else 0x3276))
+    return x
+
+
+@dsl_user_op
+def bfloat2_habs2(x: Uint32, *, loc=None, ip=None) -> Uint32:
+    """BFloat16x2 absolute value - clears sign bits of both bf16 values."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(x).ir_value(loc=loc, ip=ip)],
+            "and.b32 $0, $1, 0x7FFF7FFF;",
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def bfloat2_hmax2(a: Uint32, b: Uint32, *, loc=None, ip=None) -> Uint32:
+    """BFloat16x2 max - element-wise max of 2 bf16 pairs."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(a).ir_value(loc=loc, ip=ip), Uint32(b).ir_value(loc=loc, ip=ip)],
+            "max.bf16x2 $0, $1, $2;",
+            "=r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def bfloat2_hmax_to_f32(x: Uint32, *, loc=None, ip=None) -> Float32:
+    """Extract max of 2 bf16 values in bfloat2 as float32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(x).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b32 lo, hi;
+                .reg .f32 f0, f1;
+                and.b32 lo, $1, 0xFFFF;
+                shr.b32 hi, $1, 16;
+                shl.b32 lo, lo, 16;
+                shl.b32 hi, hi, 16;
+                mov.b32 f0, lo;
+                mov.b32 f1, hi;
+                max.f32 $0, f0, f1;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def bfloat2_to_float2_scaled(
+    bf2: Uint32, scale: Float32, *, loc=None, ip=None
+) -> Tuple[Float32, Float32]:
+    """Convert bfloat16x2 to float2 AND multiply by scale."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32()]),
+        [Uint32(bf2).ir_value(loc=loc, ip=ip), Float32(scale).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 lo, hi;
+            .reg .f32 f0, f1;
+            and.b32 lo, $2, 0xFFFF;
+            shr.b32 hi, $2, 16;
+            shl.b32 lo, lo, 16;
+            shl.b32 hi, hi, 16;
+            mov.b32 f0, lo;
+            mov.b32 f1, hi;
+            mul.f32 $0, f0, $3;
+            mul.f32 $1, f1, $3;
+        }
+        """,
+        "=f,=f,r,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+
+    f0 = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    f1 = llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)
+
+    return Float32(f0), Float32(f1)
+
+
+# =============================================================================
+# FP8 E4M3 Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def cvt_f32_to_e4m3(a: Float32, *, loc=None, ip=None) -> Uint32:
+    """Convert float32 to E4M3 using native cvt.rn.satfinite.e4m3x2.f32."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(a).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 fp8_pair;
+                .reg .f32 zero;
+                mov.f32 zero, 0f00000000;
+                cvt.rn.satfinite.e4m3x2.f32 fp8_pair, zero, $1;
+                cvt.u32.u16 $0, fp8_pair;
+            }
+            """,
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def cvt_f32x4_to_e4m3x4(
+    v0: Float32,
+    v1: Float32,
+    v2: Float32,
+    v3: Float32,
+    *,
+    loc=None,
+    ip=None,
+) -> Uint32:
+    """Convert 4 float32 values to 4 packed E4M3 bytes (v0 in the low byte)."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Float32(v0).ir_value(loc=loc, ip=ip),
+                Float32(v1).ir_value(loc=loc, ip=ip),
+                Float32(v2).ir_value(loc=loc, ip=ip),
+                Float32(v3).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b16 lo, hi;
+                cvt.rn.satfinite.e4m3x2.f32 lo, $2, $1;
+                cvt.rn.satfinite.e4m3x2.f32 hi, $4, $3;
+                mov.b32 $0, {lo, hi};
+            }
+            """,
+            "=r,f,f,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def nvfp4_scale_from_amax(block_amax: Float32, global_scale: Float32, *, loc=None, ip=None) -> Float32:
+    """Compute block_amax * reciprocal_global_scale / 6 with CUDA tensor-scalar semantics."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [
+                Float32(block_amax).ir_value(loc=loc, ip=ip),
+                Float32(global_scale).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .f64 amax_d, gs_d, q_d, six_d;
+                cvt.f64.f32 amax_d, $1;
+                cvt.f64.f32 gs_d, $2;
+                mov.f64 six_d, 0d4018000000000000;
+                mul.rn.f64 q_d, amax_d, gs_d;
+                div.rn.f64 q_d, q_d, six_d;
+                cvt.rn.f32.f64 $0, q_d;
+            }
+            """,
+            "=f,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def fp8_e4m3_to_f32(fp8_val: Uint32, *, loc=None, ip=None) -> Float32:
+    """Convert FP8 E4M3 to float32."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(fp8_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .pred p_zero, p_neg;
+                .reg .u32 sign_u, exp_u, mant_u;
+                .reg .s32 exp_s;
+                .reg .f32 exp_f, mant_f, fp8_float, fp8_neg;
+
+                setp.eq.u32 p_zero, $1, 0;
+                and.b32 sign_u, $1, 0x80;
+                and.b32 mant_u, $1, 7;
+                shr.b32 exp_u, $1, 3;
+                and.b32 exp_u, exp_u, 15;
+                sub.s32 exp_s, exp_u, 7;
+                cvt.rn.f32.s32 exp_f, exp_s;
+                ex2.approx.f32 exp_f, exp_f;
+                cvt.rn.f32.u32 mant_f, mant_u;
+                fma.rn.f32 mant_f, mant_f, 0f3E000000, 0f3F800000;
+                mul.f32 fp8_float, exp_f, mant_f;
+                neg.f32 fp8_neg, fp8_float;
+                setp.ne.u32 p_neg, sign_u, 0;
+                selp.f32 fp8_float, fp8_neg, fp8_float, p_neg;
+                selp.f32 $0, 0f00000000, fp8_float, p_zero;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def fp8_e4m3_to_f32_and_rcp(fp8_val: Uint32, *, loc=None, ip=None) -> Float32:
+    """Convert FP8 E4M3 to float32 AND compute reciprocal."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(fp8_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .pred p_zero;
+                .reg .u32 exp_u, mant_u;
+                .reg .s32 exp_s;
+                .reg .f32 exp_f, mant_f, fp8_float, result;
+
+                setp.eq.u32 p_zero, $1, 0;
+                and.b32 mant_u, $1, 7;
+                shr.b32 exp_u, $1, 3;
+                and.b32 exp_u, exp_u, 15;
+                sub.s32 exp_s, exp_u, 7;
+                cvt.rn.f32.s32 exp_f, exp_s;
+                ex2.approx.f32 exp_f, exp_f;
+                cvt.rn.f32.u32 mant_f, mant_u;
+                fma.rn.f32 mant_f, mant_f, 0f3E000000, 0f3F800000;
+                mul.f32 fp8_float, exp_f, mant_f;
+                rcp.approx.ftz.f32 result, fp8_float;
+                selp.f32 $0, 0f00000000, result, p_zero;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+# =============================================================================
+# E4M3 -> F16/F32 Native Conversion Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def cvt_e4m3x2_to_f16x2_pair(
+    packed_u32: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """Decode 4 e4m3 bytes (packed u32) into 2 x f16x2 pairs."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(i32, i32)>"),
+        [Uint32(packed_u32).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b16 b16_01, b16_23;
+            .reg .b32 hi32;
+            cvt.u16.u32 b16_01, $2;
+            shr.b32 hi32, $2, 16;
+            cvt.u16.u32 b16_23, hi32;
+            cvt.rn.f16x2.e4m3x2 $0, b16_01;
+            cvt.rn.f16x2.e4m3x2 $1, b16_23;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Uint32(llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def f16x2_to_f32x2(
+    packed_h2: Uint32, *, loc=None, ip=None
+) -> Tuple[Float32, Float32]:
+    """Unpack f16x2 (u32) to two f32 values."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(f32, f32)>"),
+        [Uint32(packed_h2).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b16 lo, hi;
+            mov.b32 {lo, hi}, $2;
+            cvt.f32.f16 $0, lo;
+            cvt.f32.f16 $1, hi;
+        }
+        """,
+        "=f,=f,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Float32(llvm.extractvalue(T.f32(), res, [0], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), res, [1], loc=loc, ip=ip)),
+    )
+
+
+@cute.jit
+def cvt_e4m3x4_to_f32x4(
+    packed_u32: Uint32,
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Decode 4 e4m3 bytes (packed u32) to 4 x f32 via hw-native e4m3->f16->f32."""
+    h01, h23 = cvt_e4m3x2_to_f16x2_pair(packed_u32)
+    f0, f1 = f16x2_to_f32x2(h01)
+    f2, f3 = f16x2_to_f32x2(h23)
+    return f0, f1, f2, f3
+
+
+@dsl_user_op
+def cvt_e4m3_to_f32_via_f16(
+    fp8_val: Uint32, *, loc=None, ip=None
+) -> Float32:
+    """Convert single E4M3 byte to f32 via hw-native cvt.rn.f16x2.e4m3x2."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(fp8_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b16 fp8_pair;
+                .reg .b32 h2;
+                .reg .b16 lo, hi;
+                cvt.u16.u32 fp8_pair, $1;
+                cvt.rn.f16x2.e4m3x2 h2, fp8_pair;
+                mov.b32 {lo, hi}, h2;
+                cvt.f32.f16 $0, lo;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def cvt_w4a16_packed_e4m3_scale_to_f32(
+    packed_byte: Uint32, *, loc=None, ip=None
+) -> Float32:
+    """Scalar mirror of packed_dequant_e4m3x4_to_bfloat2x2 for W4A16 scales."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(packed_byte).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b32 bits, tmp;
+                .reg .b16 bf;
+                and.b32 bits, $1, 0x80;
+                shl.b32 bits, bits, 7;
+                and.b32 tmp, $1, 0x7f;
+                shl.b32 tmp, tmp, 4;
+                or.b32 bits, bits, tmp;
+                cvt.u16.u32 bf, bits;
+                cvt.f32.bf16 $0, bf;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def dequant_kv_e4m3_pair_to_bf16x2(
+    p0: Uint16, p1: Uint16, scale_f: Float32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """FP8 -> BF16 K dequant for the BF16-QK m16n8k16 B operand.
+
+    Byte-for-byte mirror of FlashInfer's sparse_mla prefill BF16-QK inline
+    sequence (prefill_kernel.cuh:240-251): two ``cvt.rn.f16x2.e4m3x2`` decode
+    the two e4m3 byte-pairs ``p0``/``p1`` (each a u16 holding two consecutive
+    e4m3 K-dims), multiply the four resulting f16 lanes by the per-(token,blk)
+    UE8M0 ``scale_f`` in f32, then two ``cvt.rn.bf16x2.f32`` pack them back to
+    the bf16x2 ``b0``/``b1`` MMA operands. NON-saturating cvt (matches the
+    reference; the K magnitudes are bounded by the e4m3 range so satfinite is a
+    no-op, and the ref emits plain ``cvt.rn.bf16x2.f32``)."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(i32, i32)>"),
+        [
+            Uint16(p0).ir_value(loc=loc, ip=ip),
+            Uint16(p1).ir_value(loc=loc, ip=ip),
+            Float32(scale_f).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .b32 h2_0, h2_1;
+            .reg .b16 l0, h0, l1, h1;
+            .reg .f32 fk0, fk1, fk2, fk3;
+            cvt.rn.f16x2.e4m3x2 h2_0, $2;
+            cvt.rn.f16x2.e4m3x2 h2_1, $3;
+            mov.b32 {l0, h0}, h2_0;
+            mov.b32 {l1, h1}, h2_1;
+            cvt.f32.f16 fk0, l0;
+            cvt.f32.f16 fk1, h0;
+            cvt.f32.f16 fk2, l1;
+            cvt.f32.f16 fk3, h1;
+            mul.f32 fk0, fk0, $4;
+            mul.f32 fk1, fk1, $4;
+            mul.f32 fk2, fk2, $4;
+            mul.f32 fk3, fk3, $4;
+            cvt.rn.bf16x2.f32 $0, fk1, fk0;
+            cvt.rn.bf16x2.f32 $1, fk3, fk2;
+        }
+        """,
+        "=r,=r,h,h,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Uint32(llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def cvt_e8m0_to_f32(e8m0_val: Uint32, *, loc=None, ip=None) -> Float32:
+    """Convert a single E8M0 scale byte to its true f32 value 2**(byte-127).
+
+    Byte 0 maps to 0.0. Unlike packed_dequant_e8m0x4_* (which fold a 2**7 bias
+    into the MMA input), this returns the unbiased scale so callers can apply it
+    directly in an f32 accumulator.
+    """
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(e8m0_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .pred p0;
+                .reg .u32 b0;
+                .reg .s32 e0;
+                .reg .f32 ef0;
+                and.b32 b0, $1, 0x000000ff;
+                setp.eq.u32 p0, b0, 0;
+                cvt.s32.u32 e0, b0;
+                sub.s32 e0, e0, 127;
+                cvt.rn.f32.s32 ef0, e0;
+                ex2.approx.f32 $0, ef0;
+                selp.f32 $0, 0f00000000, $0, p0;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def cvt_e8m0x4_to_f32x4(
+    packed: Uint32, *, loc=None, ip=None
+) -> Tuple[Float32, Float32, Float32, Float32]:
+    """Decode 4 E8M0 scale bytes (packed u32) to 4 x true f32 (2**(byte-127))."""
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32(), T.f32(), T.f32()]),
+        [Uint32(packed).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .pred p0, p1, p2, p3;
+            .reg .u32 b0, b1, b2, b3;
+            .reg .s32 e0, e1, e2, e3;
+            .reg .f32 ef0, ef1, ef2, ef3;
+            and.b32 b0, $4, 0x000000ff;
+            shr.u32 b1, $4, 8;
+            and.b32 b1, b1, 0x000000ff;
+            shr.u32 b2, $4, 16;
+            and.b32 b2, b2, 0x000000ff;
+            shr.u32 b3, $4, 24;
+            setp.eq.u32 p0, b0, 0;
+            setp.eq.u32 p1, b1, 0;
+            setp.eq.u32 p2, b2, 0;
+            setp.eq.u32 p3, b3, 0;
+            cvt.s32.u32 e0, b0;
+            cvt.s32.u32 e1, b1;
+            cvt.s32.u32 e2, b2;
+            cvt.s32.u32 e3, b3;
+            sub.s32 e0, e0, 127;
+            sub.s32 e1, e1, 127;
+            sub.s32 e2, e2, 127;
+            sub.s32 e3, e3, 127;
+            cvt.rn.f32.s32 ef0, e0;
+            cvt.rn.f32.s32 ef1, e1;
+            cvt.rn.f32.s32 ef2, e2;
+            cvt.rn.f32.s32 ef3, e3;
+            ex2.approx.f32 $0, ef0;
+            ex2.approx.f32 $1, ef1;
+            ex2.approx.f32 $2, ef2;
+            ex2.approx.f32 $3, ef3;
+            selp.f32 $0, 0f00000000, $0, p0;
+            selp.f32 $1, 0f00000000, $1, p1;
+            selp.f32 $2, 0f00000000, $2, p2;
+            selp.f32 $3, 0f00000000, $3, p3;
+        }
+        """,
+        "=f,=f,=f,=f,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Float32(llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), result, [1], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), result, [2], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), result, [3], loc=loc, ip=ip)),
+    )
+
+
+# =============================================================================
+# FP4 (E2M1) Decode Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def fp4_decode_4bytes(
+    packed_u32: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32, Uint32, Uint32]:
+    """Decode 4 FP4 bytes (packed u32) into 4 x f16x2 pairs."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(i32, i32, i32, i32)>"),
+        [Uint32(packed_u32).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b8 byte0, byte1, byte2, byte3;
+            mov.b32 {byte0, byte1, byte2, byte3}, $4;
+            cvt.rn.f16x2.e2m1x2 $0, byte0;
+            cvt.rn.f16x2.e2m1x2 $1, byte1;
+            cvt.rn.f16x2.e2m1x2 $2, byte2;
+            cvt.rn.f16x2.e2m1x2 $3, byte3;
+        }
+        """,
+        "=r,=r,=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Uint32(llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), res, [2], loc=loc, ip=ip)),
+        Uint32(llvm.extractvalue(T.i32(), res, [3], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def fp4_decode_2(byte_val: Uint32, *, loc=None, ip=None) -> Uint32:
+    """Decode 1 FP4 byte into 1 f16x2 pair."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Uint32(byte_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .b8 b0;
+                cvt.u8.u32 b0, $1;
+                cvt.rn.f16x2.e2m1x2 $0, b0;
+            }
+            """,
+            "=r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def e2m1x8_to_qmma_e2m1x8(
+    packed_u32: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """Spread eight packed FP4 nibbles into QMMA E2M1 byte containers.
+
+    The SM120 f8f6f4 instruction expects one E2M1 value per byte with the
+    original nibble in bits 5:2.  This six-instruction spread is cheaper than
+    losslessly relabeling every value as E4M3 when no residual multiplier is
+    required.
+    """
+    res = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed_u32).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 s, t;
+            shl.b32 s, $2, 2;
+            shr.u32 t, $2, 2;
+            prmt.b32 $0, s, t, 0x5140;
+            prmt.b32 $1, s, t, 0x7362;
+            and.b32 $0, $0, 0x3C3C3C3C;
+            and.b32 $1, $1, 0x3C3C3C3C;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def e2m1x8_to_e4m3x8(
+    packed_u32: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """Expand 8 packed E2M1 nibbles into 8 E4M3 bytes, losslessly.
+
+    Every E2M1 value is exactly representable in E4M3, so this is a pure
+    relabeling done with two prmt magnitude-LUT lookups plus a sign pass.
+    Nibble i of the input becomes byte i of the (lo, hi) output pair.
+    """
+    res = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [Uint32(packed_u32).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .b32 clo, chi, cslo, cshi, mlo, mhi, slo, shi;
+            .reg .b32 tbl_a, tbl_b, tbl_s, zero;
+            // E4M3 encodings of {0, .5, 1, 1.5, 2, 3, 4, 6}.
+            mov.b32 tbl_a, 0x3C383000;
+            mov.b32 tbl_b, 0x4C484440;
+            mov.b32 tbl_s, 0x00008000;
+            mov.b32 zero, 0;
+            // Magnitude codes (low 3 bits of each nibble) as prmt selectors.
+            and.b32 clo, $2, 0x00007777;
+            shr.u32 chi, $2, 16;
+            and.b32 chi, chi, 0x00007777;
+            prmt.b32 mlo, tbl_a, tbl_b, clo;
+            prmt.b32 mhi, tbl_a, tbl_b, chi;
+            // Sign bit (nibble bit 3) -> byte bit 7 via a 2-entry LUT.
+            shr.u32 cslo, $2, 3;
+            and.b32 cslo, cslo, 0x00001111;
+            shr.u32 cshi, $2, 19;
+            and.b32 cshi, cshi, 0x00001111;
+            prmt.b32 slo, tbl_s, zero, cslo;
+            prmt.b32 shi, tbl_s, zero, cshi;
+            or.b32 $0, mlo, slo;
+            or.b32 $1, mhi, shi;
+        }
+        """,
+        "=r,=r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def e2m1x8_mul_residual_to_e4m3x8(
+    packed_u32: Uint32, residual_h2: Uint32, *, loc=None, ip=None
+) -> Tuple[Uint32, Uint32]:
+    """Expand 8 E2M1 nibbles to E4M3 bytes with a residual multiplier.
+
+    Decodes to f16 pairs, multiplies by ``residual_h2`` (the same residual
+    broadcast to both f16 lanes), and rounds to E4M3.  Used by the w4a8
+    NVFP4 path where the per-K/16 e4m3 scale is decomposed into a shared
+    UE8M0 hardware exponent and this in-register residual.
+    """
+    res = llvm.inline_asm(
+        llvm.StructType.get_literal([T.i32(), T.i32()]),
+        [
+            Uint32(packed_u32).ir_value(loc=loc, ip=ip),
+            Uint32(residual_h2).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .b8 b0, b1, b2, b3;
+            .reg .b32 h0, h1, h2, h3;
+            .reg .b16 e0, e1, e2, e3;
+            mov.b32 {b0, b1, b2, b3}, $2;
+            cvt.rn.f16x2.e2m1x2 h0, b0;
+            cvt.rn.f16x2.e2m1x2 h1, b1;
+            cvt.rn.f16x2.e2m1x2 h2, b2;
+            cvt.rn.f16x2.e2m1x2 h3, b3;
+            mul.f16x2 h0, h0, $3;
+            mul.f16x2 h1, h1, $3;
+            mul.f16x2 h2, h2, $3;
+            mul.f16x2 h3, h3, $3;
+            cvt.rn.satfinite.e4m3x2.f16x2 e0, h0;
+            cvt.rn.satfinite.e4m3x2.f16x2 e1, h1;
+            cvt.rn.satfinite.e4m3x2.f16x2 e2, h2;
+            cvt.rn.satfinite.e4m3x2.f16x2 e3, h3;
+            mov.b32 $0, {e0, e1};
+            mov.b32 $1, {e2, e3};
+        }
+        """,
+        "=r,=r,r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    lo = llvm.extractvalue(T.i32(), res, [0], loc=loc, ip=ip)
+    hi = llvm.extractvalue(T.i32(), res, [1], loc=loc, ip=ip)
+    return Uint32(lo), Uint32(hi)
+
+
+@dsl_user_op
+def cvt_fp32x2_to_e2m1x2(v0: Float32, v1: Float32, *, loc=None, ip=None) -> Uint32:
+    """Convert 2 x f32 to 1 x FP4 (E2M1) byte."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Float32(v0).ir_value(loc=loc, ip=ip),
+                Float32(v1).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b8 b;
+                cvt.rn.satfinite.e2m1x2.f32 b, $2, $1;
+                cvt.u32.u8 $0, b;
+            }
+            """,
+            "=r,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@cute.jit
+def quant_dequant_2(
+    v0: Float32, v1: Float32, sf_f32: Float32, eff_scale: Float32
+) -> Tuple[Float32, Float32]:
+    """Quantize-dequantize pair roundtrip through FP4."""
+    inv_scale = Float32(1.0) / eff_scale
+    fp4_byte = cvt_fp32x2_to_e2m1x2(v0 * inv_scale, v1 * inv_scale)
+    h2 = fp4_decode_2(fp4_byte)
+    f0, f1 = f16x2_to_f32x2(h2)
+    return f0 * sf_f32, f1 * sf_f32
+
+
+# =============================================================================
+# Half2 FMA Dot Product Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def hfma2_4(
+    w0: Uint32, x0: Uint32,
+    w1: Uint32, x1: Uint32,
+    w2: Uint32, x2: Uint32,
+    w3: Uint32, x3: Uint32,
+    *, loc=None, ip=None
+) -> Tuple[Float32, Float32]:
+    """4-element half2 FMA dot product returning (lo, hi) f32."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(f32, f32)>"),
+        [
+            Uint32(w0).ir_value(loc=loc, ip=ip), Uint32(x0).ir_value(loc=loc, ip=ip),
+            Uint32(w1).ir_value(loc=loc, ip=ip), Uint32(x1).ir_value(loc=loc, ip=ip),
+            Uint32(w2).ir_value(loc=loc, ip=ip), Uint32(x2).ir_value(loc=loc, ip=ip),
+            Uint32(w3).ir_value(loc=loc, ip=ip), Uint32(x3).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .f16x2 acc;
+            .reg .b16 lo, hi;
+            mov.b32 acc, 0;
+            fma.rn.f16x2 acc, $2, $3, acc;
+            fma.rn.f16x2 acc, $4, $5, acc;
+            fma.rn.f16x2 acc, $6, $7, acc;
+            fma.rn.f16x2 acc, $8, $9, acc;
+            mov.b32 {lo, hi}, acc;
+            cvt.f32.f16 $0, lo;
+            cvt.f32.f16 $1, hi;
+        }
+        """,
+        "=f,=f,r,r,r,r,r,r,r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Float32(llvm.extractvalue(T.f32(), res, [0], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), res, [1], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def hfma2_4_sum(
+    w0: Uint32, x0: Uint32,
+    w1: Uint32, x1: Uint32,
+    w2: Uint32, x2: Uint32,
+    w3: Uint32, x3: Uint32,
+    *, loc=None, ip=None
+) -> Float32:
+    """4-element half2 FMA dot product returning lane sum."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [
+                Uint32(w0).ir_value(loc=loc, ip=ip), Uint32(x0).ir_value(loc=loc, ip=ip),
+                Uint32(w1).ir_value(loc=loc, ip=ip), Uint32(x1).ir_value(loc=loc, ip=ip),
+                Uint32(w2).ir_value(loc=loc, ip=ip), Uint32(x2).ir_value(loc=loc, ip=ip),
+                Uint32(w3).ir_value(loc=loc, ip=ip), Uint32(x3).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .f16x2 acc;
+                .reg .b16 lo, hi;
+                .reg .f32 flo, fhi;
+                mov.b32 acc, 0;
+                fma.rn.f16x2 acc, $1, $2, acc;
+                fma.rn.f16x2 acc, $3, $4, acc;
+                fma.rn.f16x2 acc, $5, $6, acc;
+                fma.rn.f16x2 acc, $7, $8, acc;
+                mov.b32 {lo, hi}, acc;
+                cvt.f32.f16 flo, lo;
+                cvt.f32.f16 fhi, hi;
+                add.f32 $0, flo, fhi;
+            }
+            """,
+            "=f,r,r,r,r,r,r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def hfma2_8(
+    w0: Uint32, x0: Uint32,
+    w1: Uint32, x1: Uint32,
+    w2: Uint32, x2: Uint32,
+    w3: Uint32, x3: Uint32,
+    w4: Uint32, x4: Uint32,
+    w5: Uint32, x5: Uint32,
+    w6: Uint32, x6: Uint32,
+    w7: Uint32, x7: Uint32,
+    *, loc=None, ip=None
+) -> Tuple[Float32, Float32]:
+    """8-element half2 FMA dot product returning (lo, hi) f32."""
+    res = llvm.inline_asm(
+        ir.Type.parse("!llvm.struct<(f32, f32)>"),
+        [
+            Uint32(w0).ir_value(loc=loc, ip=ip), Uint32(x0).ir_value(loc=loc, ip=ip),
+            Uint32(w1).ir_value(loc=loc, ip=ip), Uint32(x1).ir_value(loc=loc, ip=ip),
+            Uint32(w2).ir_value(loc=loc, ip=ip), Uint32(x2).ir_value(loc=loc, ip=ip),
+            Uint32(w3).ir_value(loc=loc, ip=ip), Uint32(x3).ir_value(loc=loc, ip=ip),
+            Uint32(w4).ir_value(loc=loc, ip=ip), Uint32(x4).ir_value(loc=loc, ip=ip),
+            Uint32(w5).ir_value(loc=loc, ip=ip), Uint32(x5).ir_value(loc=loc, ip=ip),
+            Uint32(w6).ir_value(loc=loc, ip=ip), Uint32(x6).ir_value(loc=loc, ip=ip),
+            Uint32(w7).ir_value(loc=loc, ip=ip), Uint32(x7).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .f16x2 acc;
+            .reg .b16 lo, hi;
+            mov.b32 acc, 0;
+            fma.rn.f16x2 acc, $2, $3, acc;
+            fma.rn.f16x2 acc, $4, $5, acc;
+            fma.rn.f16x2 acc, $6, $7, acc;
+            fma.rn.f16x2 acc, $8, $9, acc;
+            fma.rn.f16x2 acc, $10, $11, acc;
+            fma.rn.f16x2 acc, $12, $13, acc;
+            fma.rn.f16x2 acc, $14, $15, acc;
+            fma.rn.f16x2 acc, $16, $17, acc;
+            mov.b32 {lo, hi}, acc;
+            cvt.f32.f16 $0, lo;
+            cvt.f32.f16 $1, hi;
+        }
+        """,
+        "=f,=f,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    return (
+        Float32(llvm.extractvalue(T.f32(), res, [0], loc=loc, ip=ip)),
+        Float32(llvm.extractvalue(T.f32(), res, [1], loc=loc, ip=ip)),
+    )
+
+
+@dsl_user_op
+def hfma2_8_sum(
+    w0: Uint32, x0: Uint32,
+    w1: Uint32, x1: Uint32,
+    w2: Uint32, x2: Uint32,
+    w3: Uint32, x3: Uint32,
+    w4: Uint32, x4: Uint32,
+    w5: Uint32, x5: Uint32,
+    w6: Uint32, x6: Uint32,
+    w7: Uint32, x7: Uint32,
+    *, loc=None, ip=None
+) -> Float32:
+    """8-element half2 FMA dot product returning lane sum."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [
+                Uint32(w0).ir_value(loc=loc, ip=ip), Uint32(x0).ir_value(loc=loc, ip=ip),
+                Uint32(w1).ir_value(loc=loc, ip=ip), Uint32(x1).ir_value(loc=loc, ip=ip),
+                Uint32(w2).ir_value(loc=loc, ip=ip), Uint32(x2).ir_value(loc=loc, ip=ip),
+                Uint32(w3).ir_value(loc=loc, ip=ip), Uint32(x3).ir_value(loc=loc, ip=ip),
+                Uint32(w4).ir_value(loc=loc, ip=ip), Uint32(x4).ir_value(loc=loc, ip=ip),
+                Uint32(w5).ir_value(loc=loc, ip=ip), Uint32(x5).ir_value(loc=loc, ip=ip),
+                Uint32(w6).ir_value(loc=loc, ip=ip), Uint32(x6).ir_value(loc=loc, ip=ip),
+                Uint32(w7).ir_value(loc=loc, ip=ip), Uint32(x7).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .f16x2 acc;
+                .reg .b16 lo, hi;
+                .reg .f32 flo, fhi;
+                mov.b32 acc, 0;
+                fma.rn.f16x2 acc, $1, $2, acc;
+                fma.rn.f16x2 acc, $3, $4, acc;
+                fma.rn.f16x2 acc, $5, $6, acc;
+                fma.rn.f16x2 acc, $7, $8, acc;
+                fma.rn.f16x2 acc, $9, $10, acc;
+                fma.rn.f16x2 acc, $11, $12, acc;
+                fma.rn.f16x2 acc, $13, $14, acc;
+                fma.rn.f16x2 acc, $15, $16, acc;
+                mov.b32 {lo, hi}, acc;
+                cvt.f32.f16 flo, lo;
+                cvt.f32.f16 fhi, hi;
+                add.f32 $0, flo, fhi;
+            }
+            """,
+            "=f,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+# =============================================================================
+# FP4 Dot Product Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def fp4_dot4_sum(
+    u_packed: Uint32,
+    x0: Uint32,
+    x1: Uint32,
+    x2: Uint32,
+    x3: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Float32:
+    """FP4 dot product: decode 4 FP4 bytes and dot with 4 x f16x2 inputs."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [
+                Uint32(u_packed).ir_value(loc=loc, ip=ip),
+                Uint32(x0).ir_value(loc=loc, ip=ip),
+                Uint32(x1).ir_value(loc=loc, ip=ip),
+                Uint32(x2).ir_value(loc=loc, ip=ip),
+                Uint32(x3).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b8 b0, b1, b2, b3;
+                .reg .b32 h0, h1, h2, h3;
+                .reg .f16x2 acc;
+                .reg .b16 lo, hi;
+                .reg .f32 flo, fhi;
+                mov.b32 {b0, b1, b2, b3}, $1;
+                cvt.rn.f16x2.e2m1x2 h0, b0;
+                cvt.rn.f16x2.e2m1x2 h1, b1;
+                cvt.rn.f16x2.e2m1x2 h2, b2;
+                cvt.rn.f16x2.e2m1x2 h3, b3;
+                mov.b32 acc, 0;
+                fma.rn.f16x2 acc, h0, $2, acc;
+                fma.rn.f16x2 acc, h1, $3, acc;
+                fma.rn.f16x2 acc, h2, $4, acc;
+                fma.rn.f16x2 acc, h3, $5, acc;
+                mov.b32 {lo, hi}, acc;
+                cvt.f32.f16 flo, lo;
+                cvt.f32.f16 fhi, hi;
+                add.f32 $0, flo, fhi;
+            }
+            """,
+            "=f,r,r,r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@dsl_user_op
+def fp4_dot8_dual_sum(
+    up_a: Uint32,
+    up_b: Uint32,
+    gate_a: Uint32,
+    gate_b: Uint32,
+    x0: Uint32,
+    x1: Uint32,
+    x2: Uint32,
+    x3: Uint32,
+    x4: Uint32,
+    x5: Uint32,
+    x6: Uint32,
+    x7: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Float32]:
+    """Fused dual FP4 dot product (up + gate) over the SAME 8 shared f16x2
+    activation words. Decodes both weight rows and runs two INDEPENDENT
+    f16x2 accumulator chains in a single inline-asm block, then reduces each
+    to f32. Bit-identical to running fp4_dot8_sum twice (same per-chain fma
+    order, same lo+hi f32 reduction) but emits one asm block so ptxas can
+    interleave the two independent fma chains for 2-way ILP and halves the
+    per-pair epilogue (mov/cvt/add) op count on the issue-bound decode loop."""
+    res = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.f32()]),
+        [
+            Uint32(up_a).ir_value(loc=loc, ip=ip),
+            Uint32(up_b).ir_value(loc=loc, ip=ip),
+            Uint32(gate_a).ir_value(loc=loc, ip=ip),
+            Uint32(gate_b).ir_value(loc=loc, ip=ip),
+            Uint32(x0).ir_value(loc=loc, ip=ip),
+            Uint32(x1).ir_value(loc=loc, ip=ip),
+            Uint32(x2).ir_value(loc=loc, ip=ip),
+            Uint32(x3).ir_value(loc=loc, ip=ip),
+            Uint32(x4).ir_value(loc=loc, ip=ip),
+            Uint32(x5).ir_value(loc=loc, ip=ip),
+            Uint32(x6).ir_value(loc=loc, ip=ip),
+            Uint32(x7).ir_value(loc=loc, ip=ip),
+        ],
+        """
+        {
+            .reg .b8 ua0, ua1, ua2, ua3, ub0, ub1, ub2, ub3;
+            .reg .b8 ga0, ga1, ga2, ga3, gb0, gb1, gb2, gb3;
+            .reg .b32 uh0, uh1, uh2, uh3, uh4, uh5, uh6, uh7;
+            .reg .b32 gh0, gh1, gh2, gh3, gh4, gh5, gh6, gh7;
+            .reg .f16x2 uacc, gacc;
+            .reg .b16 ulo, uhi, glo, ghi;
+            .reg .f32 uflo, ufhi, gflo, gfhi;
+            mov.b32 {ua0, ua1, ua2, ua3}, $2;
+            mov.b32 {ub0, ub1, ub2, ub3}, $3;
+            mov.b32 {ga0, ga1, ga2, ga3}, $4;
+            mov.b32 {gb0, gb1, gb2, gb3}, $5;
+            cvt.rn.f16x2.e2m1x2 uh0, ua0;
+            cvt.rn.f16x2.e2m1x2 uh1, ua1;
+            cvt.rn.f16x2.e2m1x2 uh2, ua2;
+            cvt.rn.f16x2.e2m1x2 uh3, ua3;
+            cvt.rn.f16x2.e2m1x2 uh4, ub0;
+            cvt.rn.f16x2.e2m1x2 uh5, ub1;
+            cvt.rn.f16x2.e2m1x2 uh6, ub2;
+            cvt.rn.f16x2.e2m1x2 uh7, ub3;
+            cvt.rn.f16x2.e2m1x2 gh0, ga0;
+            cvt.rn.f16x2.e2m1x2 gh1, ga1;
+            cvt.rn.f16x2.e2m1x2 gh2, ga2;
+            cvt.rn.f16x2.e2m1x2 gh3, ga3;
+            cvt.rn.f16x2.e2m1x2 gh4, gb0;
+            cvt.rn.f16x2.e2m1x2 gh5, gb1;
+            cvt.rn.f16x2.e2m1x2 gh6, gb2;
+            cvt.rn.f16x2.e2m1x2 gh7, gb3;
+            mov.b32 uacc, 0;
+            mov.b32 gacc, 0;
+            fma.rn.f16x2 uacc, uh0, $6, uacc;
+            fma.rn.f16x2 gacc, gh0, $6, gacc;
+            fma.rn.f16x2 uacc, uh1, $7, uacc;
+            fma.rn.f16x2 gacc, gh1, $7, gacc;
+            fma.rn.f16x2 uacc, uh2, $8, uacc;
+            fma.rn.f16x2 gacc, gh2, $8, gacc;
+            fma.rn.f16x2 uacc, uh3, $9, uacc;
+            fma.rn.f16x2 gacc, gh3, $9, gacc;
+            fma.rn.f16x2 uacc, uh4, $10, uacc;
+            fma.rn.f16x2 gacc, gh4, $10, gacc;
+            fma.rn.f16x2 uacc, uh5, $11, uacc;
+            fma.rn.f16x2 gacc, gh5, $11, gacc;
+            fma.rn.f16x2 uacc, uh6, $12, uacc;
+            fma.rn.f16x2 gacc, gh6, $12, gacc;
+            fma.rn.f16x2 uacc, uh7, $13, uacc;
+            fma.rn.f16x2 gacc, gh7, $13, gacc;
+            mov.b32 {ulo, uhi}, uacc;
+            mov.b32 {glo, ghi}, gacc;
+            cvt.f32.f16 uflo, ulo;
+            cvt.f32.f16 ufhi, uhi;
+            cvt.f32.f16 gflo, glo;
+            cvt.f32.f16 gfhi, ghi;
+            add.f32 $0, uflo, ufhi;
+            add.f32 $1, gflo, gfhi;
+        }
+        """,
+        "=f,=f,r,r,r,r,r,r,r,r,r,r,r,r",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    up = Float32(llvm.extractvalue(T.f32(), res, [0], loc=loc, ip=ip))
+    gate = Float32(llvm.extractvalue(T.f32(), res, [1], loc=loc, ip=ip))
+    return up, gate
+
+
+@dsl_user_op
+def fp4_dot8_sum(
+    u_a: Uint32,
+    u_b: Uint32,
+    x0: Uint32,
+    x1: Uint32,
+    x2: Uint32,
+    x3: Uint32,
+    x4: Uint32,
+    x5: Uint32,
+    x6: Uint32,
+    x7: Uint32,
+    *,
+    loc=None,
+    ip=None,
+) -> Float32:
+    """FP4 dot product: decode 8 FP4 bytes (2 x u32) and dot with 8 x f16x2 inputs."""
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [
+                Uint32(u_a).ir_value(loc=loc, ip=ip),
+                Uint32(u_b).ir_value(loc=loc, ip=ip),
+                Uint32(x0).ir_value(loc=loc, ip=ip),
+                Uint32(x1).ir_value(loc=loc, ip=ip),
+                Uint32(x2).ir_value(loc=loc, ip=ip),
+                Uint32(x3).ir_value(loc=loc, ip=ip),
+                Uint32(x4).ir_value(loc=loc, ip=ip),
+                Uint32(x5).ir_value(loc=loc, ip=ip),
+                Uint32(x6).ir_value(loc=loc, ip=ip),
+                Uint32(x7).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b8 a0, a1, a2, a3;
+                .reg .b8 b0, b1, b2, b3;
+                .reg .b32 h0, h1, h2, h3, h4, h5, h6, h7;
+                .reg .f16x2 acc;
+                .reg .b16 lo, hi;
+                .reg .f32 flo, fhi;
+                mov.b32 {a0, a1, a2, a3}, $1;
+                mov.b32 {b0, b1, b2, b3}, $2;
+                cvt.rn.f16x2.e2m1x2 h0, a0;
+                cvt.rn.f16x2.e2m1x2 h1, a1;
+                cvt.rn.f16x2.e2m1x2 h2, a2;
+                cvt.rn.f16x2.e2m1x2 h3, a3;
+                cvt.rn.f16x2.e2m1x2 h4, b0;
+                cvt.rn.f16x2.e2m1x2 h5, b1;
+                cvt.rn.f16x2.e2m1x2 h6, b2;
+                cvt.rn.f16x2.e2m1x2 h7, b3;
+                mov.b32 acc, 0;
+                fma.rn.f16x2 acc, h0, $3, acc;
+                fma.rn.f16x2 acc, h1, $4, acc;
+                fma.rn.f16x2 acc, h2, $5, acc;
+                fma.rn.f16x2 acc, h3, $6, acc;
+                fma.rn.f16x2 acc, h4, $7, acc;
+                fma.rn.f16x2 acc, h5, $8, acc;
+                fma.rn.f16x2 acc, h6, $9, acc;
+                fma.rn.f16x2 acc, h7, $10, acc;
+                mov.b32 {lo, hi}, acc;
+                cvt.f32.f16 flo, lo;
+                cvt.f32.f16 fhi, hi;
+                add.f32 $0, flo, fhi;
+            }
+            """,
+            "=f,r,r,r,r,r,r,r,r,r,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+@cute.jit
+def _f16x2_dot_sum_f32acc(a_h2: Uint32, b_h2: Uint32) -> Float32:
+    a0, a1 = f16x2_to_f32x2(a_h2)
+    b0, b1 = f16x2_to_f32x2(b_h2)
+    return a0 * b0 + a1 * b1
+
+
+@cute.jit
+def fp4_dot4_sum_f32acc(
+    u_packed: Uint32,
+    x0: Uint32,
+    x1: Uint32,
+    x2: Uint32,
+    x3: Uint32,
+) -> Float32:
+    """FP4 dot product using f32 accumulation after FP4 decode."""
+    h0, h1, h2, h3 = fp4_decode_4bytes(u_packed)
+    return (
+        _f16x2_dot_sum_f32acc(h0, x0)
+        + _f16x2_dot_sum_f32acc(h1, x1)
+        + _f16x2_dot_sum_f32acc(h2, x2)
+        + _f16x2_dot_sum_f32acc(h3, x3)
+    )
+
+
+@cute.jit
+def fp4_dot8_sum_f32acc(
+    u_a: Uint32,
+    u_b: Uint32,
+    x0: Uint32,
+    x1: Uint32,
+    x2: Uint32,
+    x3: Uint32,
+    x4: Uint32,
+    x5: Uint32,
+    x6: Uint32,
+    x7: Uint32,
+) -> Float32:
+    """FP4 dot product using f32 accumulation after FP4 decode."""
+    h0, h1, h2, h3 = fp4_decode_4bytes(u_a)
+    h4, h5, h6, h7 = fp4_decode_4bytes(u_b)
+    return (
+        _f16x2_dot_sum_f32acc(h0, x0)
+        + _f16x2_dot_sum_f32acc(h1, x1)
+        + _f16x2_dot_sum_f32acc(h2, x2)
+        + _f16x2_dot_sum_f32acc(h3, x3)
+        + _f16x2_dot_sum_f32acc(h4, x4)
+        + _f16x2_dot_sum_f32acc(h5, x5)
+        + _f16x2_dot_sum_f32acc(h6, x6)
+        + _f16x2_dot_sum_f32acc(h7, x7)
+    )
+
+
+# =============================================================================
+# Pack Intrinsics
+# =============================================================================
+
+
+@dsl_user_op
+def pack_f32x2_to_f16x2(
+    a: Float32, b: Float32, *, loc=None, ip=None
+) -> Uint32:
+    """Pack two f32 values into one f16x2 u32."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Float32(a).ir_value(loc=loc, ip=ip),
+                Float32(b).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b16 lo, hi;
+                cvt.rn.f16.f32 lo, $1;
+                cvt.rn.f16.f32 hi, $2;
+                mov.b32 $0, {lo, hi};
+            }
+            """,
+            "=r,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+            loc=loc,
+            ip=ip,
+        )
+    )
+
+
+# =============================================================================
+# UE8M0 Intrinsics (for MXFP4)
+# =============================================================================
+
+
+@dsl_user_op
+def pow2_ceil_ue8m0(
+    scale: Float32,
+    *,
+    loc=None,
+    ip=None,
+) -> Tuple[Float32, Uint32]:
+    """Round a positive FP32 ``scale`` UP to a power of two, bit-exactly.
+
+    Returns ``(rounded_fp32, ue8m0_byte)`` where:
+      * ``rounded_fp32`` == ``__uint_as_float(power_of_2_round(__float_as_uint(scale)))``
+      * ``ue8m0_byte``   == ``(__float_as_uint(rounded_fp32) >> 23) & 0xFF``
+
+    Bit-exact replica of FlashInfer's fp8_quant.cuh rounding +
+    scale_convert.cuh fp32_to_ue8m0. Integer ops only (no lg2.approx), so unlike
+    ``cvt_f32_to_ue8m0`` it matches the FlashInfer reference bit-for-bit.
+    """
+    result = llvm.inline_asm(
+        llvm.StructType.get_literal([T.f32(), T.i32()]),
+        [Float32(scale).ir_value(loc=loc, ip=ip)],
+        """
+        {
+            .reg .pred  p_mant;
+            .reg .b32   bits, mant;
+
+            // bits = __float_as_uint(scale)
+            mov.b32 bits, $2;
+            // mant = bits & 0x007FFFFF  (mantissa field)
+            and.b32 mant, bits, 8388607;
+            setp.ne.u32 p_mant, mant, 0;
+            // if (mant) bits = (bits + 0x00800000) & 0x7F800000
+            @p_mant add.u32 bits, bits, 8388608;
+            @p_mant and.b32 bits, bits, 2139095040;
+            // rounded fp32 scale = __uint_as_float(bits)
+            mov.b32 $0, bits;
+            // ue8m0 = (bits >> 23) & 0xFF
+            bfe.u32 $1, bits, 23, 8;
+        }
+        """,
+        "=f,=r,f",
+        has_side_effects=False,
+        is_align_stack=False,
+        asm_dialect=llvm.AsmDialect.AD_ATT,
+        loc=loc,
+        ip=ip,
+    )
+    rounded = llvm.extractvalue(T.f32(), result, [0], loc=loc, ip=ip)
+    ue8m0 = llvm.extractvalue(T.i32(), result, [1], loc=loc, ip=ip)
+    return Float32(rounded), Uint32(ue8m0)
+
+
+@dsl_user_op
+def cvt_f32_to_ue8m0(max_val: Float32, *, loc=None, ip=None) -> Uint32:
+    """
+    Convert float32 max value to UE8M0 scale factor.
+
+    UE8M0 is unsigned 8-bit exponent-only format:
+    - value = 2^(ue8m0 - 127)
+    - ue8m0 = ceil(log2(max_val)) + 127
+
+    Uses lg2.approx.f32 for fast log2 approximation.
+    Uses cvt.rpi (round towards positive infinity, i.e., ceiling).
+    Returns value clamped to [0, 255].
+    """
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [Float32(max_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .pred p_zero, p_neg, p_ovf;
+                .reg .f32 log2_val;
+                .reg .s32 exp_int, result;
+
+                // Check for zero/negative
+                setp.le.f32 p_zero, $1, 0f00000000;
+
+                // Compute ceil(log2(max_val)) using cvt.rpi (round towards +inf)
+                lg2.approx.f32 log2_val, $1;
+                cvt.rpi.s32.f32 exp_int, log2_val;
+
+                // Add bias and clamp to [0, 255]
+                add.s32 result, exp_int, 127;
+                setp.lt.s32 p_neg, result, 0;
+                setp.gt.s32 p_ovf, result, 255;
+                selp.s32 result, 0, result, p_neg;
+                selp.s32 result, 255, result, p_ovf;
+                selp.s32 $0, 0, result, p_zero;
+            }
+            """,
+            "=r,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+@dsl_user_op
+def ue8m0_to_output_scale(ue8m0_val: Uint32, *, loc=None, ip=None) -> Float32:
+    """
+    Convert UE8M0 to output_scale for MXFP4 quantization.
+
+    UE8M0 value = 2^(ue8m0 - 127)
+    Returns 1 / 2^(ue8m0 - 127) = 2^(127 - ue8m0)
+    """
+    return Float32(
+        llvm.inline_asm(
+            T.f32(),
+            [Uint32(ue8m0_val).ir_value(loc=loc, ip=ip)],
+            """
+            {
+                .reg .pred p_zero;
+                .reg .s32 neg_exp;
+                .reg .f32 neg_exp_f, result;
+
+                // Check for zero
+                setp.eq.u32 p_zero, $1, 0;
+
+                // Compute 2^(127 - ue8m0) = 1 / 2^(ue8m0 - 127)
+                sub.s32 neg_exp, 127, $1;
+                cvt.rn.f32.s32 neg_exp_f, neg_exp;
+                ex2.approx.f32 result, neg_exp_f;
+                selp.f32 $0, 0f00000000, result, p_zero;
+            }
+            """,
+            "=f,r",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+# =============================================================================
+# E2M1 Conversion
+# =============================================================================
+
+
+@dsl_user_op
+def cvt_e2m1x8_f32(
+    v0: Float32,
+    v1: Float32,
+    v2: Float32,
+    v3: Float32,
+    v4: Float32,
+    v5: Float32,
+    v6: Float32,
+    v7: Float32,
+    *,
+    loc=None,
+    ip=None,
+) -> Uint32:
+    """Convert eight float32 values to eight E2M1 (4-bit) values packed into uint32."""
+    return Uint32(
+        llvm.inline_asm(
+            T.i32(),
+            [
+                Float32(v0).ir_value(loc=loc, ip=ip),
+                Float32(v1).ir_value(loc=loc, ip=ip),
+                Float32(v2).ir_value(loc=loc, ip=ip),
+                Float32(v3).ir_value(loc=loc, ip=ip),
+                Float32(v4).ir_value(loc=loc, ip=ip),
+                Float32(v5).ir_value(loc=loc, ip=ip),
+                Float32(v6).ir_value(loc=loc, ip=ip),
+                Float32(v7).ir_value(loc=loc, ip=ip),
+            ],
+            """
+            {
+                .reg .b8 byte0, byte1, byte2, byte3;
+                cvt.rn.satfinite.e2m1x2.f32 byte0, $2, $1;
+                cvt.rn.satfinite.e2m1x2.f32 byte1, $4, $3;
+                cvt.rn.satfinite.e2m1x2.f32 byte2, $6, $5;
+                cvt.rn.satfinite.e2m1x2.f32 byte3, $8, $7;
+                mov.b32 $0, {byte0, byte1, byte2, byte3};
+            }
+            """,
+            "=r,f,f,f,f,f,f,f,f",
+            has_side_effects=False,
+            is_align_stack=False,
+            asm_dialect=llvm.AsmDialect.AD_ATT,
+        )
+    )
+
+
+# =============================================================================
+# Warp, Block, and Cluster Reduction Utilities
+# =============================================================================
+
+
+@cute.jit
+def warp_reduce(val, op, width: cutlass.Constexpr[int] = 32):
+    """Reduce across threads in a warp using butterfly shuffle."""
+    if cutlass.const_expr(isinstance(val, cute.TensorSSA)):
+        res = cute.make_rmem_tensor(val.shape, val.dtype)
+        res.store(val)
+        for i in cutlass.range_constexpr(cute.size(val.shape)):
+            res[i] = warp_reduce(res[i], op, width)
+        return res.load()
+    else:
+        for i in cutlass.range_constexpr(int(math.log2(width))):
+            val = op(val, cute.arch.shuffle_sync_bfly(val, offset=1 << i))
+        return val
+
+
+@cute.jit
+def block_reduce(
+    val: Float32,
+    op: Callable,
+    reduction_buffer: cute.Tensor,
+    init_val: Float32,
+) -> Float32:
+    """Block reduction across multiple warps using shared memory."""
+    lane_idx = cute.arch.lane_idx()
+    warp_idx = cute.arch.warp_idx()
+    warps_per_row = cute.size(reduction_buffer.shape[1])
+    row_idx = warp_idx // warps_per_row
+    col_idx = warp_idx % warps_per_row
+
+    if lane_idx == 0:
+        reduction_buffer[row_idx, col_idx] = val
+    cute.arch.barrier()
+
+    block_reduce_val = init_val
+    if lane_idx < warps_per_row:
+        block_reduce_val = reduction_buffer[row_idx, lane_idx]
+    return warp_reduce(block_reduce_val, op)
+
+
+@cute.jit
+def cluster_reduce(
+    val: Float32,
+    op: Callable,
+    reduction_buffer: cute.Tensor,
+    mbar_ptr: cute.Pointer,
+    cluster_n: cutlass.Constexpr[int],
+    init_val: Float32,
+) -> Float32:
+    """Cluster reduction across multiple CTAs using mbarrier."""
+    cta_rank_in_cluster = cute.arch.block_idx_in_cluster()
+    lane_idx = cute.arch.lane_idx()
+    warp_idx = cute.arch.warp_idx()
+
+    rows_per_block = reduction_buffer.shape[0]
+    warps_per_row = reduction_buffer.shape[1][0]
+
+    row_idx = warp_idx // warps_per_row
+    col_idx = warp_idx % warps_per_row
+
+    # Warp 0 sets up mbarrier transaction count
+    if warp_idx == 0:
+        with cute.arch.elect_one():
+            num_warps = rows_per_block * warps_per_row
+            expected_bytes = num_warps * cluster_n * 4
+            cute.arch.mbarrier_arrive_and_expect_tx(mbar_ptr, expected_bytes)
+
+    # Each lane < cluster_n writes to a different CTA's shared memory
+    if lane_idx < cluster_n:
+        store_shared_remote(
+            val,
+            elem_pointer(reduction_buffer, (row_idx, (col_idx, cta_rank_in_cluster))),
+            mbar_ptr,
+            peer_cta_rank_in_cluster=lane_idx,
+        )
+
+    # Wait for all cluster writes
+    cute.arch.mbarrier_wait(mbar_ptr, phase=0)
+
+    # Reduce across all values
+    num_total = warps_per_row * cluster_n
+    num_iter = cute.ceil_div(num_total, 32)
+
+    block_reduce_val = init_val
+    for i in cutlass.range_constexpr(num_iter):
+        idx = lane_idx + i * 32
+        if idx < num_total:
+            block_reduce_val = op(block_reduce_val, reduction_buffer[row_idx, idx])
+
+    return warp_reduce(block_reduce_val, op)
+
+
+@cute.jit
+def row_reduce(
+    x: cute.TensorSSA,
+    op: cute.ReductionOp,
+    threads_per_row: cutlass.Constexpr[int],
+    reduction_buffer: cute.Tensor,
+    mbar_ptr,
+    cluster_n: cutlass.Constexpr[int],
+    init_val: Float32,
+):
+    """Row reduction with optional cluster support."""
+    local_val = x.reduce(op, init_val=init_val, reduction_profile=0)
+
+    warp_op = {
+        cute.ReductionOp.ADD: operator.add,
+        cute.ReductionOp.MAX: cute.arch.fmax,
+    }[op]
+    warp_width = min(threads_per_row, 32)
+    warp_val = warp_reduce(local_val, warp_op, width=warp_width)
+
+    warps_per_row = max(threads_per_row // 32, 1)
+
+    if cutlass.const_expr(warps_per_row > 1 or cluster_n > 1):
+        if cutlass.const_expr(cluster_n == 1):
+            return block_reduce(warp_val, warp_op, reduction_buffer, init_val)
+        else:
+            return cluster_reduce(
+                warp_val, warp_op, reduction_buffer, mbar_ptr, cluster_n, init_val
+            )
+    else:
+        return warp_val
+
+
+# =============================================================================
+# Predicate Utility
+# =============================================================================
+
+
+@cute.jit
+def predicate_k(tXcX: cute.Tensor, limit: int) -> cute.Tensor:
+    """Create predicate tensor for bounds checking."""
+    tXpX = cute.make_rmem_tensor(
+        cute.make_layout(
+            (
+                cute.size(tXcX, mode=[0, 1]),
+                cute.size(tXcX, mode=[1]),
+                cute.size(tXcX, mode=[2]),
+            ),
+            stride=(cute.size(tXcX, mode=[2]), 0, 1),
+        ),
+        cutlass.Boolean,
+    )
+    for rest_v in cutlass.range_constexpr(tXpX.shape[0]):
+        for rest_k in cutlass.range_constexpr(tXpX.shape[2]):
+            tXpX[rest_v, 0, rest_k] = cute.elem_less(
+                tXcX[(0, rest_v), 0, rest_k][1], limit
+            )
+    return tXpX
+
+
+# =============================================================================
+# Helper Functions for SF Block Processing (block_size=16)
+# =============================================================================
+
+
+@cute.jit
+def load_8_half2(
+    mX: cute.Tensor, mW: cute.Tensor, row_offset: Int32, col_offset: Int32, H: int
+):
+    """Load 16 elements (8 half2 pairs) of X and W from global memory.
+
+    Returns:
+        x_h2: rmem_tensor of shape (8,) containing X as half2
+        w_h2: rmem_tensor of shape (8,) containing W as half2
+    """
+    x_h2 = cute.make_rmem_tensor((8,), Uint32)
+    w_h2 = cute.make_rmem_tensor((8,), Uint32)
+
+    # Load X (2 x 128-bit loads = 16 elements)
+    x_ptr0 = get_ptr_as_int64(mX, row_offset * H + col_offset)
+    x_ptr1 = get_ptr_as_int64(mX, row_offset * H + col_offset + Int32(8))
+    x_h2[0], x_h2[1], x_h2[2], x_h2[3] = ld_global_v4_u32(x_ptr0)
+    x_h2[4], x_h2[5], x_h2[6], x_h2[7] = ld_global_v4_u32(x_ptr1)
+
+    # Load W (2 x 128-bit loads = 16 elements)
+    w_ptr0 = get_ptr_as_int64(mW, col_offset)
+    w_ptr1 = get_ptr_as_int64(mW, col_offset + Int32(8))
+    w_h2[0], w_h2[1], w_h2[2], w_h2[3] = ld_global_v4_u32(w_ptr0)
+    w_h2[4], w_h2[5], w_h2[6], w_h2[7] = ld_global_v4_u32(w_ptr1)
+
+    return x_h2, w_h2
+
+
+@cute.jit
+def half2_mul_8(x_h2: cute.Tensor, w_h2: cute.Tensor) -> cute.Tensor:
+    """Multiply 8 half2 pairs element-wise."""
+    xw_h2 = cute.make_rmem_tensor((8,), Uint32)
+    for i in cutlass.range_constexpr(8):
+        xw_h2[i] = half2_mul(x_h2[i], w_h2[i])
+    return xw_h2
+
+
+@cute.jit
+def bfloat2_mul_8(x_h2: cute.Tensor, w_h2: cute.Tensor) -> cute.Tensor:
+    """Multiply 8 bfloat2 pairs element-wise."""
+    xw_h2 = cute.make_rmem_tensor((8,), Uint32)
+    for i in cutlass.range_constexpr(8):
+        xw_h2[i] = bfloat2_mul(x_h2[i], w_h2[i])
+    return xw_h2
+
+
+@cute.jit
+def half2_max_abs_8(xw_h2: cute.Tensor) -> Uint32:
+    """Compute max absolute value across 8 half2 values using tree reduction."""
+    # Compute abs for all 8 values
+    abs_h2 = cute.make_rmem_tensor((8,), Uint32)
+    for i in cutlass.range_constexpr(8):
+        abs_h2[i] = habs2(xw_h2[i])
+
+    # Tree reduction: 8 -> 4 -> 2 -> 1
+    max_01 = hmax2(abs_h2[0], abs_h2[1])
+    max_23 = hmax2(abs_h2[2], abs_h2[3])
+    max_45 = hmax2(abs_h2[4], abs_h2[5])
+    max_67 = hmax2(abs_h2[6], abs_h2[7])
+    max_0123 = hmax2(max_01, max_23)
+    max_4567 = hmax2(max_45, max_67)
+    return hmax2(max_0123, max_4567)
+
+
+@cute.jit
+def bfloat2_max_abs_8(xw_h2: cute.Tensor) -> Uint32:
+    """Compute max absolute value across 8 bfloat2 values using tree reduction."""
+    # Compute abs for all 8 values
+    abs_h2 = cute.make_rmem_tensor((8,), Uint32)
+    for i in cutlass.range_constexpr(8):
+        abs_h2[i] = bfloat2_habs2(xw_h2[i])
+
+    # Tree reduction: 8 -> 4 -> 2 -> 1
+    max_01 = bfloat2_hmax2(abs_h2[0], abs_h2[1])
+    max_23 = bfloat2_hmax2(abs_h2[2], abs_h2[3])
+    max_45 = bfloat2_hmax2(abs_h2[4], abs_h2[5])
+    max_67 = bfloat2_hmax2(abs_h2[6], abs_h2[7])
+    max_0123 = bfloat2_hmax2(max_01, max_23)
+    max_4567 = bfloat2_hmax2(max_45, max_67)
+    return bfloat2_hmax2(max_0123, max_4567)
+
+
+@cute.jit
+def half2_to_float16(xw_h2: cute.Tensor, scale: Float32) -> cute.Tensor:
+    """Convert 8 half2 to 16 float32 with scaling."""
+    y_f32 = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(8):
+        y_f32[i * 2], y_f32[i * 2 + 1] = half2_to_float2_scaled(xw_h2[i], scale)
+    return y_f32
+
+
+@cute.jit
+def bfloat2_to_float16(xw_h2: cute.Tensor, scale: Float32) -> cute.Tensor:
+    """Convert 8 bfloat2 to 16 float32 with scaling."""
+    y_f32 = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(8):
+        y_f32[i * 2], y_f32[i * 2 + 1] = bfloat2_to_float2_scaled(xw_h2[i], scale)
+    return y_f32
+
+
+@cute.jit
+def quantize_and_pack_16(y_f32: cute.Tensor, value_scale: Float32) -> Uint64:
+    """Quantize 16 float32 values to FP4 and pack into uint64."""
+    t025 = value_scale * Float32(0.25)
+    t075 = value_scale * Float32(0.75)
+    t125 = value_scale * Float32(1.25)
+    t175 = value_scale * Float32(1.75)
+    t250 = value_scale * Float32(2.5)
+    t350 = value_scale * Float32(3.5)
+    t500 = value_scale * Float32(5.0)
+    packed = Uint64(0)
+    for i in cutlass.range_constexpr(16):
+        q = y_f32[i]
+        mag = fabs_f32(q)
+        nibble = Uint8(0)
+        if mag > t025 and mag < t075:
+            nibble = Uint8(1)
+        elif mag >= t075 and mag <= t125:
+            nibble = Uint8(2)
+        elif mag > t125 and mag < t175:
+            nibble = Uint8(3)
+        elif mag >= t175 and mag <= t250:
+            nibble = Uint8(4)
+        elif mag > t250 and mag < t350:
+            nibble = Uint8(5)
+        elif mag >= t350 and mag <= t500:
+            nibble = Uint8(6)
+        elif mag > t500:
+            nibble = Uint8(7)
+        if nibble != Uint8(0) and q < Float32(0.0):
+            nibble = nibble | Uint8(0x8)
+        packed = packed | (Uint64(nibble) << Uint64(i * 4))
+    return packed
+
+
+@cute.jit
+def quantize_and_pack_16_fast(y_f32: cute.Tensor, inv_scale: Float32) -> Uint64:
+    """Fast approximate FP4 quantize/pack for 16 float32 values."""
+    q = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(16):
+        q[i] = y_f32[i] * inv_scale
+
+    packed_lo = cvt_e2m1x8_f32(q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7])
+    packed_hi = cvt_e2m1x8_f32(q[8], q[9], q[10], q[11], q[12], q[13], q[14], q[15])
+    return (Uint64(packed_hi) << Uint64(32)) | Uint64(packed_lo)
+
+
+@cute.jit
+def quantize_block_fp4(
+    values: cute.Tensor, max_abs: Float32, global_scale_val: Float32,
+) -> Tuple[Uint64, cutlass.Uint8]:
+    """Quantize 16 float32 values to packed FP4 + e4m3 scale byte.
+
+    Given 16 values and their pre-computed max_abs, derives the NVFP4 block
+    scale, quantizes to FP4, and packs into a uint64.  Returns
+    (packed_fp4_u64, scale_byte).  The caller handles storage writes.
+    """
+    scale_float = max_abs * global_scale_val / Float32(FLOAT4_E2M1_MAX)
+    scale_float = fmin_f32(scale_float, Float32(FLOAT8_E4M3_MAX))
+    scale_u32 = cvt_f32_to_e4m3(scale_float)
+    scale_byte = cutlass.Uint8(scale_u32 & Uint32(0xFF))
+    quantized_scale = fp8_e4m3_to_f32(scale_u32)
+    packed64 = Uint64(0)
+    if quantized_scale != Float32(0.0) and global_scale_val != Float32(0.0):
+        packed64 = quantize_and_pack_16(values, quantized_scale / global_scale_val)
+    return packed64, scale_byte
+
+
+@cute.jit
+def quantize_block_fp4_fast(
+    values: cute.Tensor, max_abs: Float32, global_scale_val: Float32,
+) -> Tuple[Uint64, cutlass.Uint8]:
+    """Fast approximate FP4 block quantization using reciprocal/vector path."""
+    scale_u32 = Uint32(0)
+    scale_byte = cutlass.Uint8(0)
+    packed64 = Uint64(0)
+    if global_scale_val != Float32(0.0):
+        fp4_max_rcp = rcp_approx_ftz(Float32(FLOAT4_E2M1_MAX))
+        scale_float = global_scale_val * (max_abs * fp4_max_rcp)
+        scale_float = fmin_f32(scale_float, Float32(FLOAT8_E4M3_MAX))
+        scale_u32 = cvt_f32_to_e4m3(scale_float)
+        scale_byte = cutlass.Uint8(scale_u32 & Uint32(0xFF))
+        inv_quantized_scale = fp8_e4m3_to_f32_and_rcp(scale_u32)
+        if inv_quantized_scale != Float32(0.0):
+            packed64 = quantize_and_pack_16_fast(values, inv_quantized_scale * global_scale_val)
+    return packed64, scale_byte
+
+
+@cute.jit
+def max_abs_16(values: cute.Tensor) -> Float32:
+    """Compute the maximum absolute value of 16 float32 values."""
+    result = fabs_f32(values[0])
+    for i in cutlass.range_constexpr(1, 16):
+        result = fmax_f32(result, fabs_f32(values[i]))
+    return result
+
+
+@cute.jit
+def silu_mul_16(
+    gate: cute.Tensor, up: cute.Tensor,
+) -> cute.Tensor:
+    """Fused SiLU(gate) * up for 16 float32 element pairs.
+
+    Used in the CompactMoEKernel epilogue to fuse the activation function
+    between GEMM1 and GEMM2, avoiding the gmem round-trip.
+    """
+    out = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(16):
+        g = gate[i]
+        sigmoid_g = cute.arch.rcp_approx(
+            Float32(1.0) + cute.math.exp(-g, fastmath=False)
+        )
+        out[i] = g * sigmoid_g * up[i]
+    return out
+
+
+@cute.jit
+def silu_mul_quantize_block_fp4(
+    gate: cute.Tensor, up: cute.Tensor, global_scale_val: Float32,
+) -> Tuple[Uint64, cutlass.Uint8]:
+    """Fused SiLU(gate)*up + FP4 quantize for 16 element pairs.
+
+    Combines silu_mul_16, max_abs_16, and quantize_block_fp4 into a single
+    helper for the CompactMoEKernel epilogue.
+    """
+    activated = silu_mul_16(gate, up)
+    block_max = max_abs_16(activated)
+    return quantize_block_fp4(activated, block_max, global_scale_val)
+
+
+@cute.jit
+def relu2_16(x: cute.Tensor) -> cute.Tensor:
+    """Compute ReLU^2 for 16 float32 values."""
+    out = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(16):
+        v = fmax_f32(x[i], Float32(0.0))
+        out[i] = v * v
+    return out
+
+
+@cute.jit
+def relu2_quantize_block_fp4(
+    x: cute.Tensor, global_scale_val: Float32,
+) -> Tuple[Uint64, cutlass.Uint8]:
+    """Fuse ReLU^2 and FP4 quantization for 16 float32 values."""
+    activated = relu2_16(x)
+    block_max = max_abs_16(activated)
+    return quantize_block_fp4(activated, block_max, global_scale_val)
+
+
+# =============================================================================
+# MXFP8 (w4a8) Block Quantization: 32-wide UE8M0 + E4M3
+# =============================================================================
+
+
+@cute.jit
+def max_abs_32(values: cute.Tensor) -> Float32:
+    """Compute the maximum absolute value of 32 float32 values."""
+    result = fabs_f32(values[0])
+    for i in cutlass.range_constexpr(1, 32):
+        result = fmax_f32(result, fabs_f32(values[i]))
+    return result
+
+
+@cute.jit
+def quantize_block_fp8_mx(
+    values: cute.Tensor, max_abs: Float32,
+) -> Tuple[cute.Tensor, Uint32]:
+    """Quantize 32 float32 values to E4M3 payload bytes + UE8M0 scale byte.
+
+    The scale is ``pow2_ceil(max_abs / 448)`` so the scaled payload never
+    exceeds the E4M3 range; the payload carries its own exponent, so the
+    power-of-two block scale handles range only.  No global scale is
+    involved (the MX scheme is self-ranging).  Returns
+    ``(payload_u32x8, ue8m0_byte)`` with value ``4*i + j`` in byte ``j`` of
+    ``payload[i]``.  An all-zero block yields scale byte 0 (decoded as a
+    zero output scale) and a zero payload.
+    """
+    scale_f = max_abs * Float32(1.0 / FLOAT8_E4M3_MAX)
+    _, scale_byte = pow2_ceil_ue8m0(scale_f)
+    inv_scale = ue8m0_to_output_scale(scale_byte)
+    payload = cute.make_rmem_tensor((8,), Uint32)
+    for i in cutlass.range_constexpr(8):
+        payload[i] = cvt_f32x4_to_e4m3x4(
+            values[i * 4 + 0] * inv_scale,
+            values[i * 4 + 1] * inv_scale,
+            values[i * 4 + 2] * inv_scale,
+            values[i * 4 + 3] * inv_scale,
+        )
+    return payload, scale_byte
+
+
+@cute.jit
+def silu_mul_32(
+    gate: cute.Tensor, up: cute.Tensor,
+) -> cute.Tensor:
+    """Fused SiLU(gate) * up for 32 float32 element pairs."""
+    out = cute.make_rmem_tensor((32,), Float32)
+    for i in cutlass.range_constexpr(32):
+        g = gate[i]
+        sigmoid_g = cute.arch.rcp_approx(
+            Float32(1.0) + cute.math.exp(-g, fastmath=False)
+        )
+        out[i] = g * sigmoid_g * up[i]
+    return out
+
+
+@cute.jit
+def silu_mul_quantize_block_fp8_mx(
+    gate: cute.Tensor, up: cute.Tensor,
+) -> Tuple[cute.Tensor, Uint32]:
+    """Fused SiLU(gate)*up + MXFP8 quantize for 32 element pairs."""
+    activated = silu_mul_32(gate, up)
+    block_max = max_abs_32(activated)
+    return quantize_block_fp8_mx(activated, block_max)
+
+
+@cute.jit
+def relu2_32(x: cute.Tensor) -> cute.Tensor:
+    """Compute ReLU^2 for 32 float32 values."""
+    out = cute.make_rmem_tensor((32,), Float32)
+    for i in cutlass.range_constexpr(32):
+        v = fmax_f32(x[i], Float32(0.0))
+        out[i] = v * v
+    return out
+
+
+@cute.jit
+def relu2_quantize_block_fp8_mx(
+    x: cute.Tensor,
+) -> Tuple[cute.Tensor, Uint32]:
+    """Fuse ReLU^2 and MXFP8 quantization for 32 float32 values."""
+    activated = relu2_32(x)
+    block_max = max_abs_32(activated)
+    return quantize_block_fp8_mx(activated, block_max)
+
+
+@cute.jit
+def mx_scale_from_amax32(amax: Float32) -> Tuple[Float32, Float32]:
+    """Per-32 MXFP8 block scale from a precomputed amax.
+
+    Returns ``(scale, inv_scale)`` with ``scale = pow2_ceil(amax/448)`` —
+    identical numerics to ``quantize_block_fp8_mx`` (zero amax yields
+    (0, 0), silencing the block).
+    """
+    rounded, byte = pow2_ceil_ue8m0(amax * Float32(1.0 / FLOAT8_E4M3_MAX))
+    inv_scale = ue8m0_to_output_scale(byte)
+    return rounded, inv_scale
+
+
+@cute.jit
+def quant_dequant_e4m3_2(
+    v0: Float32, v1: Float32, inv_scale: Float32, scale: Float32,
+) -> Tuple[Float32, Float32]:
+    """Quantize-dequantize a pair through E4M3 with a power-of-two block scale.
+
+    Bit-matches the w4a8 prefill activation quantizer
+    (``quantize_block_fp8_mx``): RN-saturating E4M3 of ``v*inv_scale``,
+    decoded back and rescaled.  Used by the micro decode kernel's a8_mx mode
+    so decode numerics track the prefill recipe.
+    """
+    q0 = fp8_e4m3_to_f32(cvt_f32_to_e4m3(v0 * inv_scale)) * scale
+    q1 = fp8_e4m3_to_f32(cvt_f32_to_e4m3(v1 * inv_scale)) * scale
+    return q0, q1
+
+
+# =============================================================================
+# Helper Functions for Float32 SF Block Processing
+# =============================================================================
+
+
+@cute.jit
+def load_f32_16_from_smem(
+    sH: cute.Tensor, row_idx: Int32, col_offset: Int32
+) -> cute.Tensor:
+    """Load 16 Float32 values from shared memory."""
+    h_f32 = cute.make_rmem_tensor((16,), Float32)
+    for i in cutlass.range_constexpr(16):
+        h_f32[i] = Float32(sH[row_idx, col_offset + i])
+    return h_f32
+
+
+@cute.jit
+def compute_y_and_max_abs_f32(
+    h_f32: cute.Tensor, w_f32: cute.Tensor, rstd: Float32
+) -> Tuple[cute.Tensor, Float32]:
+    """Compute y = h * rstd * w and max_abs for 16 Float32 values."""
+    y_f32 = cute.make_rmem_tensor((16,), Float32)
+
+    # Compute y and track max_abs
+    y_f32[0] = h_f32[0] * rstd * w_f32[0]
+    max_abs = fabs_f32(y_f32[0])
+
+    for i in cutlass.range_constexpr(1, 16):
+        y_f32[i] = h_f32[i] * rstd * w_f32[i]
+        max_abs = fmax_f32(max_abs, fabs_f32(y_f32[i]))
+
+    return y_f32, max_abs

+ 388 - 0
docker-images/glm52-nf3-hybrid/overlay/b12x/moe/fused/w4a16/host.py

@@ -0,0 +1,388 @@
+"""Host-side helpers for the CuTeDSL W4A16 MoE path."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+import torch
+
+from b12x.moe.fused.activations import (
+    SUPPORTED_MOE_ACTIVATIONS,
+    is_gated_moe_activation,
+    normalize_moe_activation,
+)
+
+
+_W4A16_ALLOWED_ROUTED_SIZES = (8, 16, 32, 48, 64)
+_ROUTED_SIZE_TARGET_FILL = 0.9
+_SUPPORTED_ACTIVATIONS = SUPPORTED_MOE_ACTIVATIONS
+
+
+@dataclass(frozen=True)
+class W4A16PackedShape:
+    num_experts: int
+    hidden_size: int
+    intermediate_size: int
+    w13_rows: int
+    is_gated: bool
+
+
+@dataclass(frozen=True)
+class W4A16PackedBuffers:
+    intermediate_cache13: torch.Tensor
+    intermediate_cache2: torch.Tensor
+    output: torch.Tensor
+    fc1_c_tmp: torch.Tensor | None = None
+    fc2_c_tmp: torch.Tensor | None = None
+    packed_route_indices: torch.Tensor | None = None
+    block_expert_ids: torch.Tensor | None = None
+    packed_route_count: torch.Tensor | None = None
+    expert_offsets: torch.Tensor | None = None
+
+
+@dataclass(frozen=True)
+class W4A16BufferPlan:
+    routed_rows: int
+    fc1_cols: int
+    route_slots: int
+    route_blocks: int
+    fc1_c_tmp_elements: int
+    fc2_c_tmp_elements: int
+    intermediate_cache13_elements: int
+    intermediate_cache2_elements: int
+
+
+def validate_activation(activation: str) -> bool:
+    activation = normalize_moe_activation(activation)
+    return is_gated_moe_activation(activation)
+
+
+def validate_w4a16_packed_inputs(
+    w13_fp4: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+) -> W4A16PackedShape:
+    is_gated = validate_activation(activation)
+    if w13_fp4.dtype != torch.uint8 or w2_fp4.dtype != torch.uint8:
+        raise TypeError("packed FP4 weights must be torch.uint8")
+    if (
+        w13_global_scale.dtype != torch.float32
+        or w2_global_scale.dtype != torch.float32
+    ):
+        raise TypeError("global scales must be torch.float32")
+
+    num_experts = int(w13_fp4.shape[0])
+    hidden_size = int(w2_fp4.shape[1])
+    intermediate_size = int(w2_fp4.shape[2] * 2)
+    w13_rows = intermediate_size * (2 if is_gated else 1)
+    if tuple(w13_fp4.shape) != (num_experts, w13_rows, hidden_size // 2):
+        raise ValueError(
+            f"expected w13_fp4 shape {(num_experts, w13_rows, hidden_size // 2)}, "
+            f"got {tuple(w13_fp4.shape)}"
+        )
+    if tuple(w2_fp4.shape) != (num_experts, hidden_size, intermediate_size // 2):
+        raise ValueError(
+            f"expected w2_fp4 shape {(num_experts, hidden_size, intermediate_size // 2)}, "
+            f"got {tuple(w2_fp4.shape)}"
+        )
+    return W4A16PackedShape(
+        num_experts=num_experts,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        w13_rows=w13_rows,
+        is_gated=is_gated,
+    )
+
+
+def validate_nf3_moe_inputs(
+    w13_codes: torch.Tensor,
+    w13_scale: torch.Tensor,
+    w2_codes: torch.Tensor,
+    w2_scale: torch.Tensor,
+    *,
+    activation: str,
+) -> W4A16PackedShape:
+    """Validate NF3 ("nf3_2p1") code/scale inputs to the packer.
+
+    Codes are integer tensors of values 0..7 in kernel-native output order:
+        w13_codes [E, 2*I, hidden]  w2_codes [E, hidden, I]
+    Scales are per-K/32-group ``t_s`` floats:
+        w13_scale [E, 2*I, hidden//32]  w2_scale [E, hidden, I//32]
+    The NF3 runtime contract requires K % 32 == 0 and N % 64 == 0 for both
+    GEMMs (the scale byte encoding and the 64-N tile packing).
+    """
+    is_gated = validate_activation(activation)
+    _int_dtypes = (torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64)
+    if w13_codes.dtype not in _int_dtypes or w2_codes.dtype not in _int_dtypes:
+        raise TypeError("NF3 codes must be integer tensors of values 0..7")
+
+    num_experts = int(w2_codes.shape[0])
+    hidden_size = int(w2_codes.shape[1])
+    intermediate_size = int(w2_codes.shape[2])
+    w13_rows = intermediate_size * (2 if is_gated else 1)
+    if tuple(w13_codes.shape) != (num_experts, w13_rows, hidden_size):
+        raise ValueError(
+            f"expected w13_codes shape {(num_experts, w13_rows, hidden_size)}, "
+            f"got {tuple(w13_codes.shape)}"
+        )
+    if tuple(w2_codes.shape) != (num_experts, hidden_size, intermediate_size):
+        raise ValueError(
+            f"expected w2_codes shape {(num_experts, hidden_size, intermediate_size)}, "
+            f"got {tuple(w2_codes.shape)}"
+        )
+    for name, size_k, size_n in (
+        ("w13", hidden_size, w13_rows),
+        ("w2", intermediate_size, hidden_size),
+    ):
+        if int(size_k) % 32 != 0:
+            raise ValueError(f"NF3 {name} requires K % 32 == 0, got {size_k}")
+        if int(size_n) % 64 != 0:
+            raise ValueError(f"NF3 {name} requires N % 64 == 0, got {size_n}")
+    if tuple(w13_scale.shape) != (num_experts, w13_rows, hidden_size // 32):
+        raise ValueError(
+            f"expected w13_scale shape {(num_experts, w13_rows, hidden_size // 32)}, "
+            f"got {tuple(w13_scale.shape)}"
+        )
+    if tuple(w2_scale.shape) != (num_experts, hidden_size, intermediate_size // 32):
+        raise ValueError(
+            "expected w2_scale shape "
+            f"{(num_experts, hidden_size, intermediate_size // 32)}, "
+            f"got {tuple(w2_scale.shape)}"
+        )
+    return W4A16PackedShape(
+        num_experts=num_experts,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        w13_rows=w13_rows,
+        is_gated=is_gated,
+    )
+
+
+def unswizzle_block_scale(
+    swizzled_scale: torch.Tensor, rows: int, cols_blocks: int
+) -> torch.Tensor:
+    cols_padded = ((cols_blocks + 3) // 4) * 4
+    rows_padded = ((rows + 127) // 128) * 128
+    unswizzled = swizzled_scale.view(torch.float8_e4m3fn).reshape(
+        rows_padded // 128,
+        cols_padded // 4,
+        32,
+        4,
+        4,
+    )
+    unswizzled = unswizzled.permute(0, 3, 2, 1, 4).contiguous()
+    unswizzled = unswizzled.reshape(rows_padded, cols_padded)
+    return unswizzled[:rows, :cols_blocks].to(torch.float32)
+
+
+def unswizzle_expert_scales(
+    swizzled: torch.Tensor,
+    *,
+    rows: int,
+    cols: int,
+) -> torch.Tensor:
+    if swizzled.dtype != torch.float8_e4m3fn:
+        swizzled = swizzled.view(torch.float8_e4m3fn)
+    scales = [
+        unswizzle_block_scale(swizzled[e], rows, cols // 16).to(torch.float8_e4m3fn)
+        for e in range(swizzled.shape[0])
+    ]
+    return torch.stack(scales, dim=0).contiguous()
+
+
+def reorder_w13_to_gate_up(
+    w13: torch.Tensor,
+    w13_scale: torch.Tensor,
+    *,
+    intermediate_size: int,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    half = int(intermediate_size)
+    return (
+        torch.cat([w13[:, half:], w13[:, :half]], dim=1).contiguous(),
+        torch.cat([w13_scale[:, half:], w13_scale[:, :half]], dim=1).contiguous(),
+    )
+
+
+def select_route_block_size_m(m: int, topk: int, num_experts: int) -> int:
+    avg_routes_per_expert = (int(m) * int(topk)) / int(num_experts)
+    for routed_size in _W4A16_ALLOWED_ROUTED_SIZES:
+        if avg_routes_per_expert < _ROUTED_SIZE_TARGET_FILL * routed_size:
+            return routed_size
+    return _W4A16_ALLOWED_ROUTED_SIZES[-1]
+
+
+def max_packed_route_slots(numel: int, block_size: int, num_experts: int) -> int:
+    max_packed_routes = int(numel) + int(num_experts) * (int(block_size) - 1)
+    if int(numel) < int(num_experts):
+        max_packed_routes = min(
+            int(numel) * int(block_size),
+            max_packed_routes,
+        )
+    return max_packed_routes
+
+
+def route_pack_numel_capacity(numel: int, topk: int = 1) -> int:
+    topk = max(int(topk), 1)
+    tokens = (max(int(numel), 1) + topk - 1) // topk
+    return route_pack_token_capacity(tokens, topk) * topk
+
+
+def route_pack_token_capacity(tokens: int, topk: int) -> int:
+    del topk
+    return 1 << (max(int(tokens), 1) - 1).bit_length()
+
+
+def max_w4a16_route_capacity(routed_rows: int, num_experts: int) -> tuple[int, int]:
+    route_slots = 0
+    route_blocks = 0
+    for block_size in _W4A16_ALLOWED_ROUTED_SIZES:
+        slots = max_packed_route_slots(
+            int(routed_rows), int(block_size), int(num_experts)
+        )
+        route_slots = max(route_slots, slots)
+        route_blocks = max(
+            route_blocks, (slots + int(block_size) - 1) // int(block_size)
+        )
+    return max(route_slots, 1), max(route_blocks, 1)
+
+
+def packed_gemm_scratch_elements(
+    *,
+    size_n: int,
+    route_slots: int,
+    moe_block_size: int,
+    sms: int,
+) -> int:
+    elements = min(
+        int(size_n) * int(route_slots),
+        int(sms) * 4 * int(moe_block_size) * 256,
+    )
+    if moe_block_size == 8:
+        elements *= 2
+    return max(elements, 1)
+
+
+def plan_w4a16_buffers(
+    prepared,
+    *,
+    m: int,
+    topk: int,
+    route_num_experts: int | None = None,
+    sms: int,
+) -> W4A16BufferPlan:
+    routed_rows = int(m) * int(topk)
+    route_num_experts = (
+        int(prepared.num_experts)
+        if route_num_experts is None
+        else int(route_num_experts)
+    )
+    intermediate_size = int(prepared.intermediate_size)
+    hidden_size = int(prepared.hidden_size)
+    fc1_cols = (2 if prepared.is_gated else 1) * intermediate_size
+    block_size_m = select_route_block_size_m(m, topk, route_num_experts)
+    route_slots = max_packed_route_slots(routed_rows, block_size_m, route_num_experts)
+    route_blocks = (route_slots + block_size_m - 1) // block_size_m
+    scratch_sms = int(sms)
+    return W4A16BufferPlan(
+        routed_rows=routed_rows,
+        fc1_cols=fc1_cols,
+        route_slots=route_slots,
+        route_blocks=route_blocks,
+        fc1_c_tmp_elements=packed_gemm_scratch_elements(
+            size_n=fc1_cols,
+            route_slots=route_slots,
+            moe_block_size=block_size_m,
+            sms=scratch_sms,
+        ),
+        fc2_c_tmp_elements=packed_gemm_scratch_elements(
+            size_n=hidden_size,
+            route_slots=route_slots,
+            moe_block_size=block_size_m,
+            sms=scratch_sms,
+        ),
+        intermediate_cache13_elements=routed_rows * max(fc1_cols, hidden_size),
+        intermediate_cache2_elements=routed_rows * intermediate_size,
+    )
+
+
+def make_w4a16_packed_buffers(
+    prepared,
+    *,
+    m: int,
+    topk: int,
+    dtype: torch.dtype,
+    device: torch.device,
+    route_num_experts: int | None = None,
+) -> W4A16PackedBuffers:
+    route_num_experts = (
+        int(prepared.num_experts)
+        if route_num_experts is None
+        else int(route_num_experts)
+    )
+    sms = int(torch.cuda.get_device_properties(device).multi_processor_count)
+    plan = plan_w4a16_buffers(
+        prepared,
+        m=m,
+        topk=topk,
+        route_num_experts=route_num_experts,
+        sms=sms,
+    )
+    fc1_c_tmp = torch.empty(
+        (plan.fc1_c_tmp_elements,),
+        dtype=torch.float32,
+        device=device,
+    )
+    fc2_c_tmp = torch.empty(
+        (plan.fc2_c_tmp_elements,),
+        dtype=torch.float32,
+        device=device,
+    )
+    return W4A16PackedBuffers(
+        intermediate_cache13=torch.empty(
+            (plan.intermediate_cache13_elements,),
+            dtype=dtype,
+            device=device,
+        ),
+        intermediate_cache2=torch.empty(
+            (plan.routed_rows, int(prepared.intermediate_size)),
+            dtype=dtype,
+            device=device,
+        ),
+        output=torch.empty((m, prepared.hidden_size), dtype=dtype, device=device),
+        fc1_c_tmp=fc1_c_tmp,
+        fc2_c_tmp=fc2_c_tmp,
+        packed_route_indices=torch.empty(
+            (plan.route_slots,), dtype=torch.int32, device=device
+        ),
+        block_expert_ids=torch.empty(
+            (plan.route_blocks,), dtype=torch.int32, device=device
+        ),
+        packed_route_count=torch.empty((1,), dtype=torch.int32, device=device),
+        expert_offsets=torch.empty(
+            (route_num_experts + 1,), dtype=torch.int32, device=device
+        ),
+    )
+
+
+__all__ = [
+    "W4A16BufferPlan",
+    "W4A16PackedBuffers",
+    "W4A16PackedShape",
+    "make_w4a16_packed_buffers",
+    "max_w4a16_route_capacity",
+    "packed_gemm_scratch_elements",
+    "max_packed_route_slots",
+    "plan_w4a16_buffers",
+    "reorder_w13_to_gate_up",
+    "route_pack_numel_capacity",
+    "route_pack_token_capacity",
+    "select_route_block_size_m",
+    "unswizzle_block_scale",
+    "unswizzle_expert_scales",
+    "validate_activation",
+    "validate_nf3_moe_inputs",
+    "validate_w4a16_packed_inputs",
+]

+ 7067 - 0
docker-images/glm52-nf3-hybrid/overlay/b12x/moe/fused/w4a16/kernel.py

@@ -0,0 +1,7067 @@
+"""CuTeDSL W4A16 NVFP4/BF16 W4A16 MoE kernels."""
+
+from __future__ import annotations
+
+import math
+import os
+from dataclasses import dataclass, replace
+from typing import NamedTuple
+
+import cuda.bindings.driver as cuda
+import cutlass
+import cutlass.cute as cute
+import torch
+from cutlass.cutlass_dsl import Int32, Int64, Uint32
+
+from b12x.cute.compiler import KernelCompileSpec, compile as b12x_compile
+from b12x.cute.fp4 import (
+    atomic_add_global_i32,
+    bf16_mma_m16n8k16_f32,
+    bf16_mma_rhs_fragments_as_mma_a_m16n8k16_f32,
+    bfloat2_broadcast_lane,
+    bfloat2_mul,
+    bfloat2_to_float2_scaled,
+    broadcast_f32_to_half2,
+    broadcast_f32_to_bfloat2,
+    cp_async4_shared_global,
+    cp_async4_shared_global_pred,
+    fabs_f32,
+    fmax_f32,
+    f16_mma_m16n8k16_f32,
+    f16_mma_rhs_fragments_as_mma_a_m16n8k16_f32,
+    half2_to_float2_scaled,
+    get_ptr_as_int64,
+    half2_mul,
+    ld_global_acquire_i32,
+    ld_global_nc_u32,
+    ld_global_v4_f32,
+    ld_shared_f32,
+    ld_shared_i32_relaxed,
+    ld_shared_u32,
+    ld_shared_v2_u32,
+    ld_shared_v4_f32,
+    ld_shared_v4_u32,
+    ldmatrix_m8n8x4_b16,
+    ldmatrix_m8n8x2_b16,
+    packed_dequant_e2m1x4_to_bfloat2x2,
+    packed_dequant_e2m1x4_to_half2x2,
+    packed_dequant_e4m3x4_to_bfloat2x2,
+    packed_dequant_e4m3x4_to_half2x2,
+    packed_dequant_e8m0x4_to_bfloat2x2,
+    packed_dequant_e8m0x4_to_half2x2,
+    packed_dequant_nf3x8_to_bfloat2x4,
+    nf3_codebook_pools,
+    pack_f32x2_to_bfloat2,
+    pack_f32x2_to_f16x2,
+    red_add_global_bf16x2,
+    red_add_global_release_i32,
+    red_max_global_f32_nonnegative,
+    shared_ptr_to_u32,
+    st_global_v4_u32,
+    st_global_i32,
+    st_global_v4_f32,
+    st_shared_bf16_from_f32,
+    st_shared_f16_from_f32,
+    st_shared_f32,
+    st_shared_i32,
+    st_shared_u32,
+    st_shared_v4_f32,
+    st_shared_v4_u32,
+    threadfence,
+    warp_reduce,
+)
+from b12x.cute.utils import current_cuda_stream, make_ptr
+from b12x.moe.fused.w4a16.route_pack import (
+    pack_topk_routes_by_expert as _pack_topk_routes_by_expert,
+)
+from b12x.moe.fused.w4a16.host import (
+    _W4A16_ALLOWED_ROUTED_SIZES,
+    max_packed_route_slots,
+    packed_gemm_scratch_elements,
+    plan_w4a16_buffers,
+    select_route_block_size_m,
+    validate_activation,
+)
+from b12x.cute.runtime_control import raise_if_kernel_resolution_frozen
+from b12x.moe.fused.activations import (
+    SWIGLUOAI_UNINTERLEAVE,
+    is_gated_moe_activation,
+    normalize_moe_activation,
+    normalize_swiglu_alpha_for_activation,
+    normalize_swiglu_beta_for_activation,
+    normalize_swiglu_limit_for_activation,
+)
+from b12x.moe.fused.micro import MoEMicroKernelBackend
+
+
+_ALLOWED_ROUTED_SIZES = _W4A16_ALLOWED_ROUTED_SIZES
+_PACK_FACTOR = 8
+_STAGES = 4
+_E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT = 64
+_DEVICE_MAX_REG_BYTES = 255 * 1024
+_DEFAULT_MAX_SHARED_MEM = 101_376
+_WEIGHT_LAYOUTS = {"packed", "modelopt", "nf3_2p1"}
+_MODEL_OPT_W13_LAYOUTS = {"w13", "w31"}
+# NF3 codebook: 8 bf16 codepoints for the 3-bit ("nf3_2p1") weight layout. The
+# device dequant reads these as prmt pools (see nf3_codebook_pools); the host
+# injects the 4 pool words as compile-time constants into the GEMM.
+_NF3_CODEBOOK = (-1.0, -0.6047, -0.3563, -0.1275, 0.1275, 0.3563, 0.6047, 1.0)
+_SCALE_FORMATS = {
+    "e4m3_k16": "e4m3_k16",
+    "e8m0_k32": "e8m0_k32",
+    "e4m3_k32": "e4m3_k32",
+}
+_E8M0_K32_FP16_GLOBAL_COMPENSATION = float(2.0**7)
+_E8M0_K32_BF16_GLOBAL_COMPENSATION = float(2.0**119)
+_MAX_DIRECT_TOPK_ROUTE_M = 6
+_W4A16_SMALL_M_DIRECT_MAX_M = 8
+
+# TC-decode: a small-M decode specialization that runs on the PACKED W4A16
+# object (the same weights/scales the prefill GEMM uses). It reuses the packed
+# tensor-core MMA inner loop but folds the top-k sum into the FC2 store
+# epilogue (dropping the separate top-k-sum launch). It never regresses vs the
+# packed GEMM within its supported M range, so it is ALWAYS used for the small-M
+# direct-topk decode sizes — there is no opt-in/opt-out switch.
+# TC-decode is available for the whole small-M direct-topk range. Its only hard
+# ceiling is the direct-topk route cap (above it, expert route-packing wins).
+# _TC_DECODE_M is retained for callers/tests that enumerate the supported sizes.
+_TC_DECODE_MAX_M = _W4A16_SMALL_M_DIRECT_MAX_M
+_TC_DECODE_M = tuple(range(1, _TC_DECODE_MAX_M + 1))
+
+
+def _m_specialization_key(size_m: int) -> int:
+    """M bucket for branches that genuinely specialize on token count."""
+    return 1 if int(size_m) == 1 else 0
+
+
+def _fake_m_for_specialization(size_m: int) -> int:
+    return 1 if _m_specialization_key(size_m) == 1 else 2
+
+
+# The W4A16 launch model chooses blocks/SM from static resource usage
+# for each specialization.  These register counts were measured from the local
+# SM121 JIT output and keep launch occupancy stable across refactors.
+_W4A16_REGS_SM121 = {
+    (256, 1, 8, 8, True): 118,
+    (256, 1, 16, 4, True): 118,
+    (256, 1, 16, 8, True): 118,
+    (256, 1, 32, 2, True): 118,
+    (128, 1, 4, 8, True): 118,
+    (128, 1, 8, 4, True): 120,
+    (256, 1, 8, 8, False): 158,
+    (128, 1, 4, 8, False): 154,
+    (128, 1, 8, 4, False): 143,
+    (256, 2, 16, 4, False): 212,
+    (128, 2, 4, 8, False): 215,
+    (128, 2, 8, 4, False): 214,
+    (256, 3, 16, 4, False): 249,
+    (128, 3, 4, 8, False): 249,
+    (128, 3, 8, 4, False): 250,
+    (256, 4, 16, 4, False): 255,
+    (128, 4, 4, 8, False): 255,
+    (128, 4, 8, 4, False): 255,
+}
+_SMALL_BATCH_TILE_CONFIGS = (
+    (128, 128, 256),
+    (64, 128, 128),
+    (128, 64, 128),
+)
+_LARGE_BATCH_TILE_CONFIGS = (
+    (64, 256, 256),
+    (64, 128, 128),
+    (128, 64, 128),
+)
+
+
+def _covering_count(total: int, quantum: int) -> int:
+    return (total + quantum - 1) // quantum
+
+
+def _e8m0_logical_tail_scale_n(size_n: int) -> int:
+    return (
+        (int(size_n) + _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT - 1)
+        // _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT
+    ) * _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT
+
+
+def _normalize_swiglu_limit(swiglu_limit: float | None) -> float | None:
+    return normalize_swiglu_limit_for_activation("silu", swiglu_limit)
+
+
+def _normalize_activation_swiglu_params(
+    activation: str,
+    swiglu_limit: float | None,
+    swiglu_alpha: float | None,
+    swiglu_beta: float | None,
+) -> tuple[float | None, float, float]:
+    activation = normalize_moe_activation(activation)
+    return (
+        normalize_swiglu_limit_for_activation(activation, swiglu_limit),
+        normalize_swiglu_alpha_for_activation(activation, swiglu_alpha),
+        normalize_swiglu_beta_for_activation(activation, swiglu_beta),
+    )
+
+
+def _w4a16_num_regs(
+    *,
+    cta_threads: int,
+    cta_m_blocks: int,
+    cta_n_blocks: int,
+    cta_k_blocks: int,
+    uses_m_block_8: bool,
+) -> int:
+    key = (
+        int(cta_threads),
+        int(cta_m_blocks),
+        int(cta_n_blocks),
+        int(cta_k_blocks),
+        bool(uses_m_block_8),
+    )
+    try:
+        return _W4A16_REGS_SM121[key]
+    except KeyError as exc:
+        raise ValueError(
+            f"missing W4A16 register count for NVFP4 BF16 specialization {key}"
+        ) from exc
+
+
+def _shared_memory_footprint(
+    *,
+    cta_m_blocks: int,
+    tile_n: int,
+    tile_k: int,
+    scale_format: str = "e4m3_k16",
+) -> int:
+    cta_m = int(cta_m_blocks) * 16
+    cta_n = int(tile_n)
+    cta_k = int(tile_k)
+    sh_block_meta_size = cta_m * 16
+    sh_a_size = _STAGES * (cta_m * cta_k) * 2
+    sh_b_size = _STAGES * (cta_k * cta_n // _PACK_FACTOR) * 4
+    sh_red_size = cta_m * (cta_n + 8) * 2
+    sh_bias_size = cta_n * 2
+    tmp_size = min(sh_b_size, sh_red_size) + sh_bias_size
+    tmp_size = max(max(sh_b_size, sh_red_size), tmp_size)
+    sh_s_size = (
+        _covering_count(cta_k, _scale_group_size(scale_format)) * cta_n * 2 * _STAGES
+    )
+    return tmp_size + sh_a_size + sh_s_size + sh_block_meta_size
+
+
+def _determine_blocks_per_sm(
+    *,
+    problem_m: int,
+    problem_n: int,
+    top_k: int,
+    cta_threads: int,
+    cta_m_blocks: int,
+    tile_n: int,
+    tile_k: int,
+    uses_m_block_8: bool,
+    sms: int,
+    max_shared_mem: int,
+    scale_format: str = "e4m3_k16",
+) -> int:
+    num_regs = _w4a16_num_regs(
+        cta_threads=cta_threads,
+        cta_m_blocks=cta_m_blocks,
+        cta_n_blocks=tile_n // 16,
+        cta_k_blocks=tile_k // 16,
+        uses_m_block_8=uses_m_block_8,
+    )
+    register_bytes = max(num_regs, 1) * int(cta_threads) * 4
+    smem_bytes = _shared_memory_footprint(
+        cta_m_blocks=cta_m_blocks,
+        tile_n=tile_n,
+        tile_k=tile_k,
+        scale_format=scale_format,
+    )
+    blocks_per_sm_limit = min(
+        _DEVICE_MAX_REG_BYTES // register_bytes,
+        int(max_shared_mem) // (smem_bytes + 1536),
+    )
+    if uses_m_block_8:
+        # Small-M (moe_block_size==8) TC-decode is weight-bandwidth/overhead
+        # bound, not parallelism bound (only m*top_k route-blocks of GEMM work).
+        # The fused FC1->activation->FC2 path crosses several grid barriers whose
+        # tid==0 atomic-counter increment serializes across all grid_x CTAs, so an
+        # oversized grid pays barrier-atomic latency proportional to grid_x for no
+        # extra GEMM throughput. Pin one persistent CTA per SM to minimize the
+        # barrier participant count while still covering the machine for the
+        # I_tp=1024 GEMMs. The split-K persistent loop is grid_x-agnostic, so this
+        # is numerically identical.
+        blocks_per_sm_limit = 1
+    elif cta_m_blocks == 1:
+        blocks_per_sm_limit = max(min(blocks_per_sm_limit, 4), 1)
+    else:
+        blocks_per_sm_limit = max(min(blocks_per_sm_limit, 2), 1)
+
+    work_cta_count = (int(problem_n) // int(tile_n)) * int(problem_m) * int(top_k) * 4
+    if work_cta_count < int(sms) * blocks_per_sm_limit:
+        blocks_per_sm_limit = max(work_cta_count // int(sms), 1)
+    return int(blocks_per_sm_limit)
+
+
+def _candidate_tile_fits(
+    *,
+    problem_n: int,
+    problem_k: int,
+    cta_m_blocks: int,
+    tile_n: int,
+    tile_k: int,
+    cta_threads: int,
+    max_shared_mem: int,
+    scale_format: str = "e4m3_k16",
+    allow_logical_tail: bool = False,
+) -> bool:
+    if int(tile_k) == -1 or int(tile_n) == -1 or int(cta_threads) == -1:
+        return False
+    scale_group_size = _scale_group_size(scale_format)
+    exact_n = int(problem_n) % int(tile_n) == 0
+    exact_k = int(problem_k) % int(tile_k) == 0
+    exact_scale_k = int(problem_k) % scale_group_size == 0
+    if not allow_logical_tail:
+        if not exact_n or not exact_k:
+            return False
+        if not exact_scale_k or int(tile_k) % scale_group_size != 0:
+            return False
+    elif (
+        _normalize_scale_format(scale_format) != "e8m0_k32"
+        or int(problem_n) % 16 != 0
+        or int(problem_k) % 8 != 0
+        or int(tile_n) % 16 != 0
+        or int(tile_k) % scale_group_size != 0
+    ):
+        return False
+    if int(tile_n) < 64 or int(tile_k) < 64 or int(cta_threads) < 128:
+        return False
+    smem_bytes = _shared_memory_footprint(
+        cta_m_blocks=cta_m_blocks,
+        tile_n=tile_n,
+        tile_k=tile_k,
+        scale_format=scale_format,
+    )
+    return smem_bytes <= int(max_shared_mem)
+
+
+def _select_tile_config(
+    *,
+    problem_m: int,
+    problem_n: int,
+    problem_k: int,
+    top_k: int,
+    moe_block_size: int,
+    sms: int,
+    max_shared_mem: int,
+    required_cta_threads: int | None = None,
+    scale_format: str = "e4m3_k16",
+    allow_logical_tail: bool = False,
+) -> tuple[int, int, int, int]:
+    cta_m_blocks = _covering_count(moe_block_size, 16)
+    uses_m_block_8 = moe_block_size == 8
+    configs = (
+        _LARGE_BATCH_TILE_CONFIGS if cta_m_blocks > 1 else _SMALL_BATCH_TILE_CONFIGS
+    )
+    best_blocks_per_sm = 0
+    best_tile_config: tuple[int, int, int, int] | None = None
+    for tile_k, tile_n, cta_threads in configs:
+        if required_cta_threads is not None and int(cta_threads) != int(
+            required_cta_threads
+        ):
+            continue
+        if not _candidate_tile_fits(
+            problem_n=problem_n,
+            problem_k=problem_k,
+            cta_m_blocks=cta_m_blocks,
+            tile_n=tile_n,
+            tile_k=tile_k,
+            cta_threads=cta_threads,
+            max_shared_mem=int(max_shared_mem) - 512,
+            scale_format=scale_format,
+            allow_logical_tail=allow_logical_tail,
+        ):
+            continue
+        occupancy_problem_n = (
+            _covering_count(int(problem_n), int(tile_n)) * int(tile_n)
+            if allow_logical_tail
+            else int(problem_n)
+        )
+        blocks_per_sm_limit = _determine_blocks_per_sm(
+            problem_m=problem_m,
+            problem_n=occupancy_problem_n,
+            top_k=top_k,
+            cta_threads=cta_threads,
+            cta_m_blocks=cta_m_blocks,
+            tile_n=tile_n,
+            tile_k=tile_k,
+            uses_m_block_8=uses_m_block_8,
+            sms=sms,
+            max_shared_mem=max_shared_mem,
+            scale_format=scale_format,
+        )
+        if blocks_per_sm_limit > best_blocks_per_sm:
+            best_blocks_per_sm = blocks_per_sm_limit
+            best_tile_config = (tile_k, tile_n, cta_threads, blocks_per_sm_limit)
+    if best_tile_config is None:
+        cta_thread_msg = (
+            ""
+            if required_cta_threads is None
+            else f", required_cta_threads={required_cta_threads}"
+        )
+        raise ValueError(
+            "no valid W4A16 tile config for "
+            f"M/N/K={problem_m}/{problem_n}/{problem_k}, moe_block_size={moe_block_size}"
+            f"{cta_thread_msg}"
+        )
+    return best_tile_config
+
+
+@dataclass(frozen=True)
+class W4A16GemmCompileResult:
+    compiled: object
+    tile_n: int
+    tile_k: int
+    moe_block_size: int
+    max_m_blocks: int
+    blocks_per_sm: int
+    weight_layout: str = "packed"
+    scale_format: str = "e4m3_k16"
+    w13_layout: str = "w13"
+
+
+@dataclass(frozen=True)
+class W4A16ActivationCompileResult:
+    compiled: object
+    rows: int
+    intermediate_size: int
+    activation: str
+    swiglu_limit: float | None
+    swiglu_alpha: float
+    swiglu_beta: float
+
+
+@dataclass(frozen=True)
+class W4A16TopKSumCompileResult:
+    compiled: object
+    m: int
+    topk: int
+    hidden_size: int
+
+
+@dataclass(frozen=True)
+class W4A16FusedMoeCompileResult:
+    compiled: object
+    size_m: int
+    hidden_size: int
+    intermediate_size: int
+    num_experts: int
+    top_k: int
+    activation: str
+    apply_router_weight_on_input: bool
+    zero_fc2_output: bool
+    element_dtype: str
+    fast_math: bool
+    swiglu_limit: float | None
+    swiglu_alpha: float
+    swiglu_beta: float
+    fc1_tile_n: int
+    fc1_tile_k: int
+    fc2_tile_n: int
+    fc2_tile_k: int
+    moe_block_size: int
+    max_m_blocks: int
+    blocks_per_sm: int
+    weight_layout: str = "packed"
+    w13_layout: str = "w13"
+    direct_topk_routes: bool = False
+    scale_format: str = "e4m3_k16"
+    tc_decode_fused_sum: bool = False
+    collect_activation_amax: bool = False
+
+
+@dataclass(frozen=True)
+class _W4A16GemmLaunch:
+    kernel: W4A16GemmCompileResult
+    c_tmp: torch.Tensor
+
+
+class _W4A16SmallMDirectLaunch(NamedTuple):
+    compiled: object
+    grid_x: int
+    m: int
+    hidden_size: int
+    intermediate_size: int
+    num_experts: int
+    topk: int
+    activation: str
+    fast_math: bool
+    topk_ids_dtype: torch.dtype
+
+
+class _W4A16SmallMDirectKernel(MoEMicroKernelBackend):
+    """Decode-sized W4A16 specialization using the native ModelOpt layout."""
+
+    _SUPPORTED_M = tuple(range(1, _W4A16_SMALL_M_DIRECT_MAX_M + 1))
+
+    @classmethod
+    def is_supported(
+        cls,
+        *,
+        m: int,
+        hidden_size: int,
+        intermediate_size: int,
+        topk: int,
+        num_experts: int,
+        scale_format: str = "e4m3_k16",
+    ) -> bool:
+        # E8M0 reads the shared packed scale grid. Both block axes must be /32.
+        if scale_format == "e8m0_k32":
+            scale_block_ok = (
+                int(hidden_size) % 32 == 0
+                and int(intermediate_size) % 32 == 0
+            )
+        else:
+            scale_block_ok = True
+        return (
+            int(m) in cls._SUPPORTED_M
+            and int(m) <= _W4A16_SMALL_M_DIRECT_MAX_M
+            and int(hidden_size) > 0
+            and int(hidden_size) % 128 == 0
+            and int(intermediate_size) > 0
+            and int(intermediate_size) % 16 == 0
+            and scale_block_ok
+            and 0 < int(topk) <= 32
+            and int(num_experts) > 0
+            and MoEMicroKernelBackend.is_supported(
+                int(m),
+                int(hidden_size),
+                int(intermediate_size),
+                int(topk),
+                int(num_experts),
+            )
+        )
+
+    def __init__(
+        self,
+        *,
+        activation: str,
+        fast_math: bool,
+        share_input_across_experts: bool,
+        share_expert_scales: bool,
+        single_token: bool,
+        scale_format: str = "e4m3_k16",
+        swiglu_limit: float | None = None,
+        swiglu_alpha: float | None = None,
+        swiglu_beta: float | None = None,
+        w13_layout: str = "w13",
+    ):
+        super().__init__(
+            sf_vec_size=16,
+            mma_tiler_mn=(64, 128),
+            output_tile_count_n=1,
+            fast_math=fast_math,
+            activation=activation,
+            share_input_across_experts=share_input_across_experts,
+            share_expert_scales=share_expert_scales,
+            single_token=single_token,
+            dynamic_down_scale=False,
+            w4a16_mode=True,
+            scale_format=scale_format,
+            swiglu_limit=swiglu_limit,
+            swiglu_alpha=swiglu_alpha,
+            swiglu_beta=swiglu_beta,
+            w13_layout=w13_layout,
+        )
+
+
+class W4A16GemmKernel:
+    def __init__(
+        self,
+        *,
+        size_m: int,
+        size_n: int,
+        size_k: int,
+        num_experts: int,
+        top_k: int,
+        mul_topk_weights: bool,
+        tile_n: int,
+        tile_k: int,
+        moe_block_size: int,
+        max_m_blocks: int,
+        element_dtype: str = "bf16",
+        epilogue_activation: str | None = None,
+        weight_layout: str = "packed",
+        scale_format: str = "e4m3_k16",
+        w13_layout: str = "w13",
+        source_n_rotation: int = 0,
+        single_token_route_fast_path: bool = False,
+        direct_topk_routes: bool = False,
+        fused_topk_sum: bool = False,
+        fused_sum_topk: int = 1,
+    ):
+        if element_dtype not in {"bf16", "fp16"}:
+            raise ValueError(f"unsupported element_dtype {element_dtype!r}")
+        if weight_layout not in _WEIGHT_LAYOUTS:
+            raise ValueError(f"unsupported W4A16 weight_layout {weight_layout!r}")
+        scale_format = _normalize_scale_format(scale_format)
+        if weight_layout == "modelopt":
+            if w13_layout not in _MODEL_OPT_W13_LAYOUTS:
+                raise ValueError(f"unsupported W4A16 w13_layout {w13_layout!r}")
+        else:
+            w13_layout = "packed"
+            source_n_rotation = 0
+        if weight_layout == "nf3_2p1":
+            if scale_format != "e4m3_k32":
+                raise ValueError(
+                    "nf3_2p1 W4A16 weights require scale_format='e4m3_k32'"
+                )
+            if element_dtype != "bf16":
+                raise ValueError(
+                    "nf3_2p1 W4A16 weights are bf16-activation only (v1)"
+                )
+        if epilogue_activation not in (None, "relu2"):
+            raise ValueError(
+                "W4A16 GEMM epilogue activation currently supports only relu2"
+            )
+        if tile_n % 16 != 0 or tile_k % 16 != 0:
+            raise ValueError("tile_n/tile_k must be multiples of 16")
+        scale_group_size = _scale_group_size(scale_format)
+        has_n_tile_tail = int(size_n) % int(tile_n) != 0
+        has_k_tile_tail = int(size_k) % int(tile_k) != 0
+        has_scale_k_tail = int(size_k) % scale_group_size != 0
+        has_logical_tail = (
+            has_n_tile_tail or has_k_tile_tail or has_scale_k_tail
+        )
+        if has_logical_tail:
+            if weight_layout != "modelopt" or scale_format != "e8m0_k32":
+                raise ValueError(
+                    "W4A16 logical tail tiles are only supported for native "
+                    "E8M0 K/32 weights"
+                )
+            if int(size_n) % 16 != 0:
+                raise ValueError(
+                    "native E8M0 W4A16 tail tiles require size_n % 16 == 0"
+                )
+            if int(size_k) % 8 != 0:
+                raise ValueError(
+                    "native E8M0 W4A16 tail tiles require size_k % 8 == 0"
+                )
+            if int(tile_k) % scale_group_size != 0:
+                raise ValueError(
+                    "native E8M0 W4A16 tail tiles require tile_k multiples of 32"
+                )
+        else:
+            if size_n % tile_n != 0:
+                raise ValueError("size_n must be divisible by tile_n")
+            if size_k % tile_k != 0:
+                raise ValueError("size_k must be divisible by tile_k")
+            if scale_format == "e8m0_k32" and (
+                size_k % 32 != 0 or tile_k % 32 != 0
+            ):
+                raise ValueError(
+                    "E8M0 K/32 W4A16 scales require size_k/tile_k multiples of 32"
+                )
+            if scale_format == "e4m3_k32" and (
+                size_k % 32 != 0 or tile_k % 32 != 0
+            ):
+                raise ValueError(
+                    "E4M3 K/32 W4A16 scales require size_k/tile_k multiples of 32"
+                )
+        if moe_block_size not in _ALLOWED_ROUTED_SIZES:
+            raise ValueError(f"unsupported moe_block_size {moe_block_size}")
+        if moe_block_size != 8 and moe_block_size % 16 != 0:
+            raise ValueError("moe_block_size must be 8 or a multiple of 16")
+        cta_threads = tile_n * tile_k // 64
+        if cta_threads not in (128, 256):
+            raise ValueError("W4A16 GEMM expects 128 or 256 CTA threads")
+        self.size_m = int(size_m)
+        self.size_n = int(size_n)
+        self.size_k = int(size_k)
+        self.num_experts = int(num_experts)
+        self.top_k = int(top_k)
+        self.mul_topk_weights = bool(mul_topk_weights)
+        self.tile_n = int(tile_n)
+        self.tile_k = int(tile_k)
+        self.cta_n_blocks = int(tile_n // 16)
+        self.cta_k_blocks = int(tile_k // 16)
+        self.cta_threads = int(cta_threads)
+        self.moe_block_size = int(moe_block_size)
+        self.element_dtype = element_dtype
+        self.is_fp16 = element_dtype == "fp16"
+        self.epilogue_relu2 = epilogue_activation == "relu2"
+        self.weight_layout = weight_layout
+        self.weight_layout_nf3 = weight_layout == "nf3_2p1"
+        self.scale_format = scale_format
+        self.scale_format_e8m0_k32 = scale_format == "e8m0_k32"
+        # k32 scale cadence (two K16 rows share one scale group). Shared by the
+        # native E8M0 K/32 path and the NF3 e4m3-style K/32 path; the scale
+        # DECODE stays keyed on scale_format_e8m0_k32 (e4m3_k32 uses the e4m3
+        # decode arm, its 2**116 compensation lives in the global_scale tensor).
+        self.scale_k32 = scale_format in ("e8m0_k32", "e4m3_k32")
+        # NF3 codebook prmt pools (host-computed compile-time constants injected
+        # into the device dequant). Only consumed by the nf3_2p1 path; cheap to
+        # compute unconditionally.
+        (
+            self._nf3_cb0,
+            self._nf3_cb1,
+            self._nf3_cb2,
+            self._nf3_cb3,
+        ) = nf3_codebook_pools(_NF3_CODEBOOK)
+        self.scale_group_size = int(scale_group_size)
+        self.scale_k_groups = _covering_count(self.size_k, self.scale_group_size)
+        self.n_tiles = _covering_count(self.size_n, self.tile_n)
+        self.k_tiles = _covering_count(self.size_k, self.tile_k)
+        self.covered_size_n = self.n_tiles * self.tile_n
+        self.covered_size_k = self.k_tiles * self.tile_k
+        self.has_n_tile_tail = bool(has_n_tile_tail)
+        self.has_k_tile_tail = bool(has_k_tile_tail)
+        self.has_scale_k_tail = bool(has_scale_k_tail)
+        self.has_logical_tail = bool(has_logical_tail)
+        self.scale_size_n = (
+            _e8m0_logical_tail_scale_n(self.size_n)
+            if self.scale_format_e8m0_k32 and self.has_n_tile_tail
+            else self.size_n
+        )
+        self.scale_n_groups = self.scale_size_n // 16
+        self.w13_layout = w13_layout
+        self.source_n_rotation = int(source_n_rotation)
+        self.single_token_route_fast_path = bool(single_token_route_fast_path)
+        self.direct_topk_routes = bool(direct_topk_routes)
+        self.fused_topk_sum = bool(fused_topk_sum)
+        self.fused_sum_topk = int(fused_sum_topk)
+        if self.fused_topk_sum and not self.direct_topk_routes:
+            raise ValueError("fused_topk_sum requires direct_topk_routes")
+        if self.fused_topk_sum and self.fused_sum_topk < 1:
+            raise ValueError("fused_sum_topk must be >= 1")
+        self.cta_m_blocks = int(_covering_count(moe_block_size, 16))
+        self.uses_m_block_8 = moe_block_size == 8
+        self.max_m_blocks = int(max_m_blocks)
+        if torch.cuda.is_available():
+            props = torch.cuda.get_device_properties(torch.cuda.current_device())
+            self.sms = int(props.multi_processor_count)
+            max_shared_mem = int(
+                getattr(props, "shared_memory_per_block_optin", _DEFAULT_MAX_SHARED_MEM)
+            )
+        else:
+            self.sms = 120
+            max_shared_mem = _DEFAULT_MAX_SHARED_MEM
+        self.blocks_per_sm = _determine_blocks_per_sm(
+            problem_m=self.size_m,
+            problem_n=self.covered_size_n,
+            top_k=self.top_k,
+            cta_threads=self.cta_threads,
+            cta_m_blocks=self.cta_m_blocks,
+            tile_n=self.tile_n,
+            tile_k=self.tile_k,
+            uses_m_block_8=self.uses_m_block_8,
+            sms=self.sms,
+            max_shared_mem=max_shared_mem,
+            scale_format=scale_format,
+        )
+
+        # W4A16 shared-memory geometry, in int4 units unless noted.
+        self.a_sh_stride = 16 * self.cta_k_blocks // 8
+        self.a_sh_stage = self.a_sh_stride * (16 * self.cta_m_blocks)
+        self.a_gl_rd_delta_o = 16 * self.cta_k_blocks // 8
+        self.a_sh_wr_delta = self.a_sh_stride * (
+            self.cta_threads // self.a_gl_rd_delta_o
+        )
+        self.a_sh_wr_iters = _covering_count(self.a_sh_stage, self.a_sh_wr_delta)
+        self.a_sh_rd_delta_i = self.a_sh_stride * 16
+
+        self.b_sh_stride = ((self.cta_n_blocks * 16) * 16 // _PACK_FACTOR) // 4
+        self.b_thread_vecs = 1
+        self.b_sh_stride_threads = self.b_sh_stride
+        self.b_sh_stage = self.b_sh_stride * self.cta_k_blocks
+        self.b_sh_wr_iters = self.b_sh_stage // self.cta_threads
+        # NF3 ("nf3_2p1") stages 12-byte triples per 32-code unit instead of the
+        # 16-byte int4 unit; the per-thread unit count is unchanged, only the
+        # bytes-per-unit and the 16-byte cp.async chunk count differ.
+        self.b_unit_bytes = 12 if self.weight_layout_nf3 else 16
+        self.b_sh_stage_bytes = self.b_sh_stage * self.b_unit_bytes
+        if self.weight_layout_nf3:
+            if self.b_sh_stage_bytes % 16 != 0:
+                raise ValueError(
+                    "nf3_2p1 B stage bytes must be a multiple of 16; "
+                    f"got {self.b_sh_stage_bytes}"
+                )
+            self.b_sh_chunks = self.b_sh_stage_bytes // 16
+            self.b_sh_wr_iters_nf3 = _covering_count(
+                self.b_sh_chunks, self.cta_threads
+            )
+        else:
+            self.b_sh_chunks = self.b_sh_stage
+            self.b_sh_wr_iters_nf3 = self.b_sh_wr_iters
+
+        self.s_sh_stride = 16 * self.cta_n_blocks // 16
+        self.s_tb_groups = (
+            self.cta_k_blocks // 2 if self.scale_k32 else self.cta_k_blocks
+        )
+        self.s_sh_stage = self.s_tb_groups * self.s_sh_stride
+        self.tb_n_warps = self.cta_n_blocks // 4
+
+        sh_block_route_indices = self.moe_block_size // 4
+        sh_rd_block_route_indices = self.moe_block_size // 4
+        sh_block_topk_weights = self.moe_block_size // 2
+        self.sh_valid_count_off = (
+            sh_block_route_indices + sh_rd_block_route_indices + sh_block_topk_weights
+        )
+        self.sh_route_off = 0
+        self.sh_rd_route_off = sh_block_route_indices
+        self.sh_topk_off = sh_block_route_indices + sh_rd_block_route_indices
+
+        sh_red_size = (2 * self.cta_n_blocks + 1) * 16 * self.cta_m_blocks
+        # B region size in int4 (16-byte) units. NF3 units are 12 bytes, so the
+        # region is 0.75x; round the total up to a 16-byte multiple so the
+        # following SMEM regions keep their 16-byte alignment (exact for all
+        # supported tiles since b_sh_stage is a multiple of 4).
+        sh_b_size = _covering_count(_STAGES * self.b_sh_stage_bytes, 16)
+        sh_size_min = min(sh_red_size, sh_b_size)
+        sh_size_max = max(sh_red_size, sh_b_size)
+        sh_bias_size = self.cta_n_blocks * 16 // 8
+        sh_b_red_bias_size = max(sh_size_max, sh_size_min + sh_bias_size)
+        self.sh_b_off = self.sh_valid_count_off
+        self.sh_red_off = self.sh_valid_count_off
+        self.sh_s_off = self.sh_valid_count_off + sh_b_red_bias_size
+        self.sh_a_off = self.sh_s_off + _STAGES * self.s_sh_stage
+        self.shared_int4 = self.sh_a_off + _STAGES * self.a_sh_stage
+        self.shared_words = self.shared_int4 * 4
+
+    @property
+    def __cache_key__(self) -> tuple[object, ...]:
+        return (
+            self.size_n,
+            self.size_k,
+            self.covered_size_n,
+            self.covered_size_k,
+            self.scale_k_groups,
+            self.has_logical_tail,
+            self.num_experts,
+            self.top_k,
+            self.mul_topk_weights,
+            self.tile_n,
+            self.tile_k,
+            self.cta_threads,
+            self.moe_block_size,
+            self.element_dtype,
+            self.epilogue_relu2,
+            self.weight_layout,
+            self.scale_format,
+            self.w13_layout,
+            self.source_n_rotation,
+            self.single_token_route_fast_path,
+            self.direct_topk_routes,
+            self.fused_topk_sum,
+            self.fused_sum_topk,
+            self.cta_m_blocks,
+            self.uses_m_block_8,
+            self.shared_words,
+            # Launch bounds are part of the compiled kernel.  Keep binaries
+            # planned for different residency targets out of the same cache
+            # entry even when their arithmetic geometry otherwise matches.
+            self.blocks_per_sm,
+        )
+
+    @cute.jit
+    def _activation_smem_permuted_offset(self, i: Int32) -> Int32:
+        row = i // Int32(self.a_gl_rd_delta_o)
+        return Int32(self.a_gl_rd_delta_o) * row + (
+            (i - row * Int32(self.a_gl_rd_delta_o)) ^ (row & Int32(7))
+        )
+
+    @cute.jit
+    def _int4_addr(self, smem_base: Int32, int4_off: Int32) -> Int32:
+        return smem_base + int4_off * Int32(16)
+
+    @cute.jit
+    def _dequant_e2m1x4_to_elem2x2(self, packed: Uint32):
+        if cutlass.const_expr(self.is_fp16):
+            return packed_dequant_e2m1x4_to_half2x2(packed)
+        return packed_dequant_e2m1x4_to_bfloat2x2(packed)
+
+    @cute.jit
+    def _dequant_e4m3x4_to_elem2x2(self, packed: Uint32):
+        if cutlass.const_expr(self.is_fp16):
+            return packed_dequant_e4m3x4_to_half2x2(packed)
+        return packed_dequant_e4m3x4_to_bfloat2x2(packed)
+
+    @cute.jit
+    def _dequant_scale_x4_to_elem2x2(self, packed: Uint32):
+        if cutlass.const_expr(self.scale_format_e8m0_k32):
+            if cutlass.const_expr(self.is_fp16):
+                return packed_dequant_e8m0x4_to_half2x2(packed)
+            return packed_dequant_e8m0x4_to_bfloat2x2(packed)
+        if cutlass.const_expr(self.is_fp16):
+            return packed_dequant_e4m3x4_to_half2x2(packed)
+        return packed_dequant_e4m3x4_to_bfloat2x2(packed)
+
+    @cute.jit
+    def _elem2_mul(self, a: Uint32, b: Uint32) -> Uint32:
+        if cutlass.const_expr(self.is_fp16):
+            return half2_mul(a, b)
+        return bfloat2_mul(a, b)
+
+    @cute.jit
+    def _broadcast_f32_to_elem2(self, x: cutlass.Float32) -> Uint32:
+        if cutlass.const_expr(self.is_fp16):
+            return broadcast_f32_to_half2(x)
+        return broadcast_f32_to_bfloat2(x)
+
+    @cute.jit
+    def _pack_f32x2_to_elem2(self, x0: cutlass.Float32, x1: cutlass.Float32) -> Uint32:
+        if cutlass.const_expr(self.is_fp16):
+            return pack_f32x2_to_f16x2(x0, x1)
+        return pack_f32x2_to_bfloat2(x0, x1)
+
+    @cute.jit
+    def _elem2_to_f32x2(self, packed: Uint32):
+        if cutlass.const_expr(self.is_fp16):
+            return half2_to_float2_scaled(packed, cutlass.Float32(1.0))
+        return bfloat2_to_float2_scaled(packed, cutlass.Float32(1.0))
+
+    @cute.jit
+    def _relu2_elem2(self, packed: Uint32) -> Uint32:
+        x0, x1 = self._elem2_to_f32x2(packed)
+        if x0 < cutlass.Float32(0.0):
+            x0 = cutlass.Float32(0.0)
+        if x1 < cutlass.Float32(0.0):
+            x1 = cutlass.Float32(0.0)
+        return self._pack_f32x2_to_elem2(x0 * x0, x1 * x1)
+
+    @cute.jit
+    def _st_shared_elem_from_f32(self, addr: Int32, val: cutlass.Float32):
+        if cutlass.const_expr(self.is_fp16):
+            st_shared_f16_from_f32(addr, val)
+        else:
+            st_shared_bf16_from_f32(addr, val)
+
+    @cute.jit
+    def _mma_m16n8k16_f32(
+        self,
+        d0: cutlass.Float32,
+        d1: cutlass.Float32,
+        d2: cutlass.Float32,
+        d3: cutlass.Float32,
+        a0: Uint32,
+        a1: Uint32,
+        a2: Uint32,
+        a3: Uint32,
+        b0: Uint32,
+        b1: Uint32,
+    ):
+        if cutlass.const_expr(self.is_fp16):
+            return f16_mma_m16n8k16_f32(d0, d1, d2, d3, a0, a1, a2, a3, b0, b1)
+        return bf16_mma_m16n8k16_f32(d0, d1, d2, d3, a0, a1, a2, a3, b0, b1)
+
+    @cute.jit
+    def _mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+        self,
+        d0: cutlass.Float32,
+        d1: cutlass.Float32,
+        d2: cutlass.Float32,
+        d3: cutlass.Float32,
+        b0_0: Uint32,
+        b1_0: Uint32,
+        b0_1: Uint32,
+        b1_1: Uint32,
+        a0: Uint32,
+        a1: Uint32,
+    ):
+        if cutlass.const_expr(self.is_fp16):
+            return f16_mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+                d0, d1, d2, d3, b0_0, b1_0, b0_1, b1_1, a0, a1
+            )
+        return bf16_mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+            d0, d1, d2, d3, b0_0, b1_0, b0_1, b1_1, a0, a1
+        )
+
+    @cute.jit
+    def __call__(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        active_m: cutlass.Int32,
+        grid_x: cutlass.Int32,
+        stream: cuda.CUstream,
+    ):
+        grid = (grid_x, 1, 1)
+        self.kernel(
+            a_bf16_flat,
+            b_i32_flat,
+            c_bf16_flat,
+            scales_i32_flat,
+            global_scale,
+            packed_route_indices,
+            block_expert_ids,
+            packed_route_count,
+            topk_weights_flat,
+            c_tmp_f32_flat,
+            locks_i32_flat,
+            active_m,
+        ).launch(
+            grid=grid,
+            block=[self.cta_threads, 1, 1],
+            min_blocks_per_mp=self.blocks_per_sm,
+            stream=stream,
+        )
+
+    @cute.kernel
+    def kernel(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        active_m: cutlass.Int32,
+    ):
+        tidx, _, _ = cute.arch.thread_idx()
+        bidx, _, _ = cute.arch.block_idx()
+        tid = Int32(tidx)
+        cta = Int32(bidx)
+
+        smem = cutlass.utils.SmemAllocator()
+
+        @cute.struct
+        class Storage:
+            words: cute.struct.Align[
+                cute.struct.MemRange[cutlass.Uint32, self.shared_words],
+                1024,
+            ]
+
+        storage = smem.allocate(Storage)
+        smem_base = shared_ptr_to_u32(storage.words.data_ptr())
+
+        grid_x, _, _ = cute.arch.grid_dim()
+        self._run_persistent_gemm(
+            a_bf16_flat,
+            b_i32_flat,
+            c_bf16_flat,
+            scales_i32_flat,
+            global_scale,
+            packed_route_indices,
+            block_expert_ids,
+            packed_route_count,
+            topk_weights_flat,
+            c_tmp_f32_flat,
+            locks_i32_flat,
+            smem_base,
+            tid,
+            cta,
+            Int32(grid_x),
+            Int32(active_m),
+        )
+
+    @cute.jit
+    def _run_persistent_gemm(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        cta: Int32,
+        grid_x: Int32,
+        active_size_m: Int32,
+    ):
+        n_tiles = Int32(self.n_tiles)
+        route_blocks = active_size_m * Int32(self.top_k)
+        if cutlass.const_expr(not self.direct_topk_routes):
+            route_blocks = packed_route_count[Int32(0)].to(Int32) // Int32(
+                self.moe_block_size
+            )
+        k_tiles = Int32(self.k_tiles)
+        global_mn_tiles = route_blocks * n_tiles
+
+        tail_mn_tiles = global_mn_tiles
+        full_grid_mn_iters = Int32(0)
+        force_one_tile_per_cta = Int32(0)
+        if cutlass.const_expr(self.uses_m_block_8):
+            # TC-decode small-M: when every mn-tile fits inside the launched grid
+            # (FC1 has only route_blocks*n_tiles tiles, far fewer than grid_x),
+            # the default tail path fans each mn-tile across multiple CTAs along
+            # K and pays a lock-serialized cross-CTA split-K finalize plus the
+            # reduction-turn handshake. Instead give the first global_mn_tiles
+            # CTAs exactly one full mn-tile (all k_tiles, reduce_slice_count==1,
+            # no finalize, no lock traffic) and idle the rest. grid_x and the
+            # grid-barrier participant count are unchanged (so FC2 coverage is
+            # untouched); only FC1's intra-GEMM work partition changes. Numerically
+            # identical: a single CTA computes the whole K-reduction per tile.
+            if global_mn_tiles <= grid_x:
+                force_one_tile_per_cta = Int32(1)
+        if force_one_tile_per_cta != Int32(0):
+            tail_mn_tiles = Int32(0)
+            full_grid_mn_iters = Int32(1)
+        elif global_mn_tiles > grid_x:
+            tail_mn_tiles = global_mn_tiles - (global_mn_tiles // grid_x) * grid_x
+            if tail_mn_tiles * Int32(3) <= grid_x:
+                tail_mn_tiles += grid_x
+            full_grid_mn_iters = (global_mn_tiles - tail_mn_tiles) // grid_x
+
+        iters = (k_tiles * tail_mn_tiles + grid_x - Int32(1)) // grid_x
+
+        lock_slot = Int32(0)
+        if tail_mn_tiles >= grid_x:
+            lock_slot = cta
+        else:
+            lock_slot = (iters * cta) // k_tiles - Int32(1)
+
+        in_tail_region = Int32(0)
+        has_work = Int32(1)
+        work_mn_tile = cta
+        reduce_k_tile = Int32(0)
+        route_block_idx = Int32(0)
+        output_n_tile = Int32(0)
+        if iters == Int32(0) and full_grid_mn_iters == Int32(0):
+            has_work = Int32(0)
+
+        while has_work != Int32(0):
+            reduce_tile_count = Int32(0)
+            reduce_slice_count = Int32(1)
+            reduce_slice_idx = Int32(0)
+
+            if in_tail_region == Int32(0) and full_grid_mn_iters > Int32(0):
+                route_block_idx = work_mn_tile // n_tiles
+                output_n_tile = work_mn_tile - route_block_idx * n_tiles
+                reduce_k_tile = Int32(0)
+                reduce_tile_count = k_tiles
+                full_grid_mn_iters -= Int32(1)
+            else:
+                if in_tail_region == Int32(0):
+                    in_tail_region = Int32(1)
+                    tail_mn_base = global_mn_tiles - tail_mn_tiles
+                    cta_iter_start = iters * cta
+                    work_mn_tile = cta_iter_start // k_tiles
+                    reduce_k_tile = cta_iter_start - work_mn_tile * k_tiles
+                    global_mn_tile = work_mn_tile + tail_mn_base
+                    route_block_idx = global_mn_tile // n_tiles
+                    output_n_tile = global_mn_tile - route_block_idx * n_tiles
+
+                if work_mn_tile < tail_mn_tiles and iters > Int32(0):
+                    reduce_tile_count = iters * (cta + Int32(1)) - (
+                        k_tiles * work_mn_tile + reduce_k_tile
+                    )
+                    if reduce_tile_count < Int32(0):
+                        reduce_tile_count = Int32(0)
+                    if reduce_k_tile + reduce_tile_count > k_tiles:
+                        reduce_tile_count = k_tiles - reduce_k_tile
+
+                    if reduce_tile_count > Int32(0):
+                        first_reduce_boundary = iters * (
+                            (k_tiles * work_mn_tile + iters - Int32(1)) // iters
+                        )
+                        if first_reduce_boundary <= k_tiles * (work_mn_tile + Int32(1)):
+                            reduce_boundary_offset = (
+                                first_reduce_boundary - k_tiles * work_mn_tile
+                            )
+                            reduce_slice_count = (
+                                k_tiles - reduce_boundary_offset + iters - Int32(1)
+                            ) // iters
+                            if reduce_boundary_offset > Int32(0):
+                                reduce_slice_count += Int32(1)
+                            reduce_boundary_delta = iters * cta - first_reduce_boundary
+                            if reduce_boundary_delta < Int32(0):
+                                reduce_slice_idx = reduce_slice_count - Int32(1)
+                            else:
+                                if reduce_boundary_offset == Int32(
+                                    0
+                                ) and reduce_boundary_delta == Int32(0):
+                                    reduce_slice_idx = reduce_slice_count - Int32(1)
+                                else:
+                                    reduce_slice_idx = (
+                                        reduce_slice_count
+                                        - Int32(1)
+                                        - reduce_boundary_delta // iters
+                                    )
+                                    if reduce_boundary_offset > Int32(0):
+                                        reduce_slice_idx -= Int32(1)
+
+                        if tail_mn_tiles >= grid_x:
+                            if reduce_slice_count > Int32(
+                                1
+                            ) and reduce_slice_idx == reduce_slice_count - Int32(1):
+                                lock_slot += Int32(1)
+                        else:
+                            lock_slot += Int32(1)
+                    else:
+                        has_work = Int32(0)
+                else:
+                    has_work = Int32(0)
+
+            if (
+                has_work != Int32(0)
+                and reduce_tile_count > Int32(0)
+                and route_block_idx < route_blocks
+            ):
+                if cutlass.const_expr(self.direct_topk_routes):
+                    expert_idx = packed_route_indices[route_block_idx].to(Int32)
+                else:
+                    expert_idx = block_expert_ids[route_block_idx].to(Int32)
+                if expert_idx >= Int32(0):
+                    self._run_tile(
+                        a_bf16_flat,
+                        b_i32_flat,
+                        c_bf16_flat,
+                        scales_i32_flat,
+                        global_scale,
+                        packed_route_indices,
+                        topk_weights_flat,
+                        c_tmp_f32_flat,
+                        locks_i32_flat,
+                        smem_base,
+                        tid,
+                        route_block_idx,
+                        expert_idx,
+                        output_n_tile,
+                        reduce_k_tile,
+                        reduce_tile_count,
+                        reduce_slice_count,
+                        reduce_slice_idx,
+                        lock_slot,
+                        active_size_m,
+                    )
+
+            if has_work != Int32(0):
+                if in_tail_region == Int32(0):
+                    work_mn_tile += grid_x
+                else:
+                    reduce_k_tile = Int32(0)
+                    work_mn_tile += Int32(1)
+                    output_n_tile += Int32(1)
+                    if output_n_tile == n_tiles:
+                        output_n_tile = Int32(0)
+                        route_block_idx += Int32(1)
+
+    @cute.jit
+    def _read_moe_block_data(
+        self,
+        packed_route_indices: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        route_block_idx: Int32,
+        global_scale_f32: cutlass.Float32,
+        active_size_m: Int32,
+    ) -> Int32:
+        if cutlass.const_expr(self.direct_topk_routes):
+            if tid == Int32(0):
+                idx = route_block_idx
+                st_shared_i32(smem_base + Int32(self.sh_route_off * 16), idx)
+                rd_row = idx // Int32(self.top_k)
+                st_shared_i32(smem_base + Int32(self.sh_rd_route_off * 16), rd_row)
+                if cutlass.const_expr(self.mul_topk_weights):
+                    topk = topk_weights_flat[idx].to(cutlass.Float32) * global_scale_f32
+                    st_shared_u32(
+                        smem_base + Int32(self.sh_topk_off * 16),
+                        self._broadcast_f32_to_elem2(topk),
+                    )
+            cute.arch.sync_threads()
+            return Int32(1)
+
+        if cutlass.const_expr(self.single_token_route_fast_path):
+            if tid == Int32(0):
+                idx = packed_route_indices[
+                    route_block_idx * Int32(self.moe_block_size)
+                ].to(Int32)
+                st_shared_i32(smem_base + Int32(self.sh_route_off * 16), idx)
+                rd_row = idx // Int32(self.top_k)
+                st_shared_i32(smem_base + Int32(self.sh_rd_route_off * 16), rd_row)
+                if cutlass.const_expr(self.mul_topk_weights):
+                    safe_idx = idx
+                    if idx >= active_size_m * Int32(self.top_k):
+                        safe_idx = Int32(0)
+                    topk = (
+                        topk_weights_flat[safe_idx].to(cutlass.Float32)
+                        * global_scale_f32
+                    )
+                    st_shared_u32(
+                        smem_base + Int32(self.sh_topk_off * 16),
+                        self._broadcast_f32_to_elem2(topk),
+                    )
+            cute.arch.sync_threads()
+            return Int32(1)
+
+        route_indices_int4_addr = self._int4_addr(
+            smem_base, Int32(self.sh_route_off) + tid
+        )
+        route_indices_gmem = get_ptr_as_int64(
+            packed_route_indices,
+            route_block_idx * Int32(self.moe_block_size) + tid * Int32(4),
+        )
+        cp_async4_shared_global_pred(
+            route_indices_int4_addr,
+            route_indices_gmem,
+            (tid < Int32(self.moe_block_size // 4)).to(Int32),
+        )
+        cute.arch.cp_async_commit_group()
+        cute.arch.cp_async_wait_group(0)
+        cute.arch.sync_threads()
+
+        if tid >= Int32(self.cta_threads - 32):
+            size_per_thread = _covering_count(self.moe_block_size, 32)
+            lane = tid - Int32(self.cta_threads - 32)
+            local_count = Int32(0)
+            for i in cutlass.range_constexpr(size_per_thread):
+                j = lane * Int32(size_per_thread) + Int32(i)
+                if j < Int32(self.moe_block_size):
+                    idx = ld_shared_i32_relaxed(
+                        smem_base + Int32(self.sh_route_off * 16) + j * Int32(4)
+                    )
+                    if idx < active_size_m * Int32(self.top_k):
+                        local_count += Int32(1)
+            valid = cute.arch.warp_redux_sync(local_count, "add")
+            if lane == Int32(0):
+                st_shared_i32(smem_base + Int32(self.sh_valid_count_off * 16), valid)
+
+        if tid < Int32(self.moe_block_size):
+            idx = ld_shared_i32_relaxed(
+                smem_base + Int32(self.sh_route_off * 16) + tid * Int32(4)
+            )
+            rd_row = idx // Int32(self.top_k)
+            st_shared_i32(
+                smem_base + Int32(self.sh_rd_route_off * 16) + tid * Int32(4),
+                rd_row,
+            )
+            if cutlass.const_expr(self.mul_topk_weights):
+                safe_idx = idx
+                if idx >= active_size_m * Int32(self.top_k):
+                    safe_idx = Int32(0)
+                topk = (
+                    topk_weights_flat[safe_idx].to(cutlass.Float32) * global_scale_f32
+                )
+                packed_topk = self._broadcast_f32_to_elem2(topk)
+                # top-k weights are cached as packed element pairs.
+                topk_word_addr = (
+                    smem_base + Int32(self.sh_topk_off * 16) + tid * Int32(4)
+                )
+                st_shared_u32(topk_word_addr, packed_topk)
+
+        cute.arch.sync_threads()
+        valid_count = ld_shared_i32_relaxed(
+            smem_base + Int32(self.sh_valid_count_off * 16)
+        )
+        cute.arch.sync_threads()
+        return valid_count
+
+    @cute.jit
+    def _run_tile(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        route_block_idx: Int32,
+        expert_idx: Int32,
+        output_n_tile: Int32,
+        reduce_k_tile: Int32,
+        reduce_tile_count: Int32,
+        reduce_slice_count: Int32,
+        reduce_slice_idx: Int32,
+        lock_slot: Int32,
+        active_size_m: Int32,
+    ):
+        if cutlass.const_expr(self.uses_m_block_8):
+            self._run_tile_m8(
+                a_bf16_flat,
+                b_i32_flat,
+                c_bf16_flat,
+                scales_i32_flat,
+                global_scale,
+                packed_route_indices,
+                topk_weights_flat,
+                c_tmp_f32_flat,
+                locks_i32_flat,
+                smem_base,
+                tid,
+                route_block_idx,
+                expert_idx,
+                output_n_tile,
+                reduce_k_tile,
+                reduce_tile_count,
+                reduce_slice_count,
+                reduce_slice_idx,
+                lock_slot,
+                active_size_m,
+            )
+        else:
+            self._run_tile_large_m(
+                a_bf16_flat,
+                b_i32_flat,
+                c_bf16_flat,
+                scales_i32_flat,
+                global_scale,
+                packed_route_indices,
+                topk_weights_flat,
+                c_tmp_f32_flat,
+                locks_i32_flat,
+                smem_base,
+                tid,
+                route_block_idx,
+                expert_idx,
+                output_n_tile,
+                reduce_k_tile,
+                reduce_tile_count,
+                reduce_slice_count,
+                reduce_slice_idx,
+                lock_slot,
+                active_size_m,
+            )
+
+    @cute.jit
+    def _tile_common_prologue(
+        self,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        route_block_idx: Int32,
+        expert_idx: Int32,
+        output_n_tile: Int32,
+        active_size_m: Int32,
+    ):
+        global_scale_f32 = global_scale[expert_idx].to(cutlass.Float32)
+        if cutlass.const_expr(self.scale_format_e8m0_k32):
+            if cutlass.const_expr(self.is_fp16):
+                global_scale_f32 *= cutlass.Float32(_E8M0_K32_FP16_GLOBAL_COMPENSATION)
+            else:
+                global_scale_f32 *= cutlass.Float32(_E8M0_K32_BF16_GLOBAL_COMPENSATION)
+        block_valid_rows = self._read_moe_block_data(
+            packed_route_indices,
+            topk_weights_flat,
+            smem_base,
+            tid,
+            route_block_idx,
+            global_scale_f32,
+            active_size_m,
+        )
+        (
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            b_sh_rd,
+            s_sh_rd,
+        ) = self._tile_stream_offsets(tid, expert_idx, output_n_tile)
+        return (
+            global_scale_f32,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            b_sh_rd,
+            s_sh_rd,
+        )
+
+    @cute.jit
+    def _tile_stream_offsets(self, tid: Int32, expert_idx: Int32, output_n_tile: Int32):
+        a_gl_stride = Int32(self.size_k // 8)
+        b_gl_stride = Int32(16 * self.size_n // (_PACK_FACTOR * 4))
+        s_gl_stride = Int32(self.scale_n_groups)
+        if cutlass.const_expr(self.scale_k32):
+            if cutlass.const_expr(
+                self.scale_format_e8m0_k32 and self.has_logical_tail
+            ):
+                scales_expert_stride = Int32(self.scale_k_groups * self.scale_n_groups)
+            else:
+                scales_expert_stride = Int32((self.size_n * self.size_k) // (32 * 16))
+        else:
+            scales_expert_stride = Int32((self.size_n * self.size_k) // (16 * 16))
+        b_expert_off = (
+            Int32((self.size_n * self.size_k) // (_PACK_FACTOR * 4)) * expert_idx
+        )
+        scales_expert_off = scales_expert_stride * expert_idx
+
+        a_gl_rd_row = tid // Int32(self.a_gl_rd_delta_o)
+        a_gl_rd_col0 = tid - a_gl_rd_row * Int32(self.a_gl_rd_delta_o)
+        a_sh_wr = Int32(self.a_sh_stride) * (tid // Int32(self.a_gl_rd_delta_o)) + (
+            tid - (tid // Int32(self.a_gl_rd_delta_o)) * Int32(self.a_gl_rd_delta_o)
+        )
+        a_rows_per_iter = Int32(self.cta_threads // self.a_gl_rd_delta_o)
+
+        if cutlass.const_expr(self.cta_threads <= self.b_sh_stride):
+            b_gl_rd_base = tid
+        else:
+            b_gl_rd_base = b_gl_stride * (tid // Int32(self.b_sh_stride)) + (
+                tid % Int32(self.b_sh_stride)
+            )
+        b_gl_rd_base += b_expert_off + Int32(self.b_sh_stride) * output_n_tile
+        b_sh_rd = tid
+        b_sh_rd += (b_sh_rd // Int32(self.b_sh_stride)) * Int32(
+            self.b_sh_stride * (self.b_sh_wr_iters - 1)
+        )
+
+        s_sh_rd = Int32(8) * ((tid // Int32(32)) % Int32(self.tb_n_warps)) + (
+            tid & Int32(31)
+        ) // Int32(4)
+        return (
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            b_sh_rd,
+            s_sh_rd,
+        )
+
+    @cute.jit
+    def _a_shared_read_offset(self, tid: Int32, lanes_per_row: cutlass.Constexpr[int]):
+        a_sh_rd = Int32(self.a_sh_stride) * (
+            (tid & Int32(31)) % Int32(lanes_per_row)
+        ) + (tid & Int32(31)) // Int32(lanes_per_row)
+        a_sh_rd += (
+            Int32(2)
+            * ((tid // Int32(32)) // Int32(self.tb_n_warps))
+            * Int32(self.b_sh_wr_iters)
+        )
+        return a_sh_rd
+
+    @cute.jit
+    def _run_tile_m8(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        route_block_idx: Int32,
+        expert_idx: Int32,
+        output_n_tile: Int32,
+        reduce_k_tile: Int32,
+        reduce_tile_count: Int32,
+        reduce_slice_count: Int32,
+        reduce_slice_idx: Int32,
+        lock_slot: Int32,
+        active_size_m: Int32,
+    ):
+        (
+            global_scale_f32,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            b_sh_rd,
+            s_sh_rd,
+        ) = self._tile_common_prologue(
+            global_scale,
+            packed_route_indices,
+            topk_weights_flat,
+            smem_base,
+            tid,
+            route_block_idx,
+            expert_idx,
+            output_n_tile,
+            active_size_m,
+        )
+        a_sh_rd = self._a_shared_read_offset(tid, 8)
+
+        acc = cute.make_rmem_tensor((4, 4), cutlass.Float32)
+        acc.fill(0.0)
+
+        k_tiles = reduce_tile_count
+        self._prefetch_initial_tiles(
+            a_bf16_flat,
+            b_i32_flat,
+            scales_i32_flat,
+            smem_base,
+            tid,
+            k_tiles,
+            reduce_k_tile,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            output_n_tile,
+            expert_idx,
+        )
+
+        b_scale_cur = cute.make_rmem_tensor((2, 4), Uint32)
+        b_scale_next = cute.make_rmem_tensor((2, 4), Uint32)
+        self._load_b_scale_register_bundle(
+            b_scale_cur,
+            smem_base,
+            tid,
+            b_sh_rd,
+            s_sh_rd,
+            Int32(0),
+            Int32(0),
+        )
+        a_regs_cur = cute.make_rmem_tensor((2,), Uint32)
+        a_regs_next = cute.make_rmem_tensor((2,), Uint32)
+        self._load_a_register_bundle(
+            a_regs_cur,
+            smem_base,
+            a_sh_rd,
+            Int32(0),
+            Int32(0),
+            True,
+        )
+        self._run_mma_pipeline(
+            a_bf16_flat,
+            b_i32_flat,
+            scales_i32_flat,
+            smem_base,
+            tid,
+            acc,
+            b_scale_cur,
+            b_scale_next,
+            a_regs_cur,
+            a_regs_next,
+            b_sh_rd,
+            s_sh_rd,
+            a_sh_rd,
+            k_tiles,
+            reduce_k_tile,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            output_n_tile,
+            expert_idx,
+            True,
+        )
+
+        self._finish_tile(
+            acc,
+            c_bf16_flat,
+            c_tmp_f32_flat,
+            locks_i32_flat,
+            smem_base,
+            tid,
+            output_n_tile,
+            block_valid_rows,
+            global_scale_f32,
+            reduce_slice_count,
+            reduce_slice_idx,
+            lock_slot,
+            True,
+        )
+
+    @cute.jit
+    def _run_tile_large_m(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        topk_weights_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        route_block_idx: Int32,
+        expert_idx: Int32,
+        output_n_tile: Int32,
+        reduce_k_tile: Int32,
+        reduce_tile_count: Int32,
+        reduce_slice_count: Int32,
+        reduce_slice_idx: Int32,
+        lock_slot: Int32,
+        active_size_m: Int32,
+    ):
+        (
+            global_scale_f32,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            b_sh_rd,
+            s_sh_rd,
+        ) = self._tile_common_prologue(
+            global_scale,
+            packed_route_indices,
+            topk_weights_flat,
+            smem_base,
+            tid,
+            route_block_idx,
+            expert_idx,
+            output_n_tile,
+            active_size_m,
+        )
+        a_sh_rd = self._a_shared_read_offset(tid, 16)
+
+        acc = cute.make_rmem_tensor((self.cta_m_blocks, 4, 2, 4), cutlass.Float32)
+        acc.fill(0.0)
+
+        k_tiles = reduce_tile_count
+        self._prefetch_initial_tiles(
+            a_bf16_flat,
+            b_i32_flat,
+            scales_i32_flat,
+            smem_base,
+            tid,
+            k_tiles,
+            reduce_k_tile,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            output_n_tile,
+            expert_idx,
+        )
+
+        b_scale_cur = cute.make_rmem_tensor((2, 4), Uint32)
+        b_scale_next = cute.make_rmem_tensor((2, 4), Uint32)
+        self._load_b_scale_register_bundle(
+            b_scale_cur,
+            smem_base,
+            tid,
+            b_sh_rd,
+            s_sh_rd,
+            Int32(0),
+            Int32(0),
+        )
+        a_regs = cute.make_rmem_tensor((self.cta_m_blocks, 4), Uint32)
+        a_regs_next = cute.make_rmem_tensor((self.cta_m_blocks, 4), Uint32)
+        self._load_a_register_bundle(
+            a_regs,
+            smem_base,
+            a_sh_rd,
+            Int32(0),
+            Int32(0),
+            False,
+        )
+        self._run_mma_pipeline(
+            a_bf16_flat,
+            b_i32_flat,
+            scales_i32_flat,
+            smem_base,
+            tid,
+            acc,
+            b_scale_cur,
+            b_scale_next,
+            a_regs,
+            a_regs_next,
+            b_sh_rd,
+            s_sh_rd,
+            a_sh_rd,
+            k_tiles,
+            reduce_k_tile,
+            block_valid_rows,
+            a_gl_stride,
+            b_gl_stride,
+            s_gl_stride,
+            scales_expert_off,
+            b_gl_rd_base,
+            a_gl_rd_row,
+            a_gl_rd_col0,
+            a_sh_wr,
+            a_rows_per_iter,
+            output_n_tile,
+            expert_idx,
+            False,
+        )
+
+        self._finish_tile(
+            acc,
+            c_bf16_flat,
+            c_tmp_f32_flat,
+            locks_i32_flat,
+            smem_base,
+            tid,
+            output_n_tile,
+            block_valid_rows,
+            global_scale_f32,
+            reduce_slice_count,
+            reduce_slice_idx,
+            lock_slot,
+            False,
+        )
+
+    @cute.jit
+    def _run_mma_pipeline(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        acc: cute.Tensor,
+        b_scale_cur: cute.Tensor,
+        b_scale_next: cute.Tensor,
+        a_regs_cur: cute.Tensor,
+        a_regs_next: cute.Tensor,
+        b_sh_rd: Int32,
+        s_sh_rd: Int32,
+        a_sh_rd: Int32,
+        k_tiles: Int32,
+        reduce_k_tile: Int32,
+        block_valid_rows: Int32,
+        a_gl_stride: Int32,
+        b_gl_stride: Int32,
+        s_gl_stride: Int32,
+        scales_expert_off: Int32,
+        b_gl_rd_base: Int32,
+        a_gl_rd_row: Int32,
+        a_gl_rd_col0: Int32,
+        a_sh_wr: Int32,
+        a_rows_per_iter: Int32,
+        output_n_tile: Int32,
+        expert_idx: Int32,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        b_frag = cute.make_rmem_tensor((2, 2), Uint32)
+        tile_idx = Int32(0)
+        while tile_idx < k_tiles:
+            for pipe in cutlass.range_constexpr(_STAGES):
+                if tile_idx < k_tiles:
+                    for kk in cutlass.range_constexpr(self.b_sh_wr_iters):
+                        self._load_next_fragment_bundle(
+                            b_scale_next,
+                            a_regs_next,
+                            smem_base,
+                            tid,
+                            b_sh_rd,
+                            s_sh_rd,
+                            a_sh_rd,
+                            pipe,
+                            kk,
+                            tile_idx,
+                            k_tiles,
+                            uses_m_block_8,
+                        )
+
+                        self._prefetch_pipeline_step(
+                            a_bf16_flat,
+                            b_i32_flat,
+                            scales_i32_flat,
+                            smem_base,
+                            tid,
+                            pipe,
+                            kk,
+                            tile_idx,
+                            k_tiles,
+                            reduce_k_tile,
+                            block_valid_rows,
+                            a_gl_stride,
+                            b_gl_stride,
+                            s_gl_stride,
+                            scales_expert_off,
+                            b_gl_rd_base,
+                            a_gl_rd_row,
+                            a_gl_rd_col0,
+                            a_sh_wr,
+                            a_rows_per_iter,
+                            output_n_tile,
+                            expert_idx,
+                        )
+
+                        for jj in cutlass.range_constexpr(4):
+                            if cutlass.const_expr(self.weight_layout_nf3):
+                                # NF3 triple: lo16 = half (jj % 2) of word
+                                # (jj // 2); hi8 = byte jj of the hi word; scale
+                                # register is the same per-jj lane as packed.
+                                lo_w = b_scale_cur[0, jj // 2]
+                                lo16 = (lo_w >> Uint32(16 * (jj % 2))) & Uint32(0xFFFF)
+                                hi8 = (b_scale_cur[0, 2] >> Uint32(8 * jj)) & Uint32(
+                                    0xFF
+                                )
+                                s = b_scale_cur[1, jj]
+                                self._scaled_dequant_b_fragment_nf3(
+                                    b_frag, lo16, hi8, s
+                                )
+                            else:
+                                q, s = self._select_b_scale_register(jj, b_scale_cur)
+                                self._scaled_dequant_b_fragment(b_frag, q, s)
+                            if cutlass.const_expr(uses_m_block_8):
+                                self._mma_accumulate_m8(
+                                    acc,
+                                    jj,
+                                    a_regs_cur,
+                                    b_frag,
+                                )
+                            else:
+                                for mb in cutlass.range_constexpr(self.cta_m_blocks):
+                                    self._mma_accumulate_large_m(
+                                        acc,
+                                        a_regs_cur,
+                                        mb,
+                                        jj,
+                                        b_frag,
+                                    )
+
+                        if cutlass.const_expr(uses_m_block_8):
+                            self._copy_a_register_bundle(
+                                a_regs_cur,
+                                a_regs_next,
+                                uses_m_block_8,
+                            )
+                            self._copy_b_scale_register_bundle(
+                                b_scale_cur, b_scale_next
+                            )
+                        else:
+                            self._copy_b_scale_register_bundle(
+                                b_scale_cur, b_scale_next
+                            )
+                            self._copy_a_register_bundle(
+                                a_regs_cur,
+                                a_regs_next,
+                                uses_m_block_8,
+                            )
+                    tile_idx += Int32(1)
+            cute.arch.sync_threads()
+            if tile_idx < k_tiles:
+                self._load_b_scale_register_bundle(
+                    b_scale_cur,
+                    smem_base,
+                    tid,
+                    b_sh_rd,
+                    s_sh_rd,
+                    Int32(0),
+                    Int32(0),
+                )
+                self._load_a_register_bundle(
+                    a_regs_cur,
+                    smem_base,
+                    a_sh_rd,
+                    Int32(0),
+                    Int32(0),
+                    uses_m_block_8,
+                )
+
+    @cute.jit
+    def _finish_tile(
+        self,
+        acc: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        output_n_tile: Int32,
+        block_valid_rows: Int32,
+        global_scale_f32: cutlass.Float32,
+        reduce_slice_count: Int32,
+        reduce_slice_idx: Int32,
+        lock_slot: Int32,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        if cutlass.const_expr(uses_m_block_8):
+            self._fold_cta_partials_m8(acc, smem_base, tid)
+        else:
+            self._fold_cta_partials_large_m(acc, smem_base, tid)
+
+        if reduce_slice_count > Int32(1):
+            self._wait_for_reduction_turn(
+                locks_i32_flat, lock_slot, reduce_slice_idx, tid
+            )
+            self._combine_splitk_accumulators(
+                acc,
+                c_tmp_f32_flat,
+                block_valid_rows,
+                lock_slot,
+                reduce_slice_idx,
+                reduce_slice_count,
+                tid,
+                uses_m_block_8,
+            )
+            self._publish_reduction_turn(
+                locks_i32_flat,
+                lock_slot,
+                reduce_slice_idx == reduce_slice_count - Int32(1),
+                tid,
+            )
+
+        if reduce_slice_idx == reduce_slice_count - Int32(1):
+            if cutlass.const_expr(uses_m_block_8):
+                self._store_tile_m8(
+                    acc,
+                    c_bf16_flat,
+                    smem_base,
+                    tid,
+                    output_n_tile,
+                    block_valid_rows,
+                    global_scale_f32,
+                )
+            else:
+                self._store_tile_large_m(
+                    acc,
+                    c_bf16_flat,
+                    smem_base,
+                    tid,
+                    output_n_tile,
+                    block_valid_rows,
+                    global_scale_f32,
+                )
+
+    @cute.jit
+    def _wait_for_reduction_turn(
+        self,
+        locks_i32_flat: cute.Tensor,
+        lock_slot: Int32,
+        count: Int32,
+        tid: Int32,
+    ):
+        lock_addr = get_ptr_as_int64(locks_i32_flat, lock_slot)
+        if tid == Int32(0):
+            state = Int32(-1)
+            while state != count:
+                state = ld_global_acquire_i32(lock_addr)
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _publish_reduction_turn(
+        self,
+        locks_i32_flat: cute.Tensor,
+        lock_slot: Int32,
+        reset,
+        tid: Int32,
+    ):
+        lock_addr = get_ptr_as_int64(locks_i32_flat, lock_slot)
+        cute.arch.sync_threads()
+        if tid == Int32(0):
+            if reset:
+                st_global_i32(lock_addr, Int32(0))
+            else:
+                red_add_global_release_i32(lock_addr, Int32(1))
+
+    @cute.jit
+    def _merge_splitk_vec4(
+        self,
+        c_tmp_f32_flat: cute.Tensor,
+        f32_off: Int32,
+        reduce_slice_idx: Int32,
+        reduce_slice_count: Int32,
+        c0: cutlass.Float32,
+        c1: cutlass.Float32,
+        c2: cutlass.Float32,
+        c3: cutlass.Float32,
+    ):
+        if reduce_slice_idx != Int32(0):
+            r0, r1, r2, r3 = ld_global_v4_f32(get_ptr_as_int64(c_tmp_f32_flat, f32_off))
+            c0 = c0 + r0
+            c1 = c1 + r1
+            c2 = c2 + r2
+            c3 = c3 + r3
+        if reduce_slice_idx != reduce_slice_count - Int32(1):
+            st_global_v4_f32(
+                get_ptr_as_int64(c_tmp_f32_flat, f32_off),
+                c0,
+                c1,
+                c2,
+                c3,
+            )
+        return c0, c1, c2, c3
+
+    @cute.jit
+    def _combine_splitk_accumulators(
+        self,
+        acc: cute.Tensor,
+        c_tmp_f32_flat: cute.Tensor,
+        block_valid_rows: Int32,
+        lock_slot: Int32,
+        reduce_slice_idx: Int32,
+        reduce_slice_count: Int32,
+        tid: Int32,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        active_threads = Int32(32 * self.tb_n_warps)
+        c_size_int4 = Int32((self.cta_m_blocks * 16 * self.cta_n_blocks * 16) // 4)
+        c_cur_offset = lock_slot * c_size_int4
+        if cutlass.const_expr(uses_m_block_8):
+            if tid < active_threads:
+                for jj in cutlass.range_constexpr(4):
+                    k = jj * 2
+                    acc[jj, 0], acc[jj, 1], acc[jj, 2], acc[jj, 3] = (
+                        self._merge_splitk_slot(
+                            c_tmp_f32_flat,
+                            c_cur_offset,
+                            active_threads,
+                            Int32(k),
+                            tid,
+                            reduce_slice_idx,
+                            reduce_slice_count,
+                            acc[jj, 0],
+                            acc[jj, 1],
+                            acc[jj, 2],
+                            acc[jj, 3],
+                        )
+                    )
+        else:
+            lane_row = (tid & Int32(31)) // Int32(4)
+            if tid < active_threads:
+                for k in cutlass.range_constexpr(self.cta_m_blocks * 8):
+                    mb = k // 8
+                    flat_j = k % 8
+                    jj = flat_j // 2
+                    half = flat_j % 2
+                    row_valid = Int32(mb * 16) + lane_row < block_valid_rows
+                    if row_valid:
+                        (
+                            acc[mb, jj, half, 0],
+                            acc[mb, jj, half, 1],
+                            acc[mb, jj, half, 2],
+                            acc[mb, jj, half, 3],
+                        ) = self._merge_splitk_slot(
+                            c_tmp_f32_flat,
+                            c_cur_offset,
+                            active_threads,
+                            Int32(k),
+                            tid,
+                            reduce_slice_idx,
+                            reduce_slice_count,
+                            acc[mb, jj, half, 0],
+                            acc[mb, jj, half, 1],
+                            acc[mb, jj, half, 2],
+                            acc[mb, jj, half, 3],
+                        )
+
+    @cute.jit
+    def _merge_splitk_slot(
+        self,
+        c_tmp_f32_flat: cute.Tensor,
+        c_cur_offset: Int32,
+        active_threads: Int32,
+        slot: Int32,
+        tid: Int32,
+        reduce_slice_idx: Int32,
+        reduce_slice_count: Int32,
+        c0: cutlass.Float32,
+        c1: cutlass.Float32,
+        c2: cutlass.Float32,
+        c3: cutlass.Float32,
+    ):
+        int4_off = c_cur_offset + active_threads * slot + tid
+        return self._merge_splitk_vec4(
+            c_tmp_f32_flat,
+            int4_off * Int32(4),
+            reduce_slice_idx,
+            reduce_slice_count,
+            c0,
+            c1,
+            c2,
+            c3,
+        )
+
+    @cute.jit
+    def _load_a_registers_large_m(
+        self,
+        smem_base: Int32,
+        a_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+        m_block: Int32,
+    ):
+        a_addr = self._int4_addr(
+            smem_base,
+            Int32(self.sh_a_off)
+            + pipe * Int32(self.a_sh_stage)
+            + self._activation_smem_permuted_offset(
+                Int32(2) * kk + m_block * Int32(self.a_sh_rd_delta_i) + a_sh_rd
+            ),
+        )
+        return ldmatrix_m8n8x4_b16(a_addr)
+
+    @cute.jit
+    def _load_a_registers_m8(
+        self,
+        smem_base: Int32,
+        a_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        a_addr = self._int4_addr(
+            smem_base,
+            Int32(self.sh_a_off)
+            + pipe * Int32(self.a_sh_stage)
+            + self._activation_smem_permuted_offset(Int32(2) * kk + a_sh_rd),
+        )
+        return ldmatrix_m8n8x2_b16(a_addr)
+
+    @cute.jit
+    def _load_a_registers_large_m_bundle(
+        self,
+        regs: cute.Tensor,
+        smem_base: Int32,
+        a_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        for mb in cutlass.range_constexpr(self.cta_m_blocks):
+            a0, a1, a2, a3 = self._load_a_registers_large_m(
+                smem_base,
+                a_sh_rd,
+                pipe,
+                kk,
+                Int32(mb),
+            )
+            regs[mb, 0] = a0
+            regs[mb, 1] = a1
+            regs[mb, 2] = a2
+            regs[mb, 3] = a3
+
+    @cute.jit
+    def _load_a_registers_m8_bundle(
+        self,
+        regs: cute.Tensor,
+        smem_base: Int32,
+        a_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        a0, a1 = self._load_a_registers_m8(smem_base, a_sh_rd, pipe, kk)
+        regs[0] = a0
+        regs[1] = a1
+
+    @cute.jit
+    def _clear_a_register_bundle_large_m(self, regs: cute.Tensor):
+        for mb in cutlass.range_constexpr(self.cta_m_blocks):
+            for reg in cutlass.range_constexpr(4):
+                regs[mb, reg] = Uint32(0)
+
+    @cute.jit
+    def _clear_a_register_bundle_m8(self, regs: cute.Tensor):
+        for reg in cutlass.range_constexpr(2):
+            regs[reg] = Uint32(0)
+
+    @cute.jit
+    def _copy_a_register_bundle_large_m(self, dst: cute.Tensor, src: cute.Tensor):
+        for mb in cutlass.range_constexpr(self.cta_m_blocks):
+            for reg in cutlass.range_constexpr(4):
+                dst[mb, reg] = src[mb, reg]
+
+    @cute.jit
+    def _copy_a_register_bundle_m8(self, dst: cute.Tensor, src: cute.Tensor):
+        for reg in cutlass.range_constexpr(2):
+            dst[reg] = src[reg]
+
+    @cute.jit
+    def _load_a_register_bundle(
+        self,
+        regs: cute.Tensor,
+        smem_base: Int32,
+        a_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        if cutlass.const_expr(uses_m_block_8):
+            self._load_a_registers_m8_bundle(regs, smem_base, a_sh_rd, pipe, kk)
+        else:
+            self._load_a_registers_large_m_bundle(regs, smem_base, a_sh_rd, pipe, kk)
+
+    @cute.jit
+    def _clear_a_register_bundle(
+        self,
+        regs: cute.Tensor,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        if cutlass.const_expr(uses_m_block_8):
+            self._clear_a_register_bundle_m8(regs)
+        else:
+            self._clear_a_register_bundle_large_m(regs)
+
+    @cute.jit
+    def _copy_a_register_bundle(
+        self,
+        dst: cute.Tensor,
+        src: cute.Tensor,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        if cutlass.const_expr(uses_m_block_8):
+            self._copy_a_register_bundle_m8(dst, src)
+        else:
+            self._copy_a_register_bundle_large_m(dst, src)
+
+    @cute.jit
+    def _load_b_scale_registers(
+        self,
+        smem_base: Int32,
+        tid: Int32,
+        b_sh_rd: Int32,
+        s_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        if cutlass.const_expr(self.weight_layout == "modelopt"):
+            q0, q1, q2, q3 = self._load_b_registers_modelopt_shared(
+                smem_base,
+                b_sh_rd,
+                pipe,
+                kk,
+            )
+        elif cutlass.const_expr(self.weight_layout_nf3):
+            # NF3-MAPPING-V1: the thread's 32-code unit index within the pipe's
+            # B region equals the stock staged-unit index (algebraically
+            # identical to b_sh_stride*kk + b_sh_rd): cur_group_id is the K16 row
+            # within the tile, (tid % b_sh_stride) is the N-pair. Each unit is a
+            # 12-byte (lo0, lo1, hi) triple; three scalar u32 loads over stride-3
+            # words are bank-conflict free (gcd(3, 32) == 1). q3 is unused.
+            nf3_warp_id = tid // Int32(32)
+            nf3_warp_row = nf3_warp_id // Int32(self.tb_n_warps)
+            nf3_group = Int32(self.b_sh_wr_iters) * nf3_warp_row + kk
+            nf3_unit = nf3_group * Int32(self.b_sh_stride) + (
+                tid % Int32(self.b_sh_stride)
+            )
+            b_addr = (
+                smem_base
+                + Int32(self.sh_b_off * 16)
+                + pipe * Int32(self.b_sh_stage_bytes)
+                + nf3_unit * Int32(12)
+            )
+            q0 = ld_shared_u32(b_addr)
+            q1 = ld_shared_u32(b_addr + Int32(4))
+            q2 = ld_shared_u32(b_addr + Int32(8))
+            q3 = Uint32(0)
+        else:
+            b_addr = self._int4_addr(
+                smem_base,
+                Int32(self.sh_b_off)
+                + pipe * Int32(self.b_sh_stage)
+                + Int32(self.b_sh_stride) * kk
+                + b_sh_rd,
+            )
+            q0, q1, q2, q3 = ld_shared_v4_u32(b_addr)
+
+        warp_id = tid // Int32(32)
+        warp_row = warp_id // Int32(self.tb_n_warps)
+        cur_group_id = Int32(self.b_sh_wr_iters) * warp_row + kk
+        if cutlass.const_expr(self.scale_k32):
+            scale_group_id = cur_group_id // Int32(2)
+        else:
+            scale_group_id = cur_group_id
+        s_addr = (
+            smem_base
+            + Int32(self.sh_s_off * 16)
+            + pipe * Int32(self.s_sh_stage * 16)
+            + (s_sh_rd + scale_group_id * Int32(2 * self.s_sh_stride)) * Int32(8)
+        )
+        s_pack0, s_pack1 = ld_shared_v2_u32(s_addr)
+        s0, s1 = self._dequant_scale_x4_to_elem2x2(s_pack0)
+        s2, s3 = self._dequant_scale_x4_to_elem2x2(s_pack1)
+        return q0, q1, q2, q3, s0, s1, s2, s3
+
+    @cute.jit
+    def _load_b_scale_register_bundle(
+        self,
+        regs: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        b_sh_rd: Int32,
+        s_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        q0, q1, q2, q3, s0, s1, s2, s3 = self._load_b_scale_registers(
+            smem_base,
+            tid,
+            b_sh_rd,
+            s_sh_rd,
+            pipe,
+            kk,
+        )
+        regs[0, 0] = q0
+        regs[0, 1] = q1
+        regs[0, 2] = q2
+        regs[0, 3] = q3
+        regs[1, 0] = s0
+        regs[1, 1] = s1
+        regs[1, 2] = s2
+        regs[1, 3] = s3
+
+    @cute.jit
+    def _clear_b_scale_register_bundle(self, regs: cute.Tensor):
+        for row in cutlass.range_constexpr(2):
+            for col in cutlass.range_constexpr(4):
+                regs[row, col] = Uint32(0)
+
+    @cute.jit
+    def _copy_b_scale_register_bundle(self, dst: cute.Tensor, src: cute.Tensor):
+        for row in cutlass.range_constexpr(2):
+            for col in cutlass.range_constexpr(4):
+                dst[row, col] = src[row, col]
+
+    @cute.jit
+    def _select_b_scale_register(self, jj: cutlass.Constexpr[int], regs: cute.Tensor):
+        return regs[0, jj], regs[1, jj]
+
+    @cute.jit
+    def _load_next_fragment_bundle(
+        self,
+        b_scale_next: cute.Tensor,
+        a_regs_next: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        b_sh_rd: Int32,
+        s_sh_rd: Int32,
+        a_sh_rd: Int32,
+        pipe: cutlass.Constexpr[int],
+        kk: cutlass.Constexpr[int],
+        tile_idx: Int32,
+        k_tiles: Int32,
+        uses_m_block_8: cutlass.Constexpr[bool],
+    ):
+        self._clear_b_scale_register_bundle(b_scale_next)
+        self._clear_a_register_bundle(a_regs_next, uses_m_block_8)
+
+        if cutlass.const_expr(kk + 1 < self.b_sh_wr_iters):
+            if tile_idx < k_tiles:
+                self._load_b_scale_register_bundle(
+                    b_scale_next,
+                    smem_base,
+                    tid,
+                    b_sh_rd,
+                    s_sh_rd,
+                    Int32(pipe),
+                    Int32(kk + 1),
+                )
+                self._load_a_register_bundle(
+                    a_regs_next,
+                    smem_base,
+                    a_sh_rd,
+                    Int32(pipe),
+                    Int32(kk + 1),
+                    uses_m_block_8,
+                )
+        else:
+            next_tile = tile_idx + Int32(1)
+            if next_tile < k_tiles:
+                self._load_b_scale_register_bundle(
+                    b_scale_next,
+                    smem_base,
+                    tid,
+                    b_sh_rd,
+                    s_sh_rd,
+                    Int32((pipe + 1) % _STAGES),
+                    Int32(0),
+                )
+                self._load_a_register_bundle(
+                    a_regs_next,
+                    smem_base,
+                    a_sh_rd,
+                    Int32((pipe + 1) % _STAGES),
+                    Int32(0),
+                    uses_m_block_8,
+                )
+
+    @cute.jit
+    def _scaled_dequant_b_fragment(self, frag: cute.Tensor, q: Uint32, s: Uint32):
+        bq1 = q
+        bq0 = bq1 << Uint32(8)
+        b0_0, b0_1 = self._dequant_e2m1x4_to_elem2x2(bq0)
+        b1_0, b1_1 = self._dequant_e2m1x4_to_elem2x2(bq1)
+        s_lane0 = bfloat2_broadcast_lane(s, Int32(0))
+        s_lane1 = bfloat2_broadcast_lane(s, Int32(1))
+        b0_0 = self._elem2_mul(b0_0, s_lane0)
+        b0_1 = self._elem2_mul(b0_1, s_lane0)
+        b1_0 = self._elem2_mul(b1_0, s_lane1)
+        b1_1 = self._elem2_mul(b1_1, s_lane1)
+        frag[0, 0] = b0_0
+        frag[0, 1] = b0_1
+        frag[1, 0] = b1_0
+        frag[1, 1] = b1_1
+
+    @cute.jit
+    def _scaled_dequant_b_fragment_nf3(
+        self, frag: cute.Tensor, lo16: Uint32, hi8: Uint32, s: Uint32
+    ):
+        # NF3: 8 3-bit codes (2 lo-bits in lo16, 1 hi-bit in hi8) -> 4 bf16x2
+        # codebook fragments, in the SAME element order the packed path uses:
+        # o0=(cb[c0],cb[c1]) -> frag[0,0], o1 -> frag[0,1], o2 -> frag[1,0],
+        # o3 -> frag[1,1]. frag[0,*] takes the N-col-0 scale lane, frag[1,*] the
+        # N-col-1 lane (identical broadcast to _scaled_dequant_b_fragment).
+        o0, o1, o2, o3 = packed_dequant_nf3x8_to_bfloat2x4(
+            lo16,
+            hi8,
+            Uint32(self._nf3_cb0),
+            Uint32(self._nf3_cb1),
+            Uint32(self._nf3_cb2),
+            Uint32(self._nf3_cb3),
+        )
+        s_lane0 = bfloat2_broadcast_lane(s, Int32(0))
+        s_lane1 = bfloat2_broadcast_lane(s, Int32(1))
+        frag[0, 0] = self._elem2_mul(o0, s_lane0)
+        frag[0, 1] = self._elem2_mul(o1, s_lane0)
+        frag[1, 0] = self._elem2_mul(o2, s_lane1)
+        frag[1, 1] = self._elem2_mul(o3, s_lane1)
+
+    @cute.jit
+    def _mma_accumulate_m8(
+        self,
+        acc: cute.Tensor,
+        jj: cutlass.Constexpr[int],
+        a_regs: cute.Tensor,
+        b_frag: cute.Tensor,
+    ):
+        d0, d1, d2, d3 = self._mma_rhs_fragments_as_mma_a_m16n8k16_f32(
+            acc[jj, 0],
+            acc[jj, 1],
+            acc[jj, 2],
+            acc[jj, 3],
+            b_frag[0, 0],
+            b_frag[1, 0],
+            b_frag[0, 1],
+            b_frag[1, 1],
+            a_regs[0],
+            a_regs[1],
+        )
+        acc[jj, 0] = d0
+        acc[jj, 1] = d1
+        acc[jj, 2] = d2
+        acc[jj, 3] = d3
+
+    @cute.jit
+    def _mma_accumulate_large_m(
+        self,
+        acc: cute.Tensor,
+        a_regs: cute.Tensor,
+        mb: cutlass.Constexpr[int],
+        jj: cutlass.Constexpr[int],
+        b_frag: cute.Tensor,
+    ):
+        d0, d1, d2, d3 = self._mma_m16n8k16_f32(
+            acc[mb, jj, 0, 0],
+            acc[mb, jj, 0, 1],
+            acc[mb, jj, 0, 2],
+            acc[mb, jj, 0, 3],
+            a_regs[mb, 0],
+            a_regs[mb, 1],
+            a_regs[mb, 2],
+            a_regs[mb, 3],
+            b_frag[0, 0],
+            b_frag[0, 1],
+        )
+        acc[mb, jj, 0, 0] = d0
+        acc[mb, jj, 0, 1] = d1
+        acc[mb, jj, 0, 2] = d2
+        acc[mb, jj, 0, 3] = d3
+        d0, d1, d2, d3 = self._mma_m16n8k16_f32(
+            acc[mb, jj, 1, 0],
+            acc[mb, jj, 1, 1],
+            acc[mb, jj, 1, 2],
+            acc[mb, jj, 1, 3],
+            a_regs[mb, 0],
+            a_regs[mb, 1],
+            a_regs[mb, 2],
+            a_regs[mb, 3],
+            b_frag[1, 0],
+            b_frag[1, 1],
+        )
+        acc[mb, jj, 1, 0] = d0
+        acc[mb, jj, 1, 1] = d1
+        acc[mb, jj, 1, 2] = d2
+        acc[mb, jj, 1, 3] = d3
+
+    @cute.jit
+    def _source_n_from_logical(self, logical_n: Int32) -> Int32:
+        source_n = logical_n
+        if cutlass.const_expr(self.source_n_rotation != 0):
+            source_n += Int32(self.source_n_rotation)
+            if source_n >= Int32(self.size_n):
+                source_n -= Int32(self.size_n)
+        return source_n
+
+    @cute.jit
+    def _stage_b_tile_modelopt_native(
+        self,
+        b_u8_flat: cute.Tensor,
+        smem_addr: Int32,
+        expert_idx: Int32,
+        output_n_tile: Int32,
+        tile_idx: Int32,
+        local_int4: Int32,
+    ):
+        chunks_per_row = Int32(self.tile_k // 32)
+        local_n = local_int4 // chunks_per_row
+        local_k_vec = local_int4 - local_n * chunks_per_row
+        logical_n = output_n_tile * Int32(self.tile_n) + local_n
+        source_n = self._source_n_from_logical(logical_n)
+        packed_cols = Int32(self.size_k // 2)
+        tile_byte = tile_idx * Int32(self.tile_k // 2) + local_k_vec * Int32(16)
+        byte_offset = (
+            Int64(expert_idx) * Int64(self.size_n * (self.size_k // 2))
+            + Int64(source_n) * Int64(packed_cols)
+            + Int64(tile_byte)
+        )
+        if cutlass.const_expr(self.has_logical_tail):
+            valid_n = logical_n < Int32(self.size_n)
+            valid_bytes = packed_cols - tile_byte
+            if valid_bytes > Int32(16):
+                valid_bytes = Int32(16)
+            if valid_n and valid_bytes >= Int32(16) and cutlass.const_expr(
+                not self.has_scale_k_tail
+            ):
+                cp_async4_shared_global(
+                    smem_addr,
+                    get_ptr_as_int64(b_u8_flat, byte_offset),
+                )
+            else:
+                v0 = Uint32(0)
+                v1 = Uint32(0)
+                v2 = Uint32(0)
+                v3 = Uint32(0)
+                if valid_n and valid_bytes > Int32(0):
+                    src = get_ptr_as_int64(b_u8_flat, byte_offset)
+                    if valid_bytes >= Int32(4):
+                        v0 = ld_global_nc_u32(src)
+                    if valid_bytes >= Int32(8):
+                        v1 = ld_global_nc_u32(src + Int64(4))
+                    if valid_bytes >= Int32(12):
+                        v2 = ld_global_nc_u32(src + Int64(8))
+                    if valid_bytes >= Int32(16):
+                        v3 = ld_global_nc_u32(src + Int64(12))
+                st_shared_v4_u32(smem_addr, v0, v1, v2, v3)
+        else:
+            cp_async4_shared_global(
+                smem_addr,
+                get_ptr_as_int64(b_u8_flat, byte_offset),
+            )
+
+    @cute.jit
+    def _load_modelopt_shared_byte(
+        self,
+        smem_base: Int32,
+        pipe: Int32,
+        n_tile: Int32,
+        k_tile: Int32,
+        warp_id: Int32,
+        tc_col: Int32,
+        tc_row: Int32,
+        n_delta: cutlass.Constexpr[int],
+        k_delta: cutlass.Constexpr[int],
+    ) -> Uint32:
+        local_n = (
+            n_tile * Int32(64)
+            + warp_id * Int32(16)
+            + tc_col
+            + Int32(n_delta)
+        )
+        local_k = k_tile * Int32(16) + tc_row + Int32(k_delta)
+        byte_offset = local_n * Int32(self.tile_k // 2) + local_k // Int32(2)
+        word_byte_offset = byte_offset - (byte_offset & Int32(3))
+        word = ld_shared_u32(
+            smem_base
+            + Int32(self.sh_b_off * 16)
+            + pipe * Int32(self.b_sh_stage * 16)
+            + word_byte_offset
+        )
+        shift = Uint32((byte_offset - word_byte_offset) * Int32(8))
+        return (word >> shift) & Uint32(0xFF)
+
+    @cute.jit
+    def _pack_modelopt_byte_pair(
+        self,
+        word: Uint32,
+        q: Uint32,
+        low_shift: cutlass.Constexpr[int],
+        high_shift: cutlass.Constexpr[int],
+    ) -> Uint32:
+        low = q & Uint32(0xF)
+        high = (q >> Uint32(4)) & Uint32(0xF)
+        return word | (low << Uint32(low_shift)) | (high << Uint32(high_shift))
+
+    @cute.jit
+    def _load_modelopt_shared_packed_word_for_lane(
+        self,
+        smem_base: Int32,
+        pipe: Int32,
+        n_tile: Int32,
+        k_tile: Int32,
+        warp_id: Int32,
+        tc_col: Int32,
+        tc_row: Int32,
+    ) -> Uint32:
+        q0 = self._load_modelopt_shared_byte(
+            smem_base, pipe, n_tile, k_tile, warp_id, tc_col, tc_row, 0, 0
+        )
+        q1 = self._load_modelopt_shared_byte(
+            smem_base, pipe, n_tile, k_tile, warp_id, tc_col, tc_row, 0, 8
+        )
+        q2 = self._load_modelopt_shared_byte(
+            smem_base, pipe, n_tile, k_tile, warp_id, tc_col, tc_row, 8, 0
+        )
+        q3 = self._load_modelopt_shared_byte(
+            smem_base, pipe, n_tile, k_tile, warp_id, tc_col, tc_row, 8, 8
+        )
+        word = Uint32(0)
+        word = self._pack_modelopt_byte_pair(word, q0, 0, 16)
+        word = self._pack_modelopt_byte_pair(word, q1, 4, 20)
+        word = self._pack_modelopt_byte_pair(word, q2, 8, 24)
+        word = self._pack_modelopt_byte_pair(word, q3, 12, 28)
+        return word
+
+    @cute.jit
+    def _load_b_registers_modelopt_shared(
+        self,
+        smem_base: Int32,
+        b_sh_rd: Int32,
+        pipe: Int32,
+        kk: Int32,
+    ):
+        packed_word_index = (Int32(self.b_sh_stride) * kk + b_sh_rd) * Int32(4)
+        words_per_k_tile = Int32((self.tile_n // 64) * 128)
+        k_tile = packed_word_index // words_per_k_tile
+        pos_in_k_tile = packed_word_index - k_tile * words_per_k_tile
+        n_tile = pos_in_k_tile // Int32(128)
+        pos = pos_in_k_tile - n_tile * Int32(128)
+        th_id = pos // Int32(4)
+        tc_col = th_id // Int32(4)
+        tc_row = (th_id - tc_col * Int32(4)) * Int32(2)
+        q0 = self._load_modelopt_shared_packed_word_for_lane(
+            smem_base, pipe, n_tile, k_tile, Int32(0), tc_col, tc_row
+        )
+        q1 = self._load_modelopt_shared_packed_word_for_lane(
+            smem_base, pipe, n_tile, k_tile, Int32(1), tc_col, tc_row
+        )
+        q2 = self._load_modelopt_shared_packed_word_for_lane(
+            smem_base, pipe, n_tile, k_tile, Int32(2), tc_col, tc_row
+        )
+        q3 = self._load_modelopt_shared_packed_word_for_lane(
+            smem_base, pipe, n_tile, k_tile, Int32(3), tc_col, tc_row
+        )
+        return q0, q1, q2, q3
+
+    @cute.jit
+    def _stage_k_tile_async(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        pipe: Int32,
+        tile_idx: Int32,
+        block_valid_rows: Int32,
+        a_gl_stride: Int32,
+        b_gl_stride: Int32,
+        s_gl_stride: Int32,
+        scales_expert_off: Int32,
+        b_gl_rd_base: Int32,
+        a_gl_rd_row: Int32,
+        a_gl_rd_col0: Int32,
+        a_sh_wr: Int32,
+        a_rows_per_iter: Int32,
+        output_n_tile: Int32,
+        expert_idx: Int32,
+    ):
+        for i in cutlass.range_constexpr(self.a_sh_wr_iters):
+            row = a_rows_per_iter * Int32(i) + a_gl_rd_row
+            route_index = Int32(0)
+            if row < Int32(self.moe_block_size):
+                route_index = ld_shared_i32_relaxed(
+                    smem_base + Int32(self.sh_rd_route_off * 16) + row * Int32(4)
+                )
+            a_int4 = (
+                route_index * a_gl_stride
+                + tile_idx * Int32(self.a_gl_rd_delta_o)
+                + a_gl_rd_col0
+            )
+            a_dst = self._int4_addr(
+                smem_base,
+                Int32(self.sh_a_off)
+                + pipe * Int32(self.a_sh_stage)
+                + self._activation_smem_permuted_offset(
+                    Int32(i * self.a_sh_wr_delta) + a_sh_wr
+                ),
+            )
+            if cutlass.const_expr(self.has_k_tile_tail):
+                a_k_int4 = tile_idx * Int32(self.a_gl_rd_delta_o) + a_gl_rd_col0
+                if row < block_valid_rows and a_k_int4 < a_gl_stride:
+                    cp_async4_shared_global(
+                        a_dst,
+                        get_ptr_as_int64(a_bf16_flat, a_int4 * Int32(8)),
+                    )
+                else:
+                    st_shared_v4_u32(
+                        a_dst, Uint32(0), Uint32(0), Uint32(0), Uint32(0)
+                    )
+            else:
+                cp_async4_shared_global_pred(
+                    a_dst,
+                    get_ptr_as_int64(a_bf16_flat, a_int4 * Int32(8)),
+                    (row < block_valid_rows).to(Int32),
+                )
+
+        if cutlass.const_expr(self.weight_layout_nf3):
+            # NF3 flat-span staging: the packer lays the per-(expert,
+            # output_n_tile, k-stage) B block out as ONE contiguous 12-byte-triple
+            # span (n_tile-major, then K16-row, then N-pair), so we copy it
+            # verbatim as 16-byte cp.async chunks. SMEM byte X of the pipe's B
+            # region == global byte X of the span, so the register read (unit*12)
+            # indexes it directly. b_gl_rd_base is unused on this path.
+            nf3_units_per_expert = (self.size_n * self.size_k) // 32
+            nf3_ntile_stride = (self.size_k // 16) * (self.tile_n // 2)
+            nf3_span_base_unit = (
+                Int32(nf3_units_per_expert) * expert_idx
+                + Int32(nf3_ntile_stride) * output_n_tile
+                + tile_idx * Int32(self.cta_k_blocks * self.b_sh_stride)
+            )
+            for i in cutlass.range_constexpr(self.b_sh_wr_iters_nf3):
+                nf3_chunk = Int32(i * self.cta_threads) + tid
+                b_dst = (
+                    smem_base
+                    + Int32(self.sh_b_off * 16)
+                    + pipe * Int32(self.b_sh_stage_bytes)
+                    + nf3_chunk * Int32(16)
+                )
+                # int32-element index of the chunk's first word:
+                # (span_base_unit*12 + chunk*16) / 4 = span_base_unit*3 + chunk*4.
+                b_src_i32 = nf3_span_base_unit * Int32(3) + nf3_chunk * Int32(4)
+                cp_async4_shared_global_pred(
+                    b_dst,
+                    get_ptr_as_int64(b_i32_flat, b_src_i32),
+                    (nf3_chunk < Int32(self.b_sh_chunks)).to(Int32),
+                )
+
+        for i in cutlass.range_constexpr(
+            0 if self.weight_layout_nf3 else self.b_sh_wr_iters
+        ):
+            b_src_int4 = (
+                b_gl_rd_base
+                + tile_idx * Int32(self.cta_k_blocks) * b_gl_stride
+                + Int32(i * (self.cta_threads // self.b_sh_stride)) * b_gl_stride
+            )
+            b_dst = self._int4_addr(
+                smem_base,
+                Int32(self.sh_b_off)
+                + pipe * Int32(self.b_sh_stage)
+                + Int32(i * self.cta_threads)
+                + tid,
+            )
+            if cutlass.const_expr(self.weight_layout == "packed"):
+                cp_async4_shared_global(
+                    b_dst,
+                    get_ptr_as_int64(b_i32_flat, b_src_int4 * Int32(4)),
+                )
+            else:
+                self._stage_b_tile_modelopt_native(
+                    b_i32_flat,
+                    b_dst,
+                    expert_idx,
+                    output_n_tile,
+                    tile_idx,
+                    Int32(i * self.cta_threads) + tid,
+                )
+
+        if tid < Int32(self.s_sh_stage):
+            s_k_group = tile_idx * Int32(self.s_tb_groups) + tid // Int32(
+                self.s_sh_stride
+            )
+            s_n_group = Int32(self.s_sh_stride) * output_n_tile + (
+                tid % Int32(self.s_sh_stride)
+            )
+            s_src_int4 = scales_expert_off + s_gl_stride * s_k_group + s_n_group
+            s_dst = self._int4_addr(
+                smem_base,
+                Int32(self.sh_s_off) + pipe * Int32(self.s_sh_stage) + tid,
+            )
+            if cutlass.const_expr(self.has_logical_tail):
+                if s_k_group < Int32(self.scale_k_groups) and s_n_group < Int32(
+                    self.scale_n_groups
+                ):
+                    cp_async4_shared_global(
+                        s_dst,
+                        get_ptr_as_int64(scales_i32_flat, s_src_int4 * Int32(4)),
+                    )
+                else:
+                    st_shared_v4_u32(
+                        s_dst, Uint32(0), Uint32(0), Uint32(0), Uint32(0)
+                    )
+            else:
+                cp_async4_shared_global(
+                    s_dst,
+                    get_ptr_as_int64(scales_i32_flat, s_src_int4 * Int32(4)),
+                )
+
+        cute.arch.cp_async_commit_group()
+
+    @cute.jit
+    def _prefetch_pipeline_step(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        pipe: cutlass.Constexpr[int],
+        kk: cutlass.Constexpr[int],
+        tile_idx: Int32,
+        k_tiles: Int32,
+        reduce_k_tile: Int32,
+        block_valid_rows: Int32,
+        a_gl_stride: Int32,
+        b_gl_stride: Int32,
+        s_gl_stride: Int32,
+        scales_expert_off: Int32,
+        b_gl_rd_base: Int32,
+        a_gl_rd_row: Int32,
+        a_gl_rd_col0: Int32,
+        a_sh_wr: Int32,
+        a_rows_per_iter: Int32,
+        output_n_tile: Int32,
+        expert_idx: Int32,
+    ):
+        if cutlass.const_expr(kk == self.b_sh_wr_iters - 2):
+            self._prefetch_lookahead_tile(
+                a_bf16_flat,
+                b_i32_flat,
+                scales_i32_flat,
+                smem_base,
+                tid,
+                pipe,
+                tile_idx,
+                k_tiles,
+                reduce_k_tile,
+                block_valid_rows,
+                a_gl_stride,
+                b_gl_stride,
+                s_gl_stride,
+                scales_expert_off,
+                b_gl_rd_base,
+                a_gl_rd_row,
+                a_gl_rd_col0,
+                a_sh_wr,
+                a_rows_per_iter,
+                output_n_tile,
+                expert_idx,
+            )
+
+    @cute.jit
+    def _prefetch_initial_tiles(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        k_tiles: Int32,
+        reduce_k_tile: Int32,
+        block_valid_rows: Int32,
+        a_gl_stride: Int32,
+        b_gl_stride: Int32,
+        s_gl_stride: Int32,
+        scales_expert_off: Int32,
+        b_gl_rd_base: Int32,
+        a_gl_rd_row: Int32,
+        a_gl_rd_col0: Int32,
+        a_sh_wr: Int32,
+        a_rows_per_iter: Int32,
+        output_n_tile: Int32,
+        expert_idx: Int32,
+    ):
+        for pipe in cutlass.range_constexpr(_STAGES - 1):
+            if Int32(pipe) < k_tiles:
+                self._stage_k_tile_async(
+                    a_bf16_flat,
+                    b_i32_flat,
+                    scales_i32_flat,
+                    smem_base,
+                    tid,
+                    Int32(pipe),
+                    reduce_k_tile + Int32(pipe),
+                    block_valid_rows,
+                    a_gl_stride,
+                    b_gl_stride,
+                    s_gl_stride,
+                    scales_expert_off,
+                    b_gl_rd_base,
+                    a_gl_rd_row,
+                    a_gl_rd_col0,
+                    a_sh_wr,
+                    a_rows_per_iter,
+                    output_n_tile,
+                    expert_idx,
+                )
+            else:
+                cute.arch.cp_async_commit_group()
+        cute.arch.cp_async_wait_group(_STAGES - 2)
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _prefetch_lookahead_tile(
+        self,
+        a_bf16_flat: cute.Tensor,
+        b_i32_flat: cute.Tensor,
+        scales_i32_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        pipe: cutlass.Constexpr[int],
+        tile_idx: Int32,
+        k_tiles: Int32,
+        reduce_k_tile: Int32,
+        block_valid_rows: Int32,
+        a_gl_stride: Int32,
+        b_gl_stride: Int32,
+        s_gl_stride: Int32,
+        scales_expert_off: Int32,
+        b_gl_rd_base: Int32,
+        a_gl_rd_row: Int32,
+        a_gl_rd_col0: Int32,
+        a_sh_wr: Int32,
+        a_rows_per_iter: Int32,
+        output_n_tile: Int32,
+        expert_idx: Int32,
+    ):
+        fetch_tile = tile_idx + Int32(_STAGES - 1)
+        if fetch_tile < k_tiles:
+            self._stage_k_tile_async(
+                a_bf16_flat,
+                b_i32_flat,
+                scales_i32_flat,
+                smem_base,
+                tid,
+                Int32((pipe + _STAGES - 1) % _STAGES),
+                reduce_k_tile + fetch_tile,
+                block_valid_rows,
+                a_gl_stride,
+                b_gl_stride,
+                s_gl_stride,
+                scales_expert_off,
+                b_gl_rd_base,
+                a_gl_rd_row,
+                a_gl_rd_col0,
+                a_sh_wr,
+                a_rows_per_iter,
+                output_n_tile,
+                expert_idx,
+            )
+        else:
+            cute.arch.cp_async_commit_group()
+        cute.arch.cp_async_wait_group(_STAGES - 2)
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _reduction_offsets(self, tid: Int32):
+        red_idx = tid // Int32(self.b_sh_stride_threads)
+        red_sh_stride = Int32(self.b_sh_stride_threads * 4 * 2)
+        red_sh_delta = Int32(self.b_sh_stride_threads)
+        red_sh_rd = red_sh_stride * (tid // Int32(self.b_sh_stride_threads)) + (
+            tid % Int32(self.b_sh_stride_threads)
+        )
+        return red_idx, red_sh_stride, red_sh_delta, red_sh_rd
+
+    @cute.jit
+    def _fold_cta_partials_m8(self, acc: cute.Tensor, smem_base: Int32, tid: Int32):
+        red_off = self.cta_threads // self.b_sh_stride_threads // 2
+        if cutlass.const_expr(red_off >= 1):
+            red_idx, red_sh_stride, red_sh_delta, red_sh_rd = self._reduction_offsets(
+                tid
+            )
+            if cutlass.const_expr(red_off == 2):
+                if Int32(2) <= red_idx and red_idx < Int32(4):
+                    for jj in cutlass.range_constexpr(4):
+                        red_sh_wr = red_sh_delta * Int32(jj * 2) + (
+                            red_sh_rd - red_sh_stride * Int32(2)
+                        )
+                        st_shared_v4_f32(
+                            self._int4_addr(
+                                smem_base, Int32(self.sh_red_off) + red_sh_wr
+                            ),
+                            acc[jj, 0],
+                            acc[jj, 1],
+                            acc[jj, 2],
+                            acc[jj, 3],
+                        )
+                cute.arch.sync_threads()
+
+            if Int32(1) <= red_idx and red_idx < Int32(2):
+                for jj in cutlass.range_constexpr(4):
+                    red_sh_wr = red_sh_delta * Int32(jj * 2) + (
+                        red_sh_rd - red_sh_stride
+                    )
+                    if cutlass.const_expr(red_off > 1):
+                        rd_addr = self._int4_addr(
+                            smem_base,
+                            Int32(self.sh_red_off)
+                            + red_sh_delta * Int32(jj * 2)
+                            + red_sh_rd,
+                        )
+                        wr_addr = self._int4_addr(
+                            smem_base, Int32(self.sh_red_off) + red_sh_wr
+                        )
+                        r0, r1, r2, r3 = ld_shared_v4_f32(rd_addr)
+                        w0, w1, w2, w3 = ld_shared_v4_f32(wr_addr)
+                        acc[jj, 0] = acc[jj, 0] + r0 + w0
+                        acc[jj, 1] = acc[jj, 1] + r1 + w1
+                        acc[jj, 2] = acc[jj, 2] + r2 + w2
+                        acc[jj, 3] = acc[jj, 3] + r3 + w3
+                    st_shared_v4_f32(
+                        self._int4_addr(smem_base, Int32(self.sh_red_off) + red_sh_wr),
+                        acc[jj, 0],
+                        acc[jj, 1],
+                        acc[jj, 2],
+                        acc[jj, 3],
+                    )
+            cute.arch.sync_threads()
+
+            if red_idx == Int32(0):
+                for jj in cutlass.range_constexpr(4):
+                    rd_addr = self._int4_addr(
+                        smem_base,
+                        Int32(self.sh_red_off)
+                        + red_sh_delta * Int32(jj * 2)
+                        + red_sh_rd,
+                    )
+                    r0, r1, r2, r3 = ld_shared_v4_f32(rd_addr)
+                    acc[jj, 0] = acc[jj, 0] + r0
+                    acc[jj, 1] = acc[jj, 1] + r1
+                    acc[jj, 2] = acc[jj, 2] + r2
+                    acc[jj, 3] = acc[jj, 3] + r3
+            cute.arch.sync_threads()
+
+    @cute.jit
+    def _output_store_cursor(self, tid: Int32, output_n_tile: Int32):
+        c_gl_stride = Int32(self.size_n // 8)
+        c_sh_stride = Int32(2 * self.cta_n_blocks + 1)
+        c_gl_wr_delta = c_gl_stride * Int32(self.cta_threads // (2 * self.cta_n_blocks))
+        c_sh_rd_delta = c_sh_stride * Int32(
+            self.cta_threads // (2 * self.cta_n_blocks)
+        )
+        c_gl_wr = (
+            c_gl_stride * (tid // Int32(2 * self.cta_n_blocks))
+            + (tid % Int32(2 * self.cta_n_blocks))
+            + Int32(2 * self.cta_n_blocks) * output_n_tile
+        )
+        c_sh_rd = c_sh_stride * (tid // Int32(2 * self.cta_n_blocks)) + (
+            tid % Int32(2 * self.cta_n_blocks)
+        )
+        return c_gl_stride, c_sh_stride, c_gl_wr_delta, c_sh_rd_delta, c_gl_wr, c_sh_rd
+
+    @cute.jit
+    def _output_store_cursor_tail(self, tid: Int32, output_n_tile: Int32):
+        c_gl_stride = Int32(self.size_n // 8)
+        c_gl_stride_covered = Int32(self.covered_size_n // 8)
+        c_sh_stride = Int32(2 * self.cta_n_blocks + 1)
+        c_gl_wr_delta = c_gl_stride_covered * Int32(
+            self.cta_threads // (2 * self.cta_n_blocks)
+        )
+        c_sh_rd_delta = c_sh_stride * Int32(self.cta_threads // (2 * self.cta_n_blocks))
+        c_gl_wr = (
+            c_gl_stride_covered * (tid // Int32(2 * self.cta_n_blocks))
+            + (tid % Int32(2 * self.cta_n_blocks))
+            + Int32(2 * self.cta_n_blocks) * output_n_tile
+        )
+        c_sh_rd = c_sh_stride * (tid // Int32(2 * self.cta_n_blocks)) + (
+            tid % Int32(2 * self.cta_n_blocks)
+        )
+        return (
+            c_gl_stride,
+            c_gl_stride_covered,
+            c_sh_stride,
+            c_gl_wr_delta,
+            c_sh_rd_delta,
+            c_gl_wr,
+            c_sh_rd,
+        )
+
+    @cute.jit
+    def _drain_output_smem(
+        self,
+        c_bf16_flat: cute.Tensor,
+        smem_base: Int32,
+        c_gl_stride: Int32,
+        c_gl_wr: Int32,
+        c_gl_wr_delta: Int32,
+        c_sh_rd: Int32,
+        c_sh_rd_delta: Int32,
+        block_valid_rows: Int32,
+        store_iters: cutlass.Constexpr[int],
+    ):
+        for _ in cutlass.range_constexpr(store_iters):
+            row = c_gl_wr // c_gl_stride
+            if row < block_valid_rows:
+                route_index = ld_shared_i32_relaxed(
+                    smem_base + Int32(self.sh_route_off * 16) + row * Int32(4)
+                )
+                true_idx = route_index * c_gl_stride + (c_gl_wr % c_gl_stride)
+                q0, q1, q2, q3 = ld_shared_v4_u32(
+                    self._int4_addr(smem_base, Int32(self.sh_red_off) + c_sh_rd)
+                )
+                if cutlass.const_expr(self.mul_topk_weights):
+                    scale_bf2 = ld_shared_u32(
+                        smem_base + Int32(self.sh_topk_off * 16) + row * Int32(4)
+                    )
+                    q0 = self._elem2_mul(q0, scale_bf2)
+                    q1 = self._elem2_mul(q1, scale_bf2)
+                    q2 = self._elem2_mul(q2, scale_bf2)
+                    q3 = self._elem2_mul(q3, scale_bf2)
+                if cutlass.const_expr(self.epilogue_relu2):
+                    q0 = self._relu2_elem2(q0)
+                    q1 = self._relu2_elem2(q1)
+                    q2 = self._relu2_elem2(q2)
+                    q3 = self._relu2_elem2(q3)
+                if cutlass.const_expr(self.fused_topk_sum):
+                    # Fold the per-route partials into the per-token output in
+                    # the epilogue (drops the separate top-k-sum launch). The
+                    # output must be zeroed before launch; each route slot maps
+                    # to token = route_index // top_k.  bf16x2 add lands two
+                    # consecutive hidden lanes per word.
+                    token_idx = route_index // Int32(self.fused_sum_topk)
+                    out_idx = token_idx * c_gl_stride + (c_gl_wr % c_gl_stride)
+                    out_addr = get_ptr_as_int64(c_bf16_flat, out_idx * Int32(8))
+                    red_add_global_bf16x2(out_addr, q0)
+                    red_add_global_bf16x2(out_addr + Int64(4), q1)
+                    red_add_global_bf16x2(out_addr + Int64(8), q2)
+                    red_add_global_bf16x2(out_addr + Int64(12), q3)
+                else:
+                    st_global_v4_u32(
+                        get_ptr_as_int64(c_bf16_flat, true_idx * Int32(8)),
+                        q0,
+                        q1,
+                        q2,
+                        q3,
+                    )
+            c_gl_wr += c_gl_wr_delta
+            c_sh_rd += c_sh_rd_delta
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _drain_output_smem_tail(
+        self,
+        c_bf16_flat: cute.Tensor,
+        smem_base: Int32,
+        c_gl_stride: Int32,
+        c_gl_stride_covered: Int32,
+        c_gl_wr: Int32,
+        c_gl_wr_delta: Int32,
+        c_sh_rd: Int32,
+        c_sh_rd_delta: Int32,
+        block_valid_rows: Int32,
+        store_iters: cutlass.Constexpr[int],
+    ):
+        for _ in cutlass.range_constexpr(store_iters):
+            row = c_gl_wr // c_gl_stride_covered
+            col_word = c_gl_wr - row * c_gl_stride_covered
+            if row < block_valid_rows and col_word < c_gl_stride:
+                route_index = ld_shared_i32_relaxed(
+                    smem_base + Int32(self.sh_route_off * 16) + row * Int32(4)
+                )
+                true_idx = route_index * c_gl_stride + col_word
+                q0, q1, q2, q3 = ld_shared_v4_u32(
+                    self._int4_addr(smem_base, Int32(self.sh_red_off) + c_sh_rd)
+                )
+                if cutlass.const_expr(self.mul_topk_weights):
+                    scale_bf2 = ld_shared_u32(
+                        smem_base + Int32(self.sh_topk_off * 16) + row * Int32(4)
+                    )
+                    q0 = self._elem2_mul(q0, scale_bf2)
+                    q1 = self._elem2_mul(q1, scale_bf2)
+                    q2 = self._elem2_mul(q2, scale_bf2)
+                    q3 = self._elem2_mul(q3, scale_bf2)
+                if cutlass.const_expr(self.epilogue_relu2):
+                    q0 = self._relu2_elem2(q0)
+                    q1 = self._relu2_elem2(q1)
+                    q2 = self._relu2_elem2(q2)
+                    q3 = self._relu2_elem2(q3)
+                if cutlass.const_expr(self.fused_topk_sum):
+                    token_idx = route_index // Int32(self.fused_sum_topk)
+                    out_idx = token_idx * c_gl_stride + col_word
+                    out_addr = get_ptr_as_int64(c_bf16_flat, out_idx * Int32(8))
+                    red_add_global_bf16x2(out_addr, q0)
+                    red_add_global_bf16x2(out_addr + Int64(4), q1)
+                    red_add_global_bf16x2(out_addr + Int64(8), q2)
+                    red_add_global_bf16x2(out_addr + Int64(12), q3)
+                else:
+                    st_global_v4_u32(
+                        get_ptr_as_int64(c_bf16_flat, true_idx * Int32(8)),
+                        q0,
+                        q1,
+                        q2,
+                        q3,
+                    )
+            c_gl_wr += c_gl_wr_delta
+            c_sh_rd += c_sh_rd_delta
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _store_tile_m8(
+        self,
+        acc: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        output_n_tile: Int32,
+        block_valid_rows: Int32,
+        global_scale_f32: cutlass.Float32,
+    ):
+        if cutlass.const_expr(self.has_n_tile_tail):
+            (
+                c_gl_stride,
+                c_gl_stride_covered,
+                c_sh_stride,
+                c_gl_wr_delta,
+                c_sh_rd_delta,
+                c_gl_wr,
+                c_sh_rd,
+            ) = self._output_store_cursor_tail(tid, output_n_tile)
+        else:
+            (
+                c_gl_stride,
+                c_sh_stride,
+                c_gl_wr_delta,
+                c_sh_rd_delta,
+                c_gl_wr,
+                c_sh_rd,
+            ) = self._output_store_cursor(tid, output_n_tile)
+            c_gl_stride_covered = c_gl_stride
+        c_sh_wr = (
+            Int32(8) * c_sh_stride * (((tid & Int32(31)) % Int32(4)) * Int32(2))
+            + (tid & Int32(31)) // Int32(4)
+            + Int32(64) * (tid // Int32(32))
+        )
+
+        if tid // Int32(32) < Int32(self.tb_n_warps):
+            write_scale = cutlass.Float32(1.0)
+            if cutlass.const_expr(not self.mul_topk_weights):
+                write_scale = global_scale_f32
+            for jj in cutlass.range_constexpr(4):
+                wr = c_sh_wr + Int32(16 * jj)
+                self._st_shared_elem_from_f32(
+                    smem_base + Int32(self.sh_red_off * 16) + (wr * Int32(2)),
+                    acc[jj, 0] * write_scale,
+                )
+                self._st_shared_elem_from_f32(
+                    smem_base
+                    + Int32(self.sh_red_off * 16)
+                    + ((wr + Int32(8) * c_sh_stride) * Int32(2)),
+                    acc[jj, 1] * write_scale,
+                )
+                self._st_shared_elem_from_f32(
+                    smem_base
+                    + Int32(self.sh_red_off * 16)
+                    + ((wr + Int32(8)) * Int32(2)),
+                    acc[jj, 2] * write_scale,
+                )
+                self._st_shared_elem_from_f32(
+                    smem_base
+                    + Int32(self.sh_red_off * 16)
+                    + ((wr + Int32(8) + Int32(8) * c_sh_stride) * Int32(2)),
+                    acc[jj, 3] * write_scale,
+                )
+        cute.arch.sync_threads()
+
+        store_iters = _covering_count(
+            16, self.cta_threads // (2 * self.cta_n_blocks)
+        )
+        if cutlass.const_expr(self.has_n_tile_tail):
+            self._drain_output_smem_tail(
+                c_bf16_flat,
+                smem_base,
+                c_gl_stride,
+                c_gl_stride_covered,
+                c_gl_wr,
+                c_gl_wr_delta,
+                c_sh_rd,
+                c_sh_rd_delta,
+                block_valid_rows,
+                store_iters,
+            )
+        else:
+            self._drain_output_smem(
+                c_bf16_flat,
+                smem_base,
+                c_gl_stride,
+                c_gl_wr,
+                c_gl_wr_delta,
+                c_sh_rd,
+                c_sh_rd_delta,
+                block_valid_rows,
+                store_iters,
+            )
+
+    @cute.jit
+    def _fold_cta_partials_large_m(
+        self, acc: cute.Tensor, smem_base: Int32, tid: Int32
+    ):
+        red_off = self.cta_threads // self.b_sh_stride_threads // 2
+        if cutlass.const_expr(red_off >= 1):
+            red_idx, red_sh_stride, red_sh_delta, red_sh_rd = self._reduction_offsets(
+                tid
+            )
+
+            for mb in cutlass.range_constexpr(self.cta_m_blocks):
+                if cutlass.const_expr(red_off == 2):
+                    if Int32(2) <= red_idx and red_idx < Int32(4):
+                        for flat_j in cutlass.range_constexpr(8):
+                            jj = flat_j // 2
+                            half = flat_j % 2
+                            red_sh_wr = red_sh_delta * Int32(flat_j) + (
+                                red_sh_rd - red_sh_stride * Int32(2)
+                            )
+                            st_shared_v4_f32(
+                                self._int4_addr(
+                                    smem_base, Int32(self.sh_red_off) + red_sh_wr
+                                ),
+                                acc[mb, jj, half, 0],
+                                acc[mb, jj, half, 1],
+                                acc[mb, jj, half, 2],
+                                acc[mb, jj, half, 3],
+                            )
+                    cute.arch.sync_threads()
+
+                if Int32(1) <= red_idx and red_idx < Int32(2):
+                    for flat_j in cutlass.range_constexpr(8):
+                        jj = flat_j // 2
+                        half = flat_j % 2
+                        red_sh_wr = red_sh_delta * Int32(flat_j) + (
+                            red_sh_rd - red_sh_stride
+                        )
+                        if cutlass.const_expr(red_off > 1):
+                            rd_addr = self._int4_addr(
+                                smem_base,
+                                Int32(self.sh_red_off)
+                                + red_sh_delta * Int32(flat_j)
+                                + red_sh_rd,
+                            )
+                            wr_addr = self._int4_addr(
+                                smem_base,
+                                Int32(self.sh_red_off) + red_sh_wr,
+                            )
+                            r0, r1, r2, r3 = ld_shared_v4_f32(rd_addr)
+                            w0, w1, w2, w3 = ld_shared_v4_f32(wr_addr)
+                            acc[mb, jj, half, 0] = acc[mb, jj, half, 0] + r0 + w0
+                            acc[mb, jj, half, 1] = acc[mb, jj, half, 1] + r1 + w1
+                            acc[mb, jj, half, 2] = acc[mb, jj, half, 2] + r2 + w2
+                            acc[mb, jj, half, 3] = acc[mb, jj, half, 3] + r3 + w3
+                        st_shared_v4_f32(
+                            self._int4_addr(
+                                smem_base, Int32(self.sh_red_off) + red_sh_wr
+                            ),
+                            acc[mb, jj, half, 0],
+                            acc[mb, jj, half, 1],
+                            acc[mb, jj, half, 2],
+                            acc[mb, jj, half, 3],
+                        )
+                cute.arch.sync_threads()
+
+                if red_idx == Int32(0):
+                    for flat_j in cutlass.range_constexpr(8):
+                        jj = flat_j // 2
+                        half = flat_j % 2
+                        rd_addr = self._int4_addr(
+                            smem_base,
+                            Int32(self.sh_red_off)
+                            + red_sh_delta * Int32(flat_j)
+                            + red_sh_rd,
+                        )
+                        r0, r1, r2, r3 = ld_shared_v4_f32(rd_addr)
+                        acc[mb, jj, half, 0] = acc[mb, jj, half, 0] + r0
+                        acc[mb, jj, half, 1] = acc[mb, jj, half, 1] + r1
+                        acc[mb, jj, half, 2] = acc[mb, jj, half, 2] + r2
+                        acc[mb, jj, half, 3] = acc[mb, jj, half, 3] + r3
+                cute.arch.sync_threads()
+
+    @cute.jit
+    def _write_bf16x2_shared(
+        self,
+        smem_base: Int32,
+        half2_idx: Int32,
+        c0: cutlass.Float32,
+        c1: cutlass.Float32,
+        write_scale: cutlass.Float32,
+    ):
+        packed = self._pack_f32x2_to_elem2(c0 * write_scale, c1 * write_scale)
+        st_shared_u32(
+            smem_base + Int32(self.sh_red_off * 16) + half2_idx * Int32(4),
+            packed,
+        )
+
+    @cute.jit
+    def _store_tile_large_m(
+        self,
+        acc: cute.Tensor,
+        c_bf16_flat: cute.Tensor,
+        smem_base: Int32,
+        tid: Int32,
+        output_n_tile: Int32,
+        block_valid_rows: Int32,
+        global_scale_f32: cutlass.Float32,
+    ):
+        if cutlass.const_expr(self.has_n_tile_tail):
+            (
+                c_gl_stride,
+                c_gl_stride_covered,
+                c_sh_stride,
+                c_gl_wr_delta,
+                c_sh_rd_delta,
+                c_gl_wr,
+                c_sh_rd,
+            ) = self._output_store_cursor_tail(tid, output_n_tile)
+        else:
+            (
+                c_gl_stride,
+                c_sh_stride,
+                c_gl_wr_delta,
+                c_sh_rd_delta,
+                c_gl_wr,
+                c_sh_rd,
+            ) = self._output_store_cursor(tid, output_n_tile)
+            c_gl_stride_covered = c_gl_stride
+        c_sh_wr = (
+            Int32(4) * c_sh_stride * ((tid & Int32(31)) // Int32(4))
+            + (tid & Int32(31)) % Int32(4)
+            + Int32(32) * (tid // Int32(32))
+        )
+
+        if tid // Int32(32) < Int32(self.tb_n_warps):
+            write_scale = cutlass.Float32(1.0)
+            if cutlass.const_expr(not self.mul_topk_weights):
+                write_scale = global_scale_f32
+            for mb in cutlass.range_constexpr(self.cta_m_blocks):
+                for jj in cutlass.range_constexpr(4):
+                    wr = c_sh_wr + Int32(8 * jj)
+                    self._write_bf16x2_shared(
+                        smem_base,
+                        wr,
+                        acc[mb, jj, 0, 0],
+                        acc[mb, jj, 0, 1],
+                        write_scale,
+                    )
+                    self._write_bf16x2_shared(
+                        smem_base,
+                        wr + (Int32(4) * c_sh_stride) * Int32(8) + Int32(0),
+                        acc[mb, jj, 0, 2],
+                        acc[mb, jj, 0, 3],
+                        write_scale,
+                    )
+                    self._write_bf16x2_shared(
+                        smem_base,
+                        wr + Int32(4),
+                        acc[mb, jj, 1, 0],
+                        acc[mb, jj, 1, 1],
+                        write_scale,
+                    )
+                    self._write_bf16x2_shared(
+                        smem_base,
+                        wr + (Int32(4) * c_sh_stride) * Int32(8) + Int32(4),
+                        acc[mb, jj, 1, 2],
+                        acc[mb, jj, 1, 3],
+                        write_scale,
+                    )
+                c_sh_wr += Int32(16 * (4 * (2 * self.cta_n_blocks + 1)))
+        cute.arch.sync_threads()
+
+        store_iters = _covering_count(
+            16 * self.cta_m_blocks,
+            self.cta_threads // (2 * self.cta_n_blocks),
+        )
+        if cutlass.const_expr(self.has_n_tile_tail):
+            self._drain_output_smem_tail(
+                c_bf16_flat,
+                smem_base,
+                c_gl_stride,
+                c_gl_stride_covered,
+                c_gl_wr,
+                c_gl_wr_delta,
+                c_sh_rd,
+                c_sh_rd_delta,
+                block_valid_rows,
+                store_iters,
+            )
+        else:
+            self._drain_output_smem(
+                c_bf16_flat,
+                smem_base,
+                c_gl_stride,
+                c_gl_wr,
+                c_gl_wr_delta,
+                c_sh_rd,
+                c_sh_rd_delta,
+                block_valid_rows,
+                store_iters,
+            )
+
+
+class W4A16FusedMoeKernel:
+    def __init__(
+        self,
+        *,
+        size_m: int,
+        hidden_size: int,
+        intermediate_size: int,
+        num_experts: int,
+        top_k: int,
+        activation: str,
+        apply_router_weight_on_input: bool,
+        zero_fc2_output: bool,
+        fc1_tile_n: int,
+        fc1_tile_k: int,
+        fc2_tile_n: int,
+        fc2_tile_k: int,
+        moe_block_size: int,
+        max_m_blocks: int,
+        element_dtype: str = "bf16",
+        fast_math: bool = True,
+        swiglu_limit: float | None = None,
+        swiglu_alpha: float | None = None,
+        swiglu_beta: float | None = None,
+        weight_layout: str = "packed",
+        scale_format: str = "e4m3_k16",
+        w13_layout: str = "w13",
+        direct_topk_routes: bool = False,
+        tc_decode_fused_sum: bool = False,
+        tc_zero_output: bool = True,
+        collect_activation_amax: bool = False,
+    ):
+        activation = normalize_moe_activation(activation)
+        is_gated = validate_activation(activation)
+        swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+            activation,
+            swiglu_limit,
+            swiglu_alpha,
+            swiglu_beta,
+        )
+        if weight_layout not in _WEIGHT_LAYOUTS:
+            raise ValueError(f"unsupported W4A16 weight_layout {weight_layout!r}")
+        scale_format = _normalize_scale_format(scale_format)
+        if weight_layout == "modelopt":
+            if w13_layout not in _MODEL_OPT_W13_LAYOUTS:
+                raise ValueError(f"unsupported W4A16 w13_layout {w13_layout!r}")
+        else:
+            w13_layout = "packed"
+        self.tc_decode_fused_sum = bool(tc_decode_fused_sum)
+        # When two TC-decode launches share one pre-zeroed output (the NF3 hybrid
+        # runs an NVFP4 launch then an NF3 launch into the same tensor), only the
+        # first must zero it. Default True preserves single-launch behavior.
+        self.tc_zero_output = bool(tc_zero_output)
+        self.collect_activation_amax = bool(collect_activation_amax)
+        if self.collect_activation_amax and bool(direct_topk_routes):
+            raise ValueError("activation amax collection requires route-packed W4A16")
+        if self.collect_activation_amax and self.tc_decode_fused_sum:
+            raise ValueError("activation amax collection is incompatible with TC-decode")
+        if self.tc_decode_fused_sum and not bool(direct_topk_routes):
+            raise ValueError("tc_decode_fused_sum requires direct_topk_routes")
+        if self.tc_decode_fused_sum and element_dtype != "bf16":
+            raise ValueError("tc_decode_fused_sum currently requires bf16 activations")
+        fc1_cols = int(intermediate_size) * (2 if is_gated else 1)
+        routed_rows = int(size_m) * int(top_k)
+        self.size_m = int(size_m)
+        self.hidden_size = int(hidden_size)
+        self.intermediate_size = int(intermediate_size)
+        self.fc1_cols = int(fc1_cols)
+        self.num_experts = int(num_experts)
+        self.top_k = int(top_k)
+        self.moe_block_size = int(moe_block_size)
+        self.activation = activation
+        self.activation_is_gated = is_gated
+        self.activation_is_swigluoai = activation == SWIGLUOAI_UNINTERLEAVE
+        self.has_swiglu_limit = swiglu_limit is not None
+        self.swiglu_limit = 0.0 if swiglu_limit is None else swiglu_limit
+        self.swiglu_alpha = float(swiglu_alpha)
+        self.swiglu_beta = float(swiglu_beta)
+        self.weight_layout = weight_layout
+        self.scale_format = scale_format
+        self.w13_layout = w13_layout
+        self.apply_router_weight_on_input = bool(apply_router_weight_on_input)
+        self.zero_fc2_output = bool(zero_fc2_output)
+        self.element_dtype = element_dtype
+        self.is_fp16 = element_dtype == "fp16"
+        self.fast_math = bool(fast_math)
+        self.direct_topk_routes = bool(direct_topk_routes)
+        fc1_source_n_rotation = (
+            int(intermediate_size)
+            if (
+                weight_layout == "modelopt"
+                and w13_layout == "w13"
+                and is_gated
+            )
+            else 0
+        )
+        self.fc1 = W4A16GemmKernel(
+            size_m=size_m,
+            size_n=fc1_cols,
+            size_k=hidden_size,
+            num_experts=num_experts,
+            top_k=top_k,
+            mul_topk_weights=bool(apply_router_weight_on_input),
+            tile_n=fc1_tile_n,
+            tile_k=fc1_tile_k,
+            moe_block_size=moe_block_size,
+            max_m_blocks=max_m_blocks,
+            element_dtype=element_dtype,
+            epilogue_activation=None if is_gated else "relu2",
+            weight_layout=weight_layout,
+            scale_format=scale_format,
+            w13_layout=w13_layout,
+            source_n_rotation=fc1_source_n_rotation,
+            single_token_route_fast_path=size_m == 1
+            and not self.direct_topk_routes,
+            direct_topk_routes=self.direct_topk_routes,
+        )
+        self.fc2 = W4A16GemmKernel(
+            size_m=routed_rows,
+            size_n=hidden_size,
+            size_k=intermediate_size,
+            num_experts=num_experts,
+            top_k=1,
+            mul_topk_weights=not bool(apply_router_weight_on_input),
+            tile_n=fc2_tile_n,
+            tile_k=fc2_tile_k,
+            moe_block_size=moe_block_size,
+            max_m_blocks=max_m_blocks,
+            element_dtype=element_dtype,
+            weight_layout=weight_layout,
+            scale_format=scale_format,
+            w13_layout=w13_layout,
+            single_token_route_fast_path=size_m == 1
+            and not self.direct_topk_routes,
+            direct_topk_routes=self.direct_topk_routes,
+            fused_topk_sum=self.tc_decode_fused_sum,
+            fused_sum_topk=int(top_k),
+        )
+        self.cta_threads = max(self.fc1.cta_threads, self.fc2.cta_threads)
+        if self.fc1.cta_threads != self.fc2.cta_threads:
+            raise ValueError(
+                "fused W4A16 kernel expects matching FC1/FC2 thread counts"
+            )
+        self.sms = self.fc1.sms
+        self.blocks_per_sm = min(self.fc1.blocks_per_sm, self.fc2.blocks_per_sm)
+        self.shared_words = max(self.fc1.shared_words, self.fc2.shared_words)
+        self.barrier_count_off = self.sms * 4
+        self.barrier_sense_off = self.sms * 4 + 1
+
+    @property
+    def __cache_key__(self) -> tuple[object, ...]:
+        return (
+            self.hidden_size,
+            self.intermediate_size,
+            self.fc1_cols,
+            self.num_experts,
+            self.top_k,
+            self.activation,
+            self.activation_is_gated,
+            self.activation_is_swigluoai,
+            self.has_swiglu_limit,
+            self.swiglu_limit,
+            self.swiglu_alpha,
+            self.swiglu_beta,
+            self.weight_layout,
+            self.scale_format,
+            self.apply_router_weight_on_input,
+            self.zero_fc2_output,
+            self.element_dtype,
+            self.fast_math,
+            self.direct_topk_routes,
+            self.tc_zero_output,
+            self.collect_activation_amax,
+            self.fc1.__cache_key__,
+            self.fc2.__cache_key__,
+            self.cta_threads,
+            self.sms,
+            self.shared_words,
+            self.blocks_per_sm,
+        )
+
+    @cute.jit
+    def _cast_elem(self, x: cutlass.Float32):
+        if cutlass.const_expr(self.is_fp16):
+            return cutlass.Float16(x)
+        return cutlass.BFloat16(x)
+
+    @cute.jit
+    def _clamp_swiglu_inputs(
+        self,
+        gate: cutlass.Float32,
+        up: cutlass.Float32,
+    ):
+        if cutlass.const_expr(self.has_swiglu_limit):
+            limit = cutlass.Float32(self.swiglu_limit)
+            neg_limit = cutlass.Float32(-self.swiglu_limit)
+            if gate > limit:
+                gate = limit
+            if up > limit:
+                up = limit
+            if up < neg_limit:
+                up = neg_limit
+        return gate, up
+
+    @cute.jit
+    def __call__(
+        self,
+        a_bf16_ptr: cute.Pointer,
+        w13_i32_flat: cute.Tensor,
+        w2_i32_flat: cute.Tensor,
+        fc1_bf16_flat: cute.Tensor,
+        activated_bf16_flat: cute.Tensor,
+        fc2_bf16_flat: cute.Tensor,
+        w13_scales_i32_flat: cute.Tensor,
+        w2_scales_i32_flat: cute.Tensor,
+        w13_global_scale: cute.Tensor,
+        w2_global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        activation_amax_flat: cute.Tensor,
+        layer_idx: cutlass.Int32,
+        topk_weights_ptr: cute.Pointer,
+        fc1_c_tmp_f32_flat: cute.Tensor,
+        fc2_c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        active_m: cutlass.Int32,
+        grid_x: cutlass.Int32,
+        stream: cuda.CUstream,
+    ):
+        a_bf16_flat = cute.make_tensor(
+            a_bf16_ptr,
+            layout=cute.make_layout(
+                (active_m * Int32(self.hidden_size),), stride=(1,)
+            ),
+        )
+        topk_weights_flat = cute.make_tensor(
+            topk_weights_ptr,
+            layout=cute.make_layout((active_m * Int32(self.top_k),), stride=(1,)),
+        )
+        grid = (grid_x, 1, 1)
+        self.kernel(
+            a_bf16_flat,
+            w13_i32_flat,
+            w2_i32_flat,
+            fc1_bf16_flat,
+            activated_bf16_flat,
+            fc2_bf16_flat,
+            w13_scales_i32_flat,
+            w2_scales_i32_flat,
+            w13_global_scale,
+            w2_global_scale,
+            packed_route_indices,
+            block_expert_ids,
+            packed_route_count,
+            activation_amax_flat,
+            layer_idx,
+            topk_weights_flat,
+            fc1_c_tmp_f32_flat,
+            fc2_c_tmp_f32_flat,
+            locks_i32_flat,
+            active_m,
+        ).launch(
+            grid=grid,
+            block=[self.cta_threads, 1, 1],
+            min_blocks_per_mp=self.blocks_per_sm,
+            stream=stream,
+        )
+
+    @cute.kernel
+    def kernel(
+        self,
+        a_bf16_flat: cute.Tensor,
+        w13_i32_flat: cute.Tensor,
+        w2_i32_flat: cute.Tensor,
+        fc1_bf16_flat: cute.Tensor,
+        activated_bf16_flat: cute.Tensor,
+        fc2_bf16_flat: cute.Tensor,
+        w13_scales_i32_flat: cute.Tensor,
+        w2_scales_i32_flat: cute.Tensor,
+        w13_global_scale: cute.Tensor,
+        w2_global_scale: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        activation_amax_flat: cute.Tensor,
+        layer_idx: cutlass.Int32,
+        topk_weights_flat: cute.Tensor,
+        fc1_c_tmp_f32_flat: cute.Tensor,
+        fc2_c_tmp_f32_flat: cute.Tensor,
+        locks_i32_flat: cute.Tensor,
+        active_m: cutlass.Int32,
+    ):
+        tidx, _, _ = cute.arch.thread_idx()
+        bidx, _, _ = cute.arch.block_idx()
+        grid_x_raw, _, _ = cute.arch.grid_dim()
+        tid = Int32(tidx)
+        cta = Int32(bidx)
+        grid_x = Int32(grid_x_raw)
+
+        smem = cutlass.utils.SmemAllocator()
+
+        @cute.struct
+        class Storage:
+            words: cute.struct.Align[
+                cute.struct.MemRange[cutlass.Uint32, self.shared_words],
+                1024,
+            ]
+
+        storage = smem.allocate(Storage)
+        smem_base = shared_ptr_to_u32(storage.words.data_ptr())
+
+        if cutlass.const_expr(self.tc_decode_fused_sum):
+            # The TC-decode FC2 epilogue atomically accumulates per-route
+            # partials directly into the per-token output, so the output must be
+            # pre-zeroed. Previously this was a SEPARATE host-side output.zero_()
+            # kernel launch on the latency-bound decode critical path (an extra
+            # launch + its grid-fill memset before the fused kernel even starts).
+            # Fold it into the fused kernel prologue here: every CTA zeroes a
+            # grid-strided slice of the output BEFORE FC1, and the EXISTING
+            # post-FC1 grid barrier (already required to order FC1 writes before
+            # the activation/FC2 read) makes all zero stores globally visible
+            # before the first FC2 atomic -- so no extra barrier is added. The
+            # tiny m*hidden bf16 memset (decode: <=4*4096 elems) is dwarfed by
+            # FC1's whole-K FP4-weight stream, but we delete one whole kernel
+            # launch from the per-decode chain. The TC-decode output is per-token
+            # (top_k routes atomically summed into the SAME token row), so the
+            # zero span is active_m*hidden_size -- NOT the per-route
+            # active_m*top_k*hidden_size of _zero_fc2_output.
+            # tc_zero_output=False skips the zero (a paired earlier launch has
+            # already zeroed the shared output); the grid barrier below is
+            # unconditional so ordering is preserved either way.
+            if cutlass.const_expr(self.tc_zero_output):
+                zidx = cta * Int32(self.cta_threads) + tid
+                zstride = grid_x * Int32(self.cta_threads)
+                ztotal = active_m * Int32(self.hidden_size)
+                zzero = self._cast_elem(cutlass.Float32(0.0))
+                while zidx < ztotal:
+                    fc2_bf16_flat[zidx] = zzero
+                    zidx += zstride
+
+        if cutlass.const_expr(self.activation_is_gated):
+            self.fc1._run_persistent_gemm(
+                a_bf16_flat,
+                w13_i32_flat,
+                fc1_bf16_flat,
+                w13_scales_i32_flat,
+                w13_global_scale,
+                packed_route_indices,
+                block_expert_ids,
+                packed_route_count,
+                topk_weights_flat,
+                fc1_c_tmp_f32_flat,
+                locks_i32_flat,
+                smem_base,
+                tid,
+                cta,
+                grid_x,
+                active_m,
+            )
+            self._grid_barrier(locks_i32_flat, tid, grid_x)
+            self._run_activation(
+                fc1_bf16_flat,
+                activated_bf16_flat,
+                tid,
+                cta,
+                grid_x,
+                active_m,
+            )
+        else:
+            self.fc1._run_persistent_gemm(
+                a_bf16_flat,
+                w13_i32_flat,
+                activated_bf16_flat,
+                w13_scales_i32_flat,
+                w13_global_scale,
+                packed_route_indices,
+                block_expert_ids,
+                packed_route_count,
+                topk_weights_flat,
+                fc1_c_tmp_f32_flat,
+                locks_i32_flat,
+                smem_base,
+                tid,
+                cta,
+                grid_x,
+                active_m,
+            )
+        self._grid_barrier(locks_i32_flat, tid, grid_x)
+        if cutlass.const_expr(self.collect_activation_amax):
+            self._collect_activation_amax_epilogue(
+                a_bf16_flat,
+                activated_bf16_flat,
+                packed_route_indices,
+                block_expert_ids,
+                packed_route_count,
+                activation_amax_flat,
+                layer_idx,
+                smem_base,
+                tid,
+                cta,
+                grid_x,
+                active_m,
+            )
+        if cutlass.const_expr(self.zero_fc2_output):
+            self._zero_fc2_output(fc2_bf16_flat, tid, cta, grid_x, active_m)
+            self._grid_barrier(locks_i32_flat, tid, grid_x)
+        self.fc2._run_persistent_gemm(
+            activated_bf16_flat,
+            w2_i32_flat,
+            fc2_bf16_flat,
+            w2_scales_i32_flat,
+            w2_global_scale,
+            packed_route_indices,
+            block_expert_ids,
+            packed_route_count,
+            topk_weights_flat,
+            fc2_c_tmp_f32_flat,
+            locks_i32_flat,
+            smem_base,
+            tid,
+            cta,
+            grid_x,
+            active_m * Int32(self.top_k),
+        )
+
+    @cute.jit
+    def _grid_barrier(
+        self,
+        locks_i32_flat: cute.Tensor,
+        tid: Int32,
+        grid_x: Int32,
+    ):
+        cute.arch.sync_threads()
+        if tid == Int32(0):
+            count_addr = get_ptr_as_int64(locks_i32_flat, Int32(self.barrier_count_off))
+            sense_addr = get_ptr_as_int64(locks_i32_flat, Int32(self.barrier_sense_off))
+            old_sense = ld_global_acquire_i32(sense_addr)
+            old_count = atomic_add_global_i32(count_addr, Int32(1))
+            if old_count == grid_x - Int32(1):
+                st_global_i32(count_addr, Int32(0))
+                threadfence()
+                red_add_global_release_i32(sense_addr, Int32(1))
+            else:
+                sense = old_sense
+                while sense == old_sense:
+                    sense = ld_global_acquire_i32(sense_addr)
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _zero_fc2_output(
+        self,
+        fc2_bf16_flat: cute.Tensor,
+        tid: Int32,
+        cta: Int32,
+        grid_x: Int32,
+        active_m: cutlass.Int32,
+    ):
+        idx = cta * Int32(self.cta_threads) + tid
+        stride = grid_x * Int32(self.cta_threads)
+        total = active_m * Int32(self.top_k * self.hidden_size)
+        zero = self._cast_elem(cutlass.Float32(0.0))
+        while idx < total:
+            fc2_bf16_flat[idx] = zero
+            idx += stride
+
+    @cute.jit
+    def _reduce_and_red_activation_amax(
+        self,
+        local_max: cutlass.Float32,
+        activation_amax_flat: cute.Tensor,
+        layer_idx: cutlass.Int32,
+        expert_idx: Int32,
+        slot: Int32,
+        smem_base: Int32,
+        tid: Int32,
+    ):
+        lane = tid & Int32(31)
+        warp_idx = tid // Int32(32)
+        warp_amax = warp_reduce(local_max, fmax_f32)
+        if lane == Int32(0):
+            st_shared_f32(smem_base + warp_idx * Int32(4), warp_amax)
+        cute.arch.sync_threads()
+
+        if warp_idx == Int32(0):
+            block_amax = cutlass.Float32(0.0)
+            if lane < Int32(self.cta_threads // 32):
+                block_amax = ld_shared_f32(smem_base + lane * Int32(4))
+            block_amax = warp_reduce(block_amax, fmax_f32)
+            if lane == Int32(0) and block_amax > cutlass.Float32(0.0):
+                out_idx = (
+                    (layer_idx * Int32(self.num_experts) + expert_idx) * Int32(2)
+                    + slot
+                )
+                red_max_global_f32_nonnegative(
+                    get_ptr_as_int64(activation_amax_flat, out_idx),
+                    block_amax,
+                )
+        cute.arch.sync_threads()
+
+    @cute.jit
+    def _collect_activation_amax_epilogue(
+        self,
+        a_bf16_flat: cute.Tensor,
+        activated_bf16_flat: cute.Tensor,
+        packed_route_indices: cute.Tensor,
+        block_expert_ids: cute.Tensor,
+        packed_route_count: cute.Tensor,
+        activation_amax_flat: cute.Tensor,
+        layer_idx: cutlass.Int32,
+        smem_base: Int32,
+        tid: Int32,
+        cta: Int32,
+        grid_x: Int32,
+        active_m: cutlass.Int32,
+    ):
+        live_routes = active_m * Int32(self.top_k)
+        route_count = packed_route_count[Int32(0)].to(Int32)
+        route_blocks = (
+            route_count + Int32(self.moe_block_size) - Int32(1)
+        ) // Int32(self.moe_block_size)
+        expert_idx = cta
+        while expert_idx < Int32(self.num_experts):
+            local_fc1 = cutlass.Float32(0.0)
+            local_fc2 = cutlass.Float32(0.0)
+            has_route_block = Int32(0)
+            block_idx = Int32(0)
+            while block_idx < route_blocks:
+                block_expert = block_expert_ids[block_idx].to(Int32)
+                if block_expert == expert_idx:
+                    has_route_block = Int32(1)
+                    route_pos = block_idx * Int32(self.moe_block_size)
+                    route_stop = route_pos + Int32(self.moe_block_size)
+                    if route_stop > route_count:
+                        route_stop = route_count
+                    while route_pos < route_stop:
+                        route_idx = packed_route_indices[route_pos].to(Int32)
+                        if route_idx >= Int32(0) and route_idx < live_routes:
+                            token_idx = route_idx // Int32(self.top_k)
+                            fc1_col = tid
+                            while fc1_col < Int32(self.hidden_size):
+                                v1 = a_bf16_flat[
+                                    token_idx * Int32(self.hidden_size) + fc1_col
+                                ].to(cutlass.Float32)
+                                local_fc1 = fmax_f32(local_fc1, fabs_f32(v1))
+                                fc1_col += Int32(self.cta_threads)
+
+                            fc2_col = tid
+                            while fc2_col < Int32(self.intermediate_size):
+                                v2 = activated_bf16_flat[
+                                    route_idx * Int32(self.intermediate_size) + fc2_col
+                                ].to(cutlass.Float32)
+                                local_fc2 = fmax_f32(local_fc2, fabs_f32(v2))
+                                fc2_col += Int32(self.cta_threads)
+                        route_pos += Int32(1)
+                block_idx += Int32(1)
+
+            if has_route_block != Int32(0):
+                self._reduce_and_red_activation_amax(
+                    local_fc1,
+                    activation_amax_flat,
+                    layer_idx,
+                    expert_idx,
+                    Int32(0),
+                    smem_base,
+                    tid,
+                )
+                self._reduce_and_red_activation_amax(
+                    local_fc2,
+                    activation_amax_flat,
+                    layer_idx,
+                    expert_idx,
+                    Int32(1),
+                    smem_base,
+                    tid,
+                )
+            expert_idx += grid_x
+
+    @cute.jit
+    def _run_activation(
+        self,
+        fc1_bf16_flat: cute.Tensor,
+        activated_bf16_flat: cute.Tensor,
+        tid: Int32,
+        cta: Int32,
+        grid_x: Int32,
+        active_m: cutlass.Int32,
+    ):
+        idx = cta * Int32(self.cta_threads) + tid
+        stride = grid_x * Int32(self.cta_threads)
+        total = active_m * Int32(self.top_k * self.intermediate_size)
+        while idx < total:
+            if cutlass.const_expr(self.activation_is_gated):
+                row = idx // Int32(self.intermediate_size)
+                col = idx - row * Int32(self.intermediate_size)
+                base = row * Int32(self.fc1_cols)
+                gate = fc1_bf16_flat[base + col].to(cutlass.Float32)
+                up = fc1_bf16_flat[base + Int32(self.intermediate_size) + col].to(
+                    cutlass.Float32
+                )
+                gate, up = self._clamp_swiglu_inputs(gate, up)
+                sigmoid_arg = gate
+                up_term = up
+                if cutlass.const_expr(self.activation_is_swigluoai):
+                    sigmoid_arg = cutlass.Float32(self.swiglu_alpha) * gate
+                    up_term = up + cutlass.Float32(self.swiglu_beta)
+                if cutlass.const_expr(self.fast_math):
+                    exp_neg_gate = cute.math.exp(-sigmoid_arg, fastmath=True)
+                else:
+                    exp_neg_gate = cute.math.exp(-sigmoid_arg, fastmath=False)
+                silu = gate / (cutlass.Float32(1.0) + exp_neg_gate)
+                if cutlass.const_expr(self.activation_is_swigluoai):
+                    activated_bf16_flat[idx] = self._cast_elem(silu * up_term)
+                else:
+                    activated_bf16_flat[idx] = self._cast_elem(
+                        self._cast_elem(silu) * self._cast_elem(up_term)
+                    )
+            else:
+                x = fc1_bf16_flat[idx].to(cutlass.Float32)
+                if x < cutlass.Float32(0.0):
+                    x = cutlass.Float32(0.0)
+                activated_bf16_flat[idx] = self._cast_elem(x * x)
+            idx += stride
+
+
+class W4A16ActivationKernel:
+    def __init__(
+        self,
+        *,
+        rows: int,
+        intermediate_size: int,
+        activation: str,
+        element_dtype: str = "bf16",
+        fast_math: bool = True,
+        swiglu_limit: float | None = None,
+        swiglu_alpha: float | None = None,
+        swiglu_beta: float | None = None,
+    ):
+        activation = normalize_moe_activation(activation)
+        is_gated = validate_activation(activation)
+        swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+            activation,
+            swiglu_limit,
+            swiglu_alpha,
+            swiglu_beta,
+        )
+        if element_dtype not in {"bf16", "fp16"}:
+            raise ValueError(f"unsupported element_dtype {element_dtype!r}")
+        if rows <= 0 or intermediate_size <= 0:
+            raise ValueError("rows and intermediate_size must be positive")
+        self.rows = int(rows)
+        self.intermediate_size = int(intermediate_size)
+        self.activation = activation
+        self.is_gated = is_gated
+        self.is_swigluoai = activation == SWIGLUOAI_UNINTERLEAVE
+        self.has_swiglu_limit = swiglu_limit is not None
+        self.swiglu_limit = 0.0 if swiglu_limit is None else swiglu_limit
+        self.swiglu_alpha = float(swiglu_alpha)
+        self.swiglu_beta = float(swiglu_beta)
+        self.element_dtype = element_dtype
+        self.is_fp16 = element_dtype == "fp16"
+        self.fast_math = bool(fast_math)
+        self.cta_threads = 256
+
+    @property
+    def __cache_key__(self) -> tuple[object, ...]:
+        return (
+            self.intermediate_size,
+            self.activation,
+            self.is_gated,
+            self.is_swigluoai,
+            self.has_swiglu_limit,
+            self.swiglu_limit,
+            self.swiglu_alpha,
+            self.swiglu_beta,
+            self.element_dtype,
+            self.fast_math,
+            self.cta_threads,
+        )
+
+    @cute.jit
+    def _cast_elem(self, x: cutlass.Float32):
+        if cutlass.const_expr(self.is_fp16):
+            return cutlass.Float16(x)
+        return cutlass.BFloat16(x)
+
+    @cute.jit
+    def _clamp_swiglu_inputs(
+        self,
+        gate: cutlass.Float32,
+        up: cutlass.Float32,
+    ):
+        if cutlass.const_expr(self.has_swiglu_limit):
+            limit = cutlass.Float32(self.swiglu_limit)
+            neg_limit = cutlass.Float32(-self.swiglu_limit)
+            if gate > limit:
+                gate = limit
+            if up > limit:
+                up = limit
+            if up < neg_limit:
+                up = neg_limit
+        return gate, up
+
+    @cute.jit
+    def __call__(
+        self,
+        fc1_flat: cute.Tensor,
+        activated_flat: cute.Tensor,
+        active_rows: cutlass.Int32,
+        stream: cuda.CUstream,
+    ):
+        total = active_rows * Int32(self.intermediate_size)
+        grid = (_covering_count(total, self.cta_threads), 1, 1)
+        self.kernel(fc1_flat, activated_flat, active_rows).launch(
+            grid=grid,
+            block=[self.cta_threads, 1, 1],
+            stream=stream,
+        )
+
+    @cute.kernel
+    def kernel(
+        self,
+        fc1_flat: cute.Tensor,
+        activated_flat: cute.Tensor,
+        active_rows: cutlass.Int32,
+    ):
+        tidx, _, _ = cute.arch.thread_idx()
+        bidx, _, _ = cute.arch.block_idx()
+        idx = Int32(bidx) * Int32(self.cta_threads) + Int32(tidx)
+        total = Int32(active_rows) * Int32(self.intermediate_size)
+        if idx < total:
+            if cutlass.const_expr(self.is_gated):
+                row = idx // Int32(self.intermediate_size)
+                col = idx - row * Int32(self.intermediate_size)
+                base = row * Int32(2 * self.intermediate_size)
+                gate = fc1_flat[base + col].to(cutlass.Float32)
+                up = fc1_flat[base + Int32(self.intermediate_size) + col].to(
+                    cutlass.Float32
+                )
+                gate, up = self._clamp_swiglu_inputs(gate, up)
+                sigmoid_arg = gate
+                up_term = up
+                if cutlass.const_expr(self.is_swigluoai):
+                    sigmoid_arg = cutlass.Float32(self.swiglu_alpha) * gate
+                    up_term = up + cutlass.Float32(self.swiglu_beta)
+                if cutlass.const_expr(self.fast_math):
+                    exp_neg_gate = cute.math.exp(-sigmoid_arg, fastmath=True)
+                else:
+                    exp_neg_gate = cute.math.exp(-sigmoid_arg, fastmath=False)
+                silu = gate / (cutlass.Float32(1.0) + exp_neg_gate)
+                if cutlass.const_expr(self.is_swigluoai):
+                    activated_flat[idx] = self._cast_elem(silu * up_term)
+                else:
+                    activated_flat[idx] = self._cast_elem(
+                        self._cast_elem(silu) * self._cast_elem(up_term)
+                    )
+            else:
+                x = fc1_flat[idx].to(cutlass.Float32)
+                if x < cutlass.Float32(0.0):
+                    x = cutlass.Float32(0.0)
+                activated_flat[idx] = self._cast_elem(x * x)
+
+
+class W4A16TopKSumKernel:
+    def __init__(
+        self, *, topk: int, hidden_size: int, element_dtype: str = "bf16"
+    ):
+        if element_dtype not in {"bf16", "fp16"}:
+            raise ValueError(f"unsupported element_dtype {element_dtype!r}")
+        if topk <= 0 or hidden_size <= 0:
+            raise ValueError("topk and hidden_size must be positive")
+        self.topk = int(topk)
+        self.hidden_size = int(hidden_size)
+        self.element_dtype = element_dtype
+        self.is_fp16 = element_dtype == "fp16"
+        self.cta_threads = 256
+
+    @cute.jit
+    def _cast_elem(self, x: cutlass.Float32):
+        if cutlass.const_expr(self.is_fp16):
+            return cutlass.Float16(x)
+        return cutlass.BFloat16(x)
+
+    @cute.jit
+    def __call__(
+        self,
+        fc2_ptr: cute.Pointer,
+        output_ptr: cute.Pointer,
+        active_m: cutlass.Int32,
+        stream: cuda.CUstream,
+    ):
+        fc2_flat = cute.make_tensor(
+            fc2_ptr,
+            layout=cute.make_layout(
+                (active_m * Int32(self.topk * self.hidden_size),), stride=(1,)
+            ),
+        )
+        output_flat = cute.make_tensor(
+            output_ptr,
+            layout=cute.make_layout((active_m * Int32(self.hidden_size),), stride=(1,)),
+        )
+        total = active_m * Int32(self.hidden_size)
+        grid = (_covering_count(total, self.cta_threads), 1, 1)
+        self.kernel(fc2_flat, output_flat, active_m).launch(
+            grid=grid,
+            block=[self.cta_threads, 1, 1],
+            stream=stream,
+        )
+
+    @cute.kernel
+    def kernel(
+        self,
+        fc2_flat: cute.Tensor,
+        output_flat: cute.Tensor,
+        active_m: cutlass.Int32,
+    ):
+        tidx, _, _ = cute.arch.thread_idx()
+        bidx, _, _ = cute.arch.block_idx()
+        idx = Int32(bidx) * Int32(self.cta_threads) + Int32(tidx)
+        total = active_m * Int32(self.hidden_size)
+        if idx < total:
+            token = idx // Int32(self.hidden_size)
+            col = idx - token * Int32(self.hidden_size)
+            acc = cutlass.Float32(0.0)
+            for route in cutlass.range_constexpr(self.topk):
+                row = token * Int32(self.topk) + Int32(route)
+                acc += fc2_flat[row * Int32(self.hidden_size) + col].to(cutlass.Float32)
+            output_flat[idx] = self._cast_elem(acc)
+
+
+_CACHE: dict[tuple, W4A16GemmCompileResult] = {}
+_FUSED_CACHE: dict[tuple, W4A16FusedMoeCompileResult] = {}
+_ACTIVATION_CACHE: dict[tuple, W4A16ActivationCompileResult] = {}
+_SUM_CACHE: dict[tuple, W4A16TopKSumCompileResult] = {}
+_SMALL_M_DIRECT_CACHE: dict[tuple, _W4A16SmallMDirectLaunch] = {}
+
+
+def _normalize_element_dtype(dtype: torch.dtype) -> str:
+    if dtype == torch.bfloat16:
+        return "bf16"
+    if dtype == torch.float16:
+        return "fp16"
+    raise TypeError(f"unsupported W4A16 activation dtype {dtype}")
+
+
+def _normalize_scale_format(scale_format: str) -> str:
+    try:
+        return _SCALE_FORMATS[scale_format.lower()]
+    except KeyError as exc:
+        raise ValueError(
+            "scale_format must be one of 'e4m3_k16', 'e8m0_k32', or 'e4m3_k32', "
+            f"got {scale_format!r}"
+        ) from exc
+
+
+def _scale_group_size(scale_format: str) -> int:
+    return (
+        32
+        if _normalize_scale_format(scale_format) in ("e8m0_k32", "e4m3_k32")
+        else 16
+    )
+
+
+def _scale_fake_int32_elements(
+    *,
+    num_experts: int,
+    size_k: int,
+    size_n: int,
+    scale_format: str,
+    allow_k_tail: bool = False,
+    allow_n_tail: bool = False,
+) -> int:
+    group_size = _scale_group_size(scale_format)
+    if int(size_n) % 16 != 0:
+        raise ValueError(
+            f"W4A16 {scale_format} scales require size_n divisible by 16"
+        )
+    if int(size_k) % group_size != 0 and not allow_k_tail:
+        raise ValueError(
+            f"W4A16 {scale_format} scales require size_k divisible by {group_size}, "
+            f"got {size_k}"
+        )
+    groups_k = (
+        _covering_count(int(size_k), group_size)
+        if allow_k_tail
+        else int(size_k) // group_size
+    )
+    scale_size_n = (
+        _e8m0_logical_tail_scale_n(int(size_n)) if allow_n_tail else int(size_n)
+    )
+    return int(num_experts) * groups_k * (scale_size_n // 4)
+
+
+def _cutlass_element_dtype(element_dtype: str):
+    if element_dtype == "bf16":
+        return cutlass.BFloat16
+    if element_dtype == "fp16":
+        return cutlass.Float16
+    raise ValueError(f"unsupported element_dtype {element_dtype!r}")
+
+
+def _small_m_direct_supported(
+    *,
+    m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    swiglu_limit: float | None,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    element_dtype: str,
+    weight_layout: str,
+    w13_layout: str,
+    scale_format: str = "e4m3_k16",
+    expert_map: torch.Tensor | None = None,
+) -> bool:
+    if os.environ.get("B12X_W4A16_SMALL_M_DIRECT", "1") == "0":
+        return False
+    activation = normalize_moe_activation(activation)
+    swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+        activation,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+    )
+    if activation == SWIGLUOAI_UNINTERLEAVE and swiglu_limit is None:
+        return False
+    return (
+        element_dtype == "bf16"
+        # Packed serving weights use the W4A16 TC-decode path for small M.
+        # The direct micro kernel is kept limited to native ModelOpt weights.
+        and weight_layout == "modelopt"
+        and w13_layout in ("w13", "w31")
+        and not bool(apply_router_weight_on_input)
+        and (swiglu_limit is None or activation in ("silu", SWIGLUOAI_UNINTERLEAVE))
+        and expert_map is None
+        and _W4A16SmallMDirectKernel.is_supported(
+            m=m,
+            hidden_size=hidden_size,
+            intermediate_size=intermediate_size,
+            topk=topk,
+            num_experts=num_experts,
+            scale_format=scale_format,
+        )
+    )
+
+
+def _compile_w4a16_small_m_direct(
+    *,
+    m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    fast_math: bool,
+    topk_ids_dtype: torch.dtype,
+    device: torch.device | None,
+    scale_format: str = "e4m3_k16",
+    swiglu_limit: float | None = None,
+    swiglu_alpha: float | None = None,
+    swiglu_beta: float | None = None,
+    w13_layout: str = "w13",
+) -> _W4A16SmallMDirectLaunch:
+    if topk_ids_dtype not in (torch.int32, torch.int64):
+        raise TypeError("small-M W4A16 direct path requires int32/int64 topk_ids")
+    activation = normalize_moe_activation(activation)
+    swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+        activation,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+    )
+    cache_key = (
+        "w4a16_small_m_direct",
+        None if device is None else int(device.index or 0),
+        int(m),
+        int(hidden_size),
+        int(intermediate_size),
+        int(num_experts),
+        int(topk),
+        activation,
+        bool(fast_math),
+        topk_ids_dtype,
+        scale_format,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+        w13_layout,
+    )
+    cached = _SMALL_M_DIRECT_CACHE.get(cache_key)
+    if cached is not None:
+        return cached
+
+    kernel = _W4A16SmallMDirectKernel(
+        activation=activation,
+        fast_math=bool(fast_math),
+        share_input_across_experts=(int(m) == 1),
+        share_expert_scales=True,
+        single_token=(int(m) == 1),
+        scale_format=scale_format,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        w13_layout=w13_layout,
+    )
+    kernel.configure(
+        int(m),
+        int(hidden_size),
+        int(intermediate_size),
+        int(topk),
+        int(num_experts),
+        device=device,
+    )
+
+    def dummy(dt):
+        return make_ptr(dt, 16, cute.AddressSpace.gmem, assumed_align=16)
+
+    ids_dtype = cutlass.Int32 if topk_ids_dtype == torch.int32 else cutlass.Int64
+    barrier_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (1,),
+        assumed_align=4,
+    )
+    raise_if_kernel_resolution_frozen(
+        "cute.compile", target=kernel, cache_key=cache_key
+    )
+    compiled = b12x_compile(
+        kernel,
+        dummy(cutlass.BFloat16),
+        dummy(cutlass.Uint8),
+        dummy(cutlass.Uint8),
+        dummy(cutlass.Float32),
+        dummy(cutlass.Float32),
+        dummy(cutlass.Float32),
+        dummy(cutlass.Uint32),
+        dummy(cutlass.Uint8),
+        dummy(cutlass.Uint8),
+        dummy(cutlass.Float32),
+        dummy(ids_dtype),
+        dummy(cutlass.Float32),
+        dummy(cutlass.BFloat16),
+        barrier_fake,
+        barrier_fake,
+        Int32(m),
+        Int32(kernel.grid_x),
+        current_cuda_stream(),
+        compile_spec=KernelCompileSpec.from_facts(
+            "moe.w4a16.small_m_direct",
+            1,
+            ("device_index", None if device is None else int(device.index or 0)),
+            ("m", int(m)),
+            ("hidden_size", int(hidden_size)),
+            ("intermediate_size", int(intermediate_size)),
+            ("num_experts", int(num_experts)),
+            ("topk", int(topk)),
+            ("activation", activation),
+            ("fast_math", bool(fast_math)),
+            ("topk_ids_dtype", str(topk_ids_dtype)),
+            ("scale_format", scale_format),
+            ("swiglu_limit", swiglu_limit),
+            ("swiglu_alpha", swiglu_alpha),
+            ("swiglu_beta", swiglu_beta),
+            ("w13_layout", w13_layout),
+            ("grid_x", int(kernel.grid_x)),
+        ),
+    )
+    launch = _W4A16SmallMDirectLaunch(
+        compiled=compiled,
+        grid_x=int(kernel.grid_x),
+        m=int(m),
+        hidden_size=int(hidden_size),
+        intermediate_size=int(intermediate_size),
+        num_experts=int(num_experts),
+        topk=int(topk),
+        activation=activation,
+        fast_math=bool(fast_math),
+        topk_ids_dtype=topk_ids_dtype,
+    )
+    _SMALL_M_DIRECT_CACHE[cache_key] = launch
+    return launch
+
+
+def compile_w4a16_gemm(
+    *,
+    size_m: int,
+    size_n: int,
+    size_k: int,
+    num_experts: int,
+    top_k: int,
+    mul_topk_weights: bool,
+    tile_n: int,
+    tile_k: int,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str = "bf16",
+    scale_format: str = "e4m3_k16",
+) -> W4A16GemmCompileResult:
+    scale_format = _normalize_scale_format(scale_format)
+    cutlass_dtype = _cutlass_element_dtype(element_dtype)
+    if torch.cuda.is_available():
+        device = int(torch.cuda.current_device())
+    else:
+        device = None
+    kernel = W4A16GemmKernel(
+        size_m=size_m,
+        size_n=size_n,
+        size_k=size_k,
+        num_experts=num_experts,
+        top_k=top_k,
+        mul_topk_weights=mul_topk_weights,
+        tile_n=tile_n,
+        tile_k=tile_k,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        scale_format=scale_format,
+    )
+    cache_key = (
+        "w4a16_gemm",
+        device,
+        kernel.__cache_key__,
+    )
+    cached = _CACHE.get(cache_key)
+    if cached is not None:
+        return replace(
+            cached,
+            max_m_blocks=max_m_blocks,
+            blocks_per_sm=kernel.blocks_per_sm,
+        )
+
+    compile_size_m = _fake_m_for_specialization(size_m)
+    compile_route_blocks = 1
+    compile_route_slots = compile_route_blocks * int(moe_block_size)
+    a_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_size_m * size_k,),
+        assumed_align=16,
+    )
+    b_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (num_experts * (size_k // 16) * (size_n // 16 * 32),),
+        assumed_align=16,
+    )
+    c_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_size_m * top_k * size_n,),
+        assumed_align=16,
+    )
+    scales_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (
+            _scale_fake_int32_elements(
+                num_experts=num_experts,
+                size_k=size_k,
+                size_n=size_n,
+                scale_format=scale_format,
+            ),
+        ),
+        assumed_align=16,
+    )
+    global_scale_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (num_experts,),
+        assumed_align=16,
+    )
+    packed_routes_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (compile_route_slots,),
+        assumed_align=16,
+    )
+    block_experts_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (compile_route_blocks,),
+        assumed_align=16,
+    )
+    route_count_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (1,),
+        assumed_align=4,
+    )
+    topk_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (compile_size_m * top_k,),
+        assumed_align=4,
+    )
+    c_tmp_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (
+            max(
+                size_n * compile_route_slots,
+                4 * 256 * moe_block_size * 256,
+            ),
+        ),
+        assumed_align=16,
+    )
+    locks_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (4 * 256,),
+        assumed_align=16,
+    )
+
+    raise_if_kernel_resolution_frozen(
+        "cute.compile", target=kernel, cache_key=cache_key
+    )
+    compiled = b12x_compile(
+        kernel,
+        a_fake,
+        b_fake,
+        c_fake,
+        scales_fake,
+        global_scale_fake,
+        packed_routes_fake,
+        block_experts_fake,
+        route_count_fake,
+        topk_fake,
+        c_tmp_fake,
+        locks_fake,
+        Int32(compile_size_m),
+        Int32(1),
+        current_cuda_stream(),
+        compile_spec=KernelCompileSpec.from_key(
+            "moe.w4a16.gemm",
+            1,
+            cache_key,
+        ),
+    )
+    result = W4A16GemmCompileResult(
+        compiled=compiled,
+        tile_n=tile_n,
+        tile_k=tile_k,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        blocks_per_sm=kernel.blocks_per_sm,
+        scale_format=scale_format,
+    )
+    _CACHE[cache_key] = result
+    return result
+
+
+def compile_w4a16_fused_moe(
+    *,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    top_k: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str = "bf16",
+    fast_math: bool = True,
+    sms: int,
+    max_shared_mem: int,
+    swiglu_limit: float | None = None,
+    swiglu_alpha: float | None = None,
+    swiglu_beta: float | None = None,
+    weight_layout: str = "packed",
+    scale_format: str = "e4m3_k16",
+    w13_layout: str = "w13",
+    direct_topk_routes: bool = False,
+    tc_decode_fused_sum: bool = False,
+    collect_activation_amax: bool = False,
+    force_tile_config: tuple[int, int, int, int] | None = None,
+) -> W4A16FusedMoeCompileResult:
+    scale_format = _normalize_scale_format(scale_format)
+    cutlass_dtype = _cutlass_element_dtype(element_dtype)
+    device = int(torch.cuda.current_device()) if torch.cuda.is_available() else None
+    activation = normalize_moe_activation(activation)
+    is_gated = validate_activation(activation)
+    swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+        activation,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+    )
+    if weight_layout not in _WEIGHT_LAYOUTS:
+        raise ValueError(f"unsupported W4A16 weight_layout {weight_layout!r}")
+    if weight_layout == "modelopt":
+        if w13_layout not in _MODEL_OPT_W13_LAYOUTS:
+            raise ValueError(f"unsupported W4A16 w13_layout {w13_layout!r}")
+    else:
+        w13_layout = "packed"
+    direct_topk_routes = bool(direct_topk_routes)
+    tc_decode_fused_sum = bool(tc_decode_fused_sum)
+    collect_activation_amax = bool(collect_activation_amax)
+    if collect_activation_amax and (direct_topk_routes or tc_decode_fused_sum):
+        raise ValueError(
+            "W4A16 activation amax collection requires the route-packed fused path"
+        )
+    # The TC-decode path validates M in {1,2,4,8} itself and uses direct-topk
+    # routing for the whole {1,2,4,8} range, so it lifts the default decode cap.
+    direct_topk_m_cap = (
+        _W4A16_SMALL_M_DIRECT_MAX_M if tc_decode_fused_sum else _MAX_DIRECT_TOPK_ROUTE_M
+    )
+    if direct_topk_routes and (
+        int(size_m) > direct_topk_m_cap
+        or weight_layout not in ("packed", "nf3_2p1")
+        or bool(zero_fc2_output)
+    ):
+        raise ValueError(
+            "direct_topk_routes is only valid for small-M packed W4A16 without expert_map"
+        )
+    fc1_cols = int(intermediate_size) * (2 if is_gated else 1)
+    routed_rows = int(size_m) * int(top_k)
+    allow_native_logical_tail = (
+        weight_layout == "modelopt"
+        and scale_format == "e8m0_k32"
+        and int(intermediate_size) % 32 != 0
+    )
+    fc1_tile_k, fc1_tile_n, fc1_cta_threads, _ = _select_tile_config(
+        problem_m=size_m,
+        problem_n=fc1_cols,
+        problem_k=hidden_size,
+        top_k=top_k,
+        moe_block_size=moe_block_size,
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        scale_format=scale_format,
+        allow_logical_tail=allow_native_logical_tail,
+    )
+    fc2_tile_k, fc2_tile_n, fc2_cta_threads, _ = _select_tile_config(
+        problem_m=routed_rows,
+        problem_n=hidden_size,
+        problem_k=intermediate_size,
+        top_k=1,
+        moe_block_size=moe_block_size,
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        scale_format=scale_format,
+        allow_logical_tail=allow_native_logical_tail,
+    )
+    if fc1_cta_threads != fc2_cta_threads:
+        common_cta_threads = min(fc1_cta_threads, fc2_cta_threads)
+        fc1_tile_k, fc1_tile_n, fc1_cta_threads, _ = _select_tile_config(
+            problem_m=size_m,
+            problem_n=fc1_cols,
+            problem_k=hidden_size,
+            top_k=top_k,
+            moe_block_size=moe_block_size,
+            sms=sms,
+            max_shared_mem=max_shared_mem,
+            required_cta_threads=common_cta_threads,
+            scale_format=scale_format,
+            allow_logical_tail=allow_native_logical_tail,
+        )
+        fc2_tile_k, fc2_tile_n, fc2_cta_threads, _ = _select_tile_config(
+            problem_m=routed_rows,
+            problem_n=hidden_size,
+            problem_k=intermediate_size,
+            top_k=1,
+            moe_block_size=moe_block_size,
+            sms=sms,
+            max_shared_mem=max_shared_mem,
+            required_cta_threads=common_cta_threads,
+            scale_format=scale_format,
+            allow_logical_tail=allow_native_logical_tail,
+        )
+        if fc1_cta_threads != fc2_cta_threads:
+            raise ValueError(
+                "fused W4A16 FC1/FC2 selected different thread counts: "
+                f"{fc1_cta_threads} vs {fc2_cta_threads}"
+            )
+    # TC-decode FC1 wide-N override (single-wave-collapse sizes only): in the m8
+    # fused path the host right-sizes grid_x to the FC1 mn-tile count and forces
+    # one whole mn-tile per CTA over the full K. With the default fc1_tile_n=128,
+    # FC1 (N=fc1_cols=2*intermediate_size) produces size_m*top_k*(fc1_cols/128)
+    # mn-tiles. For TP=2 I_tp=1024 (fc1_cols=2048 => 16 n-tiles/route) bs=1 is
+    # 96 tiles (<= 188 SMs, one wave); bs=2 is 192 -- JUST over the single-wave
+    # SM cap -- forcing a 2-wave launch of grid_x=96 (half the machine idle per
+    # wave, a serialized second FC1 wave of pure tail latency on the bandwidth-
+    # bound decode). Widening FC1 to tile_n=256 (256-wide N slab per CTA over
+    # full K; tile_k=64 keeps cta_threads=256) HALVES FC1's mn-tile count, so
+    # bs=2 collapses to 96 tiles = exactly ONE wave, removing that whole second
+    # FC1 wave. The narrower tile_k=64 is slower per-tile, so we apply this ONLY
+    # where it turns a 2-wave launch into a 1-wave launch: the default 128-wide
+    # FC1 spans 2 waves (sms < default_mn_tiles <= 2*sms) AND the wide tile fits
+    # in one (default/2 <= sms). bs=1 (one wave already) and bs>=4 (still multi-
+    # wave after halving) keep the faster default 128x128 tile.
+    # Guarded by fc1_cols%256==0, smem-fit, and 256-thread geometry so the fused
+    # FC1/FC2 single-thread-geometry contract is preserved.
+    default_fc1_mn_tiles = (
+        int(size_m) * int(top_k) * (int(fc1_cols) // int(fc1_tile_n))
+        if fc1_tile_n > 0
+        else 0
+    )
+    if (
+        bool(tc_decode_fused_sum)
+        and int(fc1_cols) % 256 == 0
+        and fc1_tile_n == 128
+        and (fc1_tile_n * fc1_tile_k) // 64 == 256
+        and int(sms) < default_fc1_mn_tiles <= 2 * int(sms)
+        and (default_fc1_mn_tiles // 2) <= int(sms)
+    ):
+        wide_fc1_tile_k = 64
+        if _candidate_tile_fits(
+            problem_n=fc1_cols,
+            problem_k=hidden_size,
+            cta_m_blocks=_covering_count(moe_block_size, 16),
+            tile_n=256,
+            tile_k=wide_fc1_tile_k,
+            cta_threads=256,
+            max_shared_mem=int(max_shared_mem) - 512,
+            scale_format=scale_format,
+        ):
+            fc1_tile_n = 256
+            fc1_tile_k = wide_fc1_tile_k
+            fc1_cta_threads = 256
+    # TC-decode FC2 wide-N override: in the m8 fused path the host right-sizes
+    # grid_x to the FC1 mn-tile count (one persistent wave, no split-K). FC2
+    # (N=hidden_size, K=intermediate_size) with the default tile_n=128 produces
+    # route_blocks*(hidden_size/128) mn-tiles -- roughly double FC1's count --
+    # so FC2 would need ~2 persistent waves while FC1 fits in 1; that second
+    # FC2 wave is pure serialized tail latency on the bandwidth-bound decode.
+    # Selecting tile_n=256 for FC2 (a 256-wide N slab per CTA over full K)
+    # halves FC2's mn-tile count so it also fits one wave. Guarded by smem-fit,
+    # hidden_size%256==0, and matching cta_threads so the fused single
+    # thread-geometry contract is preserved.
+    if (
+        bool(tc_decode_fused_sum)
+        and int(hidden_size) % 256 == 0
+        and fc2_tile_n == 128
+        and fc1_cta_threads == 256
+    ):
+        wide_fc2_tile_k = 64
+        if _candidate_tile_fits(
+            problem_n=hidden_size,
+            problem_k=intermediate_size,
+            cta_m_blocks=_covering_count(moe_block_size, 16),
+            tile_n=256,
+            tile_k=wide_fc2_tile_k,
+            cta_threads=256,
+            max_shared_mem=int(max_shared_mem) - 512,
+            scale_format=scale_format,
+        ):
+            fc2_tile_n = 256
+            fc2_tile_k = wide_fc2_tile_k
+            fc2_cta_threads = 256
+    # TC-decode FC2 ultra-wide override (perfect wave-balance with FC1): the
+    # persistent grid_x is right-sized to FC1's mn-tile count. After the FC1/FC2
+    # wide-N (tile_n=256) overrides, bs=2 still has FC1=route_blocks*8 tiles vs
+    # FC2=route_blocks*16 tiles -- FC2 is DOUBLE FC1 and thus needs a second
+    # persistent wave at grid_x sized to FC1. That FC2 second wave is pure
+    # serialized tail latency on the bandwidth-bound decode. Widening FC2 to
+    # tile_n=512 (a 512-wide N slab per CTA over full K) halves FC2's mn-tile
+    # count again so FC2 == FC1's tile count and fits the SAME single wave. A
+    # 512-wide N tile needs tile_k=32 to keep cta_threads=256 (512*32/64); that
+    # is below the generic tile_k>=64 fits-floor, so we validate the footprint
+    # directly here. tile_k=32 == the e8m0_k32 scale group, so cta_k_blocks=2
+    # with one e8m0 scale group per k-tile -- the existing scale layout is a
+    # clean covering. Fire ONLY when it drops FC2 from >1 wave to FC1's wave
+    # count (bs=2). Numerically identical: only the FC2 output-tile width changes.
+    fc1_mn_after = (
+        int(size_m) * int(top_k) * (int(fc1_cols) // int(fc1_tile_n))
+        if fc1_tile_n > 0
+        else 0
+    )
+    fc2_mn_after = (
+        int(size_m) * int(top_k) * (int(hidden_size) // int(fc2_tile_n))
+        if fc2_tile_n > 0
+        else 0
+    )
+    if (
+        bool(tc_decode_fused_sum)
+        and int(hidden_size) % 512 == 0
+        and fc2_tile_n == 256
+        and fc1_cta_threads == 256
+        and fc1_mn_after > 0
+        and fc2_mn_after > fc1_mn_after
+        and (fc2_mn_after // 2) <= fc1_mn_after
+        and fc1_mn_after <= int(sms)
+    ):
+        ultra_fc2_tile_k = 32
+        ultra_smem = _shared_memory_footprint(
+            cta_m_blocks=_covering_count(moe_block_size, 16),
+            tile_n=512,
+            tile_k=ultra_fc2_tile_k,
+            scale_format=scale_format,
+        )
+        if (
+            int(intermediate_size) % ultra_fc2_tile_k == 0
+            and ultra_smem <= int(max_shared_mem) - 512
+        ):
+            fc2_tile_n = 512
+            fc2_tile_k = ultra_fc2_tile_k
+            fc2_cta_threads = 256
+    if force_tile_config is not None:
+        # Explicit (fc1_tile_k, fc1_tile_n, fc2_tile_k, fc2_tile_n) pin. The
+        # NF3 ("nf3_2p1") flat-span weight layout is packed for a specific CTA
+        # N-tile, so hybrid deployments pin ONE tile config across every m
+        # regime instead of the m-dependent auto selection (and TC-decode
+        # wide-N overrides) above. Overrides whatever was selected; the tiles
+        # land in the GEMM cache keys, so no cache collision is possible.
+        fc1_tile_k, fc1_tile_n, fc2_tile_k, fc2_tile_n = (
+            int(v) for v in force_tile_config
+        )
+        fc1_cta_threads = (fc1_tile_n * fc1_tile_k) // 64
+        fc2_cta_threads = (fc2_tile_n * fc2_tile_k) // 64
+        if fc1_cta_threads != fc2_cta_threads:
+            raise ValueError(
+                "force_tile_config FC1/FC2 thread counts must match, got "
+                f"{fc1_cta_threads} vs {fc2_cta_threads}"
+            )
+        for name, forced_pn, forced_pk, forced_tn, forced_tk in (
+            ("fc1", fc1_cols, hidden_size, fc1_tile_n, fc1_tile_k),
+            ("fc2", hidden_size, intermediate_size, fc2_tile_n, fc2_tile_k),
+        ):
+            if not _candidate_tile_fits(
+                problem_n=forced_pn,
+                problem_k=forced_pk,
+                cta_m_blocks=_covering_count(moe_block_size, 16),
+                tile_n=forced_tn,
+                tile_k=forced_tk,
+                cta_threads=fc1_cta_threads,
+                max_shared_mem=int(max_shared_mem) - 512,
+                scale_format=scale_format,
+                allow_logical_tail=allow_native_logical_tail,
+            ):
+                raise ValueError(
+                    f"force_tile_config {name} tile "
+                    f"(tile_k={forced_tk}, tile_n={forced_tn}) does not fit "
+                    f"problem N/K={forced_pn}/{forced_pk} at "
+                    f"moe_block_size={moe_block_size}"
+                )
+    kernel = W4A16FusedMoeKernel(
+        size_m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        top_k=top_k,
+        activation=activation,
+        apply_router_weight_on_input=apply_router_weight_on_input,
+        zero_fc2_output=zero_fc2_output,
+        fc1_tile_n=fc1_tile_n,
+        fc1_tile_k=fc1_tile_k,
+        fc2_tile_n=fc2_tile_n,
+        fc2_tile_k=fc2_tile_k,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        fast_math=fast_math,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        weight_layout=weight_layout,
+        scale_format=scale_format,
+        w13_layout=w13_layout,
+        direct_topk_routes=direct_topk_routes,
+        tc_decode_fused_sum=tc_decode_fused_sum,
+        collect_activation_amax=collect_activation_amax,
+    )
+    cache_key = (
+        "w4a16_fused_moe",
+        device,
+        kernel.__cache_key__,
+    )
+    cached = _FUSED_CACHE.get(cache_key)
+    if cached is not None:
+        return replace(
+            cached,
+            size_m=size_m,
+            max_m_blocks=max_m_blocks,
+            blocks_per_sm=kernel.blocks_per_sm,
+        )
+
+    if (not collect_activation_amax) and _small_m_direct_supported(
+        m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        topk=top_k,
+        activation=activation,
+        apply_router_weight_on_input=bool(apply_router_weight_on_input),
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        element_dtype=element_dtype,
+        weight_layout=weight_layout,
+        w13_layout=w13_layout,
+        scale_format=scale_format,
+    ):
+        for ids_dtype in (torch.int32, torch.int64):
+            _compile_w4a16_small_m_direct(
+                m=size_m,
+                hidden_size=hidden_size,
+                intermediate_size=intermediate_size,
+                num_experts=num_experts,
+                topk=top_k,
+                activation=activation,
+                fast_math=fast_math,
+                topk_ids_dtype=ids_dtype,
+                scale_format=scale_format,
+                swiglu_limit=swiglu_limit,
+                swiglu_alpha=swiglu_alpha,
+                swiglu_beta=swiglu_beta,
+                w13_layout=w13_layout,
+                device=torch.device("cuda", device) if device is not None else None,
+            )
+
+    compile_size_m = _fake_m_for_specialization(size_m)
+    compile_routed_rows = int(compile_size_m) * int(top_k)
+    compile_route_blocks = compile_routed_rows if direct_topk_routes else 1
+    compile_route_slots = compile_route_blocks * int(moe_block_size)
+    packed_route_fake_elements = (
+        compile_routed_rows
+        if direct_topk_routes
+        else compile_route_slots
+    )
+    a_fake = make_ptr(cutlass_dtype, 16, cute.AddressSpace.gmem, assumed_align=16)
+    if weight_layout == "modelopt":
+        w13_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Uint8,
+            (num_experts * fc1_cols * (hidden_size // 2),),
+            assumed_align=16,
+        )
+        w2_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Uint8,
+            (num_experts * hidden_size * (intermediate_size // 2),),
+            assumed_align=16,
+        )
+    elif weight_layout == "nf3_2p1":
+        # NF3: int32, 3 words per 32-code unit; (size_n // 2) units per K16 row.
+        w13_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Int32,
+            (num_experts * (hidden_size // 16) * (fc1_cols // 2) * 3,),
+            assumed_align=16,
+        )
+        w2_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Int32,
+            (num_experts * (intermediate_size // 16) * (hidden_size // 2) * 3,),
+            assumed_align=16,
+        )
+    else:
+        w13_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Int32,
+            (num_experts * (hidden_size // 16) * (fc1_cols // 16 * 32),),
+            assumed_align=16,
+        )
+        w2_fake = cute.runtime.make_fake_compact_tensor(
+            cutlass.Int32,
+            (num_experts * (intermediate_size // 16) * (hidden_size // 16 * 32),),
+            assumed_align=16,
+        )
+    fc1_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_routed_rows * fc1_cols,),
+        assumed_align=16,
+    )
+    activated_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_routed_rows * intermediate_size,),
+        assumed_align=16,
+    )
+    fc2_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_routed_rows * hidden_size,),
+        assumed_align=16,
+    )
+    w13_scales_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (
+            _scale_fake_int32_elements(
+                num_experts=num_experts,
+                size_k=hidden_size,
+                size_n=fc1_cols,
+                scale_format=scale_format,
+                allow_n_tail=allow_native_logical_tail,
+            ),
+        ),
+        assumed_align=16,
+    )
+    w2_scales_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (
+            _scale_fake_int32_elements(
+                num_experts=num_experts,
+                size_k=intermediate_size,
+                size_n=hidden_size,
+                scale_format=scale_format,
+                allow_k_tail=allow_native_logical_tail,
+            ),
+        ),
+        assumed_align=16,
+    )
+    w13_global_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (num_experts,),
+        assumed_align=16,
+    )
+    w2_global_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (num_experts,),
+        assumed_align=16,
+    )
+    packed_routes_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (packed_route_fake_elements,),
+        assumed_align=16,
+    )
+    block_experts_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (compile_route_blocks,),
+        assumed_align=16,
+    )
+    route_count_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (1,),
+        assumed_align=4,
+    )
+    activation_amax_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (num_experts * 2,),
+        assumed_align=4,
+    )
+    topk_fake = make_ptr(cutlass.Float32, 4, cute.AddressSpace.gmem, assumed_align=4)
+    fc1_c_tmp_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (
+            max(
+                fc1_cols * compile_route_slots,
+                4 * 256 * moe_block_size * 256,
+            ),
+        ),
+        assumed_align=16,
+    )
+    fc2_c_tmp_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Float32,
+        (
+            max(
+                hidden_size * compile_route_slots,
+                4 * 256 * moe_block_size * 256,
+            ),
+        ),
+        assumed_align=16,
+    )
+    locks_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass.Int32,
+        (4 * 256 + 2,),
+        assumed_align=16,
+    )
+
+    raise_if_kernel_resolution_frozen(
+        "cute.compile", target=kernel, cache_key=cache_key
+    )
+    compiled = b12x_compile(
+        kernel,
+        a_fake,
+        w13_fake,
+        w2_fake,
+        fc1_fake,
+        activated_fake,
+        fc2_fake,
+        w13_scales_fake,
+        w2_scales_fake,
+        w13_global_fake,
+        w2_global_fake,
+        packed_routes_fake,
+        block_experts_fake,
+        route_count_fake,
+        activation_amax_fake,
+        0,
+        topk_fake,
+        fc1_c_tmp_fake,
+        fc2_c_tmp_fake,
+        locks_fake,
+        1,
+        1,
+        current_cuda_stream(),
+        compile_spec=KernelCompileSpec.from_key(
+            "moe.w4a16.fused_moe",
+            1,
+            cache_key,
+        ),
+    )
+    result = W4A16FusedMoeCompileResult(
+        compiled=compiled,
+        size_m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        top_k=top_k,
+        activation=activation,
+        apply_router_weight_on_input=bool(apply_router_weight_on_input),
+        zero_fc2_output=bool(zero_fc2_output),
+        element_dtype=element_dtype,
+        fast_math=bool(fast_math),
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        fc1_tile_n=fc1_tile_n,
+        fc1_tile_k=fc1_tile_k,
+        fc2_tile_n=fc2_tile_n,
+        fc2_tile_k=fc2_tile_k,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        blocks_per_sm=kernel.blocks_per_sm,
+        weight_layout=weight_layout,
+        w13_layout=w13_layout,
+        direct_topk_routes=kernel.direct_topk_routes,
+        scale_format=scale_format,
+        tc_decode_fused_sum=bool(tc_decode_fused_sum),
+        collect_activation_amax=collect_activation_amax,
+    )
+    _FUSED_CACHE[cache_key] = result
+    return result
+
+
+def clear_w4a16_kernel_cache() -> None:
+    _CACHE.clear()
+    _FUSED_CACHE.clear()
+    _ACTIVATION_CACHE.clear()
+    _SUM_CACHE.clear()
+    _SMALL_M_DIRECT_CACHE.clear()
+
+
+def compile_w4a16_activation(
+    *,
+    rows: int,
+    intermediate_size: int,
+    activation: str,
+    element_dtype: str = "bf16",
+    fast_math: bool = True,
+    swiglu_limit: float | None = None,
+    swiglu_alpha: float | None = None,
+    swiglu_beta: float | None = None,
+) -> W4A16ActivationCompileResult:
+    cutlass_dtype = _cutlass_element_dtype(element_dtype)
+    activation = normalize_moe_activation(activation)
+    is_gated = validate_activation(activation)
+    swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+        activation,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+    )
+    kernel = W4A16ActivationKernel(
+        rows=rows,
+        intermediate_size=intermediate_size,
+        activation=activation,
+        element_dtype=element_dtype,
+        fast_math=fast_math,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+    )
+    cache_key = (
+        "w4a16_activation",
+        kernel.__cache_key__,
+    )
+    cached = _ACTIVATION_CACHE.get(cache_key)
+    if cached is not None:
+        return replace(cached, rows=rows)
+
+    w13_shards = 2 if is_gated else 1
+    compile_rows = _fake_m_for_specialization(rows)
+    fc1_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_rows * w13_shards * intermediate_size,),
+        assumed_align=16,
+    )
+    activated_fake = cute.runtime.make_fake_compact_tensor(
+        cutlass_dtype,
+        (compile_rows * intermediate_size,),
+        assumed_align=16,
+    )
+    raise_if_kernel_resolution_frozen(
+        "cute.compile", target=kernel, cache_key=cache_key
+    )
+    compiled = b12x_compile(
+        kernel,
+        fc1_fake,
+        activated_fake,
+        Int32(compile_rows),
+        current_cuda_stream(),
+        compile_spec=KernelCompileSpec.from_key(
+            "moe.w4a16.activation",
+            1,
+            cache_key,
+        ),
+    )
+    result = W4A16ActivationCompileResult(
+        compiled=compiled,
+        rows=rows,
+        intermediate_size=intermediate_size,
+        activation=activation,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+    )
+    _ACTIVATION_CACHE[cache_key] = result
+    return result
+
+
+def compile_w4a16_topk_sum(
+    *,
+    m: int,
+    topk: int,
+    hidden_size: int,
+    element_dtype: str = "bf16",
+) -> W4A16TopKSumCompileResult:
+    cutlass_dtype = _cutlass_element_dtype(element_dtype)
+    cache_key = ("w4a16_topk_sum", element_dtype, topk, hidden_size)
+    cached = _SUM_CACHE.get(cache_key)
+    if cached is not None:
+        return cached
+
+    fc2_fake = make_ptr(cutlass_dtype, 16, cute.AddressSpace.gmem, assumed_align=16)
+    output_fake = make_ptr(cutlass_dtype, 16, cute.AddressSpace.gmem, assumed_align=16)
+    kernel = W4A16TopKSumKernel(
+        topk=topk,
+        hidden_size=hidden_size,
+        element_dtype=element_dtype,
+    )
+    raise_if_kernel_resolution_frozen(
+        "cute.compile", target=kernel, cache_key=cache_key
+    )
+    compiled = b12x_compile(
+        kernel,
+        fc2_fake,
+        output_fake,
+        1,
+        current_cuda_stream(),
+        compile_spec=KernelCompileSpec.from_key(
+            "moe.w4a16.topk_sum",
+            1,
+            cache_key,
+        ),
+    )
+    result = W4A16TopKSumCompileResult(
+        compiled=compiled,
+        m=0,
+        topk=topk,
+        hidden_size=hidden_size,
+    )
+    _SUM_CACHE[cache_key] = result
+    return result
+
+
+def _w4a16_small_m_direct_launch_flat(
+    a_input: torch.Tensor,
+    w13_u8: torch.Tensor,
+    w13_scale_u8: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    inter_u32: torch.Tensor,
+    w2_u8: torch.Tensor,
+    w2_scale_u8: torch.Tensor,
+    topk_ids: torch.Tensor,
+    topk_weights: torch.Tensor,
+    output: torch.Tensor,
+    barrier_count: torch.Tensor,
+    barrier_epoch: torch.Tensor,
+    m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    fast_math: bool,
+    scale_format: str,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    w13_layout: str,
+    stream_int: int,
+) -> None:
+    swiglu_limit = float(swiglu_limit_value) if has_swiglu_limit else None
+    direct_launch = _compile_w4a16_small_m_direct(
+        m=m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        topk=topk,
+        activation=activation,
+        fast_math=bool(fast_math),
+        topk_ids_dtype=topk_ids.dtype,
+        scale_format=scale_format,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        w13_layout=w13_layout,
+        device=a_input.device,
+    )
+
+    def ptr(dt, tensor: torch.Tensor):
+        return make_ptr(dt, tensor.data_ptr(), cute.AddressSpace.gmem, assumed_align=16)
+
+    ids_dtype = cutlass.Int64 if topk_ids.dtype == torch.int64 else cutlass.Int32
+    direct_launch.compiled(
+        ptr(cutlass.BFloat16, a_input),
+        ptr(cutlass.Uint8, w13_u8),
+        ptr(cutlass.Uint8, w13_scale_u8.view(torch.uint8)),
+        ptr(cutlass.Float32, w13_global_scale),
+        ptr(cutlass.Float32, w13_global_scale),
+        ptr(cutlass.Float32, w2_global_scale),
+        ptr(cutlass.Uint32, inter_u32.view(torch.uint32)),
+        ptr(cutlass.Uint8, w2_u8),
+        ptr(cutlass.Uint8, w2_scale_u8.view(torch.uint8)),
+        ptr(cutlass.Float32, w2_global_scale),
+        ptr(ids_dtype, topk_ids),
+        ptr(cutlass.Float32, topk_weights),
+        ptr(cutlass.BFloat16, output),
+        barrier_count,
+        barrier_epoch,
+        Int32(m),
+        Int32(direct_launch.grid_x),
+        cuda.CUstream(stream_int),
+    )
+
+
+@torch.library.custom_op(
+    "b12x::w4a16_small_m_direct_launch",
+    mutates_args="unknown",
+)
+def _w4a16_small_m_direct_launch_op(
+    a_input: torch.Tensor,
+    w13_u8: torch.Tensor,
+    w13_scale_u8: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    inter_u32: torch.Tensor,
+    w2_u8: torch.Tensor,
+    w2_scale_u8: torch.Tensor,
+    topk_ids: torch.Tensor,
+    topk_weights: torch.Tensor,
+    output: torch.Tensor,
+    barrier_count: torch.Tensor,
+    barrier_epoch: torch.Tensor,
+    m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    fast_math: bool,
+    scale_format: str,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    w13_layout: str,
+    stream_int: int,
+) -> None:
+    _w4a16_small_m_direct_launch_flat(
+        a_input=a_input,
+        w13_u8=w13_u8,
+        w13_scale_u8=w13_scale_u8,
+        w13_global_scale=w13_global_scale,
+        w2_global_scale=w2_global_scale,
+        inter_u32=inter_u32,
+        w2_u8=w2_u8,
+        w2_scale_u8=w2_scale_u8,
+        topk_ids=topk_ids,
+        topk_weights=topk_weights,
+        output=output,
+        barrier_count=barrier_count,
+        barrier_epoch=barrier_epoch,
+        m=m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        topk=topk,
+        activation=activation,
+        fast_math=fast_math,
+        scale_format=scale_format,
+        has_swiglu_limit=has_swiglu_limit,
+        swiglu_limit_value=swiglu_limit_value,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        w13_layout=w13_layout,
+        stream_int=stream_int,
+    )
+
+
+@_w4a16_small_m_direct_launch_op.register_fake
+def _w4a16_small_m_direct_launch_fake(
+    a_input: torch.Tensor,
+    w13_u8: torch.Tensor,
+    w13_scale_u8: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    inter_u32: torch.Tensor,
+    w2_u8: torch.Tensor,
+    w2_scale_u8: torch.Tensor,
+    topk_ids: torch.Tensor,
+    topk_weights: torch.Tensor,
+    output: torch.Tensor,
+    barrier_count: torch.Tensor,
+    barrier_epoch: torch.Tensor,
+    m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    fast_math: bool,
+    scale_format: str,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    w13_layout: str,
+    stream_int: int,
+) -> None:
+    return None
+
+
+def _w4a16_fused_moe_launch_flat(
+    a_input: torch.Tensor,
+    w13_arg: torch.Tensor,
+    w2_arg: torch.Tensor,
+    fc1_out: torch.Tensor,
+    activated: torch.Tensor,
+    fc2_out: torch.Tensor,
+    w13_scale_i32: torch.Tensor,
+    w2_scale_i32: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    packed_route_indices: torch.Tensor,
+    block_expert_ids: torch.Tensor,
+    packed_route_count: torch.Tensor,
+    activation_amax: torch.Tensor | None,
+    layer_idx: int,
+    topk_weights: torch.Tensor,
+    fc1_scratch: torch.Tensor,
+    fc2_scratch: torch.Tensor,
+    workspace: torch.Tensor,
+    m: int,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    fast_math: bool,
+    sms: int,
+    max_shared_mem: int,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    weight_layout: str,
+    scale_format: str,
+    w13_layout: str,
+    direct_topk_routes: bool,
+    tc_decode_fused_sum: bool,
+    collect_activation_amax: bool,
+    stream_int: int,
+) -> None:
+    swiglu_limit = float(swiglu_limit_value) if has_swiglu_limit else None
+    collect_activation_amax = bool(collect_activation_amax)
+    if collect_activation_amax and activation_amax is None:
+        raise ValueError("activation_amax is required for calibrated W4A16 launch")
+    activation_amax_arg = (
+        activation_amax.view(-1) if activation_amax is not None else w13_global_scale
+    )
+    fused = compile_w4a16_fused_moe(
+        size_m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        top_k=topk,
+        activation=activation,
+        apply_router_weight_on_input=bool(apply_router_weight_on_input),
+        zero_fc2_output=bool(zero_fc2_output),
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        fast_math=bool(fast_math),
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        weight_layout=weight_layout,
+        scale_format=scale_format,
+        w13_layout=w13_layout,
+        direct_topk_routes=bool(direct_topk_routes),
+        tc_decode_fused_sum=bool(tc_decode_fused_sum),
+        collect_activation_amax=collect_activation_amax,
+    )
+    fused.compiled(
+        make_ptr(
+            _cutlass_element_dtype(element_dtype),
+            a_input.data_ptr(),
+            cute.AddressSpace.gmem,
+            assumed_align=16,
+        ),
+        w13_arg,
+        w2_arg,
+        fc1_out,
+        activated,
+        fc2_out,
+        w13_scale_i32,
+        w2_scale_i32,
+        w13_global_scale,
+        w2_global_scale,
+        packed_route_indices,
+        block_expert_ids,
+        packed_route_count,
+        activation_amax_arg,
+        int(layer_idx),
+        make_ptr(
+            cutlass.Float32,
+            topk_weights.data_ptr(),
+            cute.AddressSpace.gmem,
+            assumed_align=4,
+        ),
+        fc1_scratch,
+        fc2_scratch,
+        workspace,
+        m,
+        _w4a16_fused_persistent_grid_x(
+            fused=fused,
+            m=m,
+            topk=topk,
+            intermediate_size=intermediate_size,
+            activation=activation,
+            direct_topk_routes=bool(direct_topk_routes),
+            sms=sms,
+        ),
+        cuda.CUstream(stream_int),
+    )
+
+
+def _w4a16_fused_persistent_grid_x(
+    *,
+    fused: W4A16FusedMoeCompileResult,
+    m: int,
+    topk: int,
+    intermediate_size: int,
+    activation: str,
+    direct_topk_routes: bool,
+    sms: int,
+) -> int:
+    """Right-size the persistent grid for the fused FC1+FC2 launch.
+
+    The default over-subscribes the cooperative grid (sms*blocks_per_sm CTAs)
+    and forces the larger GEMM into the cross-CTA split-K tail (lock-serialized
+    finalize + c_tmp gmem round-trip) whenever its mn-tile count exceeds the
+    grid. For the small-M direct-topk decode the host knows the exact FC1
+    mn-tile count, so pick the fewest full persistent waves that fit the
+    co-residency cap and set grid_x to that wave's tile count. Then every CTA
+    owns whole FC1 (and FC2, whose tile count is an integer multiple) mn-tiles
+    over the full K -- no split-K reduction, no lock traffic -- with fewer
+    grid-barrier participants, while staying <= the cap so the cooperative
+    barrier never deadlocks. Falls back to the default for the route-pack path
+    where the host cannot know route_blocks ahead of the launch.
+    """
+    cap = int(sms) * int(fused.blocks_per_sm)
+    if not direct_topk_routes or m <= 0:
+        return max(cap, 1)
+    is_gated = is_gated_moe_activation(activation)
+    fc1_cols = int(intermediate_size) * (2 if is_gated else 1)
+    fc1_tile_n = int(getattr(fused, "fc1_tile_n", 0))
+    if fc1_tile_n <= 0 or fc1_cols % fc1_tile_n != 0:
+        return max(cap, 1)
+    n_tiles = fc1_cols // fc1_tile_n
+    route_blocks = int(m) * int(topk)
+    fc1_mn_tiles = route_blocks * n_tiles
+    if fc1_mn_tiles <= 0 or cap <= 0:
+        return max(cap, 1)
+    waves = (fc1_mn_tiles + cap - 1) // cap
+    if waves <= 0:
+        return max(cap, 1)
+    # Only commit to the right-sized grid when every wave is a whole tile cover
+    # (no remainder => no split-K tail); otherwise keep the safe default.
+    if fc1_mn_tiles % waves != 0:
+        return max(cap, 1)
+    grid_x = fc1_mn_tiles // waves
+    if grid_x < 1 or grid_x > cap:
+        return max(cap, 1)
+    return grid_x
+
+
+@torch.library.custom_op(
+    "b12x::w4a16_fused_moe_launch",
+    mutates_args="unknown",
+)
+def _w4a16_fused_moe_launch_op(
+    a_input: torch.Tensor,
+    w13_arg: torch.Tensor,
+    w2_arg: torch.Tensor,
+    fc1_out: torch.Tensor,
+    activated: torch.Tensor,
+    fc2_out: torch.Tensor,
+    w13_scale_i32: torch.Tensor,
+    w2_scale_i32: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    packed_route_indices: torch.Tensor,
+    block_expert_ids: torch.Tensor,
+    packed_route_count: torch.Tensor,
+    topk_weights: torch.Tensor,
+    fc1_scratch: torch.Tensor,
+    fc2_scratch: torch.Tensor,
+    workspace: torch.Tensor,
+    m: int,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    fast_math: bool,
+    sms: int,
+    max_shared_mem: int,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    weight_layout: str,
+    scale_format: str,
+    w13_layout: str,
+    direct_topk_routes: bool,
+    tc_decode_fused_sum: bool,
+    stream_int: int,
+) -> None:
+    _w4a16_fused_moe_launch_flat(
+        a_input=a_input,
+        w13_arg=w13_arg,
+        w2_arg=w2_arg,
+        fc1_out=fc1_out,
+        activated=activated,
+        fc2_out=fc2_out,
+        w13_scale_i32=w13_scale_i32,
+        w2_scale_i32=w2_scale_i32,
+        w13_global_scale=w13_global_scale,
+        w2_global_scale=w2_global_scale,
+        packed_route_indices=packed_route_indices,
+        block_expert_ids=block_expert_ids,
+        packed_route_count=packed_route_count,
+        activation_amax=None,
+        layer_idx=0,
+        topk_weights=topk_weights,
+        fc1_scratch=fc1_scratch,
+        fc2_scratch=fc2_scratch,
+        workspace=workspace,
+        m=m,
+        size_m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        topk=topk,
+        activation=activation,
+        apply_router_weight_on_input=apply_router_weight_on_input,
+        zero_fc2_output=zero_fc2_output,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        fast_math=fast_math,
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        has_swiglu_limit=has_swiglu_limit,
+        swiglu_limit_value=swiglu_limit_value,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        weight_layout=weight_layout,
+        scale_format=scale_format,
+        w13_layout=w13_layout,
+        direct_topk_routes=direct_topk_routes,
+        tc_decode_fused_sum=tc_decode_fused_sum,
+        collect_activation_amax=False,
+        stream_int=stream_int,
+    )
+
+
+@_w4a16_fused_moe_launch_op.register_fake
+def _w4a16_fused_moe_launch_fake(
+    a_input: torch.Tensor,
+    w13_arg: torch.Tensor,
+    w2_arg: torch.Tensor,
+    fc1_out: torch.Tensor,
+    activated: torch.Tensor,
+    fc2_out: torch.Tensor,
+    w13_scale_i32: torch.Tensor,
+    w2_scale_i32: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    packed_route_indices: torch.Tensor,
+    block_expert_ids: torch.Tensor,
+    packed_route_count: torch.Tensor,
+    topk_weights: torch.Tensor,
+    fc1_scratch: torch.Tensor,
+    fc2_scratch: torch.Tensor,
+    workspace: torch.Tensor,
+    m: int,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    fast_math: bool,
+    sms: int,
+    max_shared_mem: int,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    weight_layout: str,
+    scale_format: str,
+    w13_layout: str,
+    direct_topk_routes: bool,
+    tc_decode_fused_sum: bool,
+    stream_int: int,
+) -> None:
+    return None
+
+
+@torch.library.custom_op(
+    "b12x::w4a16_fused_moe_calibrated_launch",
+    mutates_args="unknown",
+)
+def _w4a16_fused_moe_calibrated_launch_op(
+    a_input: torch.Tensor,
+    w13_arg: torch.Tensor,
+    w2_arg: torch.Tensor,
+    fc1_out: torch.Tensor,
+    activated: torch.Tensor,
+    fc2_out: torch.Tensor,
+    w13_scale_i32: torch.Tensor,
+    w2_scale_i32: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    packed_route_indices: torch.Tensor,
+    block_expert_ids: torch.Tensor,
+    packed_route_count: torch.Tensor,
+    activation_amax: torch.Tensor,
+    layer_idx: int,
+    topk_weights: torch.Tensor,
+    fc1_scratch: torch.Tensor,
+    fc2_scratch: torch.Tensor,
+    workspace: torch.Tensor,
+    m: int,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    fast_math: bool,
+    sms: int,
+    max_shared_mem: int,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    weight_layout: str,
+    scale_format: str,
+    w13_layout: str,
+    stream_int: int,
+) -> None:
+    _w4a16_fused_moe_launch_flat(
+        a_input=a_input,
+        w13_arg=w13_arg,
+        w2_arg=w2_arg,
+        fc1_out=fc1_out,
+        activated=activated,
+        fc2_out=fc2_out,
+        w13_scale_i32=w13_scale_i32,
+        w2_scale_i32=w2_scale_i32,
+        w13_global_scale=w13_global_scale,
+        w2_global_scale=w2_global_scale,
+        packed_route_indices=packed_route_indices,
+        block_expert_ids=block_expert_ids,
+        packed_route_count=packed_route_count,
+        activation_amax=activation_amax,
+        layer_idx=layer_idx,
+        topk_weights=topk_weights,
+        fc1_scratch=fc1_scratch,
+        fc2_scratch=fc2_scratch,
+        workspace=workspace,
+        m=m,
+        size_m=size_m,
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        topk=topk,
+        activation=activation,
+        apply_router_weight_on_input=apply_router_weight_on_input,
+        zero_fc2_output=zero_fc2_output,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        fast_math=fast_math,
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        has_swiglu_limit=has_swiglu_limit,
+        swiglu_limit_value=swiglu_limit_value,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        weight_layout=weight_layout,
+        scale_format=scale_format,
+        w13_layout=w13_layout,
+        direct_topk_routes=False,
+        tc_decode_fused_sum=False,
+        collect_activation_amax=True,
+        stream_int=stream_int,
+    )
+
+
+@_w4a16_fused_moe_calibrated_launch_op.register_fake
+def _w4a16_fused_moe_calibrated_launch_fake(
+    a_input: torch.Tensor,
+    w13_arg: torch.Tensor,
+    w2_arg: torch.Tensor,
+    fc1_out: torch.Tensor,
+    activated: torch.Tensor,
+    fc2_out: torch.Tensor,
+    w13_scale_i32: torch.Tensor,
+    w2_scale_i32: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    packed_route_indices: torch.Tensor,
+    block_expert_ids: torch.Tensor,
+    packed_route_count: torch.Tensor,
+    activation_amax: torch.Tensor,
+    layer_idx: int,
+    topk_weights: torch.Tensor,
+    fc1_scratch: torch.Tensor,
+    fc2_scratch: torch.Tensor,
+    workspace: torch.Tensor,
+    m: int,
+    size_m: int,
+    hidden_size: int,
+    intermediate_size: int,
+    num_experts: int,
+    topk: int,
+    activation: str,
+    apply_router_weight_on_input: bool,
+    zero_fc2_output: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    fast_math: bool,
+    sms: int,
+    max_shared_mem: int,
+    has_swiglu_limit: bool,
+    swiglu_limit_value: float,
+    swiglu_alpha: float,
+    swiglu_beta: float,
+    weight_layout: str,
+    scale_format: str,
+    w13_layout: str,
+    stream_int: int,
+) -> None:
+    return None
+
+
+def _w4a16_topk_sum_launch_flat(
+    fc2_out: torch.Tensor,
+    output: torch.Tensor,
+    m: int,
+    topk: int,
+    hidden_size: int,
+    element_dtype: str,
+    stream_int: int,
+) -> None:
+    sum_kernel = compile_w4a16_topk_sum(
+        m=m,
+        topk=topk,
+        hidden_size=hidden_size,
+        element_dtype=element_dtype,
+    )
+    sum_kernel.compiled(
+        make_ptr(
+            _cutlass_element_dtype(element_dtype),
+            fc2_out.data_ptr(),
+            cute.AddressSpace.gmem,
+            assumed_align=16,
+        ),
+        make_ptr(
+            _cutlass_element_dtype(element_dtype),
+            output.data_ptr(),
+            cute.AddressSpace.gmem,
+            assumed_align=16,
+        ),
+        m,
+        cuda.CUstream(stream_int),
+    )
+
+
+@torch.library.custom_op(
+    "b12x::w4a16_topk_sum_launch",
+    mutates_args=("output",),
+)
+def _w4a16_topk_sum_launch_op(
+    fc2_out: torch.Tensor,
+    output: torch.Tensor,
+    m: int,
+    topk: int,
+    hidden_size: int,
+    element_dtype: str,
+    stream_int: int,
+) -> None:
+    _w4a16_topk_sum_launch_flat(
+        fc2_out=fc2_out,
+        output=output,
+        m=m,
+        topk=topk,
+        hidden_size=hidden_size,
+        element_dtype=element_dtype,
+        stream_int=stream_int,
+    )
+
+
+@_w4a16_topk_sum_launch_op.register_fake
+def _w4a16_topk_sum_launch_fake(
+    fc2_out: torch.Tensor,
+    output: torch.Tensor,
+    m: int,
+    topk: int,
+    hidden_size: int,
+    element_dtype: str,
+    stream_int: int,
+) -> None:
+    return None
+
+
+def _get_c_tmp(
+    elements: int,
+    *,
+    device: torch.device,
+    scratch: torch.Tensor | None = None,
+) -> torch.Tensor:
+    if scratch is not None:
+        if scratch.dtype != torch.float32:
+            raise TypeError("W4A16 c_tmp scratch buffers must be torch.float32")
+        if scratch.device != device:
+            raise ValueError(f"W4A16 c_tmp scratch buffers must be on {device}")
+        if not scratch.is_contiguous():
+            raise ValueError("W4A16 c_tmp scratch buffers must be contiguous")
+        if int(scratch.numel()) >= int(elements):
+            return scratch[: int(elements)]
+    if torch.cuda.is_current_stream_capturing():
+        raise RuntimeError(
+            "W4A16 GEMM scratch is not initialized for CUDA graph capture; "
+            "provide a preallocated fc*_c_tmp workspace with sufficient capacity"
+        )
+    return torch.empty((elements,), dtype=torch.float32, device=device)
+
+
+def _validate_topk_ids(
+    topk_ids: torch.Tensor,
+    *,
+    require_cuda: bool,
+    require_contiguous: bool = True,
+) -> None:
+    if topk_ids.dtype not in (torch.int32, torch.int64):
+        raise TypeError("topk_ids must be torch.int32 or torch.int64")
+    if require_cuda and not topk_ids.is_cuda:
+        raise ValueError("topk_ids must be a CUDA tensor")
+    if require_contiguous and not topk_ids.is_contiguous():
+        raise ValueError("topk_ids must be contiguous")
+
+
+def _validate_expert_map(
+    expert_map: torch.Tensor | None,
+    *,
+    device: torch.device | None = None,
+    exact_num_experts: int | None = None,
+) -> None:
+    if expert_map is None:
+        return
+    if expert_map.dtype != torch.int32:
+        raise TypeError("expert_map must be torch.int32")
+    if device is None:
+        if not expert_map.is_cuda:
+            raise ValueError("expert_map must be a CUDA tensor")
+    elif expert_map.device != device:
+        raise ValueError("expert_map must be on the same device as a_input")
+    if exact_num_experts is None:
+        if expert_map.ndim != 1 or not expert_map.is_contiguous():
+            raise ValueError("expert_map must be a contiguous rank-1 tensor")
+        return
+    if not expert_map.is_contiguous():
+        raise ValueError("expert_map must be contiguous")
+    if expert_map.ndim != 1 or int(expert_map.numel()) != int(exact_num_experts):
+        raise ValueError(
+            f"expert_map must have shape {(int(exact_num_experts),)}, got {tuple(expert_map.shape)}"
+        )
+
+
+def _validate_activation_amax(
+    activation_amax: torch.Tensor | None,
+    *,
+    layer_idx: int | None,
+    num_experts: int,
+    device: torch.device,
+) -> int | None:
+    if activation_amax is None:
+        if layer_idx is not None:
+            raise ValueError("layer_idx requires activation_amax")
+        return None
+    if layer_idx is None:
+        raise ValueError("layer_idx is required when activation_amax is provided")
+    if activation_amax.dtype != torch.float32:
+        raise TypeError("activation_amax must be torch.float32")
+    if activation_amax.device != device:
+        raise ValueError("activation_amax must be on the same device as a_input")
+    if not activation_amax.is_cuda:
+        raise ValueError("activation_amax must be a CUDA tensor")
+    if not activation_amax.is_contiguous():
+        raise ValueError("activation_amax must be contiguous")
+    if activation_amax.ndim != 3 or int(activation_amax.shape[2]) != 2:
+        raise ValueError(
+            "activation_amax must have shape [num_layers, num_experts, 2]"
+        )
+    if int(activation_amax.shape[1]) < int(num_experts):
+        raise ValueError(
+            "activation_amax expert dimension is smaller than the local expert count"
+        )
+    layer = int(layer_idx)
+    if layer < 0 or layer >= int(activation_amax.shape[0]):
+        raise ValueError(
+            f"layer_idx {layer} is out of bounds for activation_amax with "
+            f"{int(activation_amax.shape[0])} layers"
+        )
+    return layer
+
+
+def _compile_w4a16_gemm_launch(
+    *,
+    size_m: int,
+    size_n: int,
+    size_k: int,
+    num_experts: int,
+    top_k: int,
+    mul_topk_weights: bool,
+    moe_block_size: int,
+    max_m_blocks: int,
+    element_dtype: str,
+    packed_route_indices: torch.Tensor,
+    sms: int,
+    max_shared_mem: int,
+    device: torch.device,
+    c_tmp: torch.Tensor | None = None,
+    scale_format: str = "e4m3_k16",
+) -> _W4A16GemmLaunch:
+    tile_k, tile_n, _, _ = _select_tile_config(
+        problem_m=size_m,
+        problem_n=size_n,
+        problem_k=size_k,
+        top_k=top_k,
+        moe_block_size=moe_block_size,
+        sms=sms,
+        max_shared_mem=max_shared_mem,
+        scale_format=scale_format,
+    )
+    kernel = compile_w4a16_gemm(
+        size_m=size_m,
+        size_n=size_n,
+        size_k=size_k,
+        num_experts=num_experts,
+        top_k=top_k,
+        mul_topk_weights=mul_topk_weights,
+        tile_n=tile_n,
+        tile_k=tile_k,
+        moe_block_size=moe_block_size,
+        max_m_blocks=max_m_blocks,
+        element_dtype=element_dtype,
+        scale_format=scale_format,
+    )
+    c_tmp = _get_c_tmp(
+        packed_gemm_scratch_elements(
+            size_n=size_n,
+            route_slots=int(packed_route_indices.numel()),
+            moe_block_size=moe_block_size,
+            sms=sms,
+        ),
+        device=device,
+        scratch=c_tmp,
+    )
+    return _W4A16GemmLaunch(kernel=kernel, c_tmp=c_tmp)
+
+
+def pack_topk_routes_by_expert(
+    topk_ids: torch.Tensor,
+    block_size: int,
+    num_experts: int,
+    *,
+    expert_map: torch.Tensor | None = None,
+    packed_route_indices: torch.Tensor | None = None,
+    block_expert_ids: torch.Tensor | None = None,
+    packed_route_count: torch.Tensor | None = None,
+    expert_offsets: torch.Tensor | None = None,
+    stream: cuda.CUstream | None = None,
+) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
+    """Group top-k routes by expert and pad each group to the GEMM M-block size."""
+    _validate_topk_ids(topk_ids, require_cuda=True)
+    if block_size <= 0:
+        raise ValueError(f"block_size must be positive, got {block_size}")
+    if num_experts <= 0:
+        raise ValueError(f"num_experts must be positive, got {num_experts}")
+    _validate_expert_map(expert_map, exact_num_experts=int(num_experts))
+    del stream
+    return _pack_topk_routes_by_expert(
+        topk_ids,
+        int(block_size),
+        int(num_experts),
+        expert_map=expert_map,
+        packed_route_indices=packed_route_indices,
+        block_expert_ids=block_expert_ids,
+        packed_route_count=packed_route_count,
+        expert_offsets=expert_offsets,
+    )
+
+
+def run_w4a16_moe(
+    a_input: torch.Tensor,
+    prepared,
+    topk_weights: torch.Tensor,
+    topk_ids: torch.Tensor,
+    *,
+    activation: str,
+    intermediate_cache13: torch.Tensor,
+    intermediate_cache2: torch.Tensor,
+    output: torch.Tensor,
+    fc1_c_tmp: torch.Tensor | None = None,
+    fc2_c_tmp: torch.Tensor | None = None,
+    packed_route_indices: torch.Tensor | None = None,
+    block_expert_ids: torch.Tensor | None = None,
+    packed_route_count: torch.Tensor | None = None,
+    expert_offsets: torch.Tensor | None = None,
+    expert_map: torch.Tensor | None = None,
+    activation_amax: torch.Tensor | None = None,
+    layer_idx: int | None = None,
+    apply_router_weight_on_input: bool = False,
+    fast_math: bool = True,
+    swiglu_limit: float | None = None,
+    swiglu_alpha: float | None = None,
+    swiglu_beta: float | None = None,
+    fused_launch: W4A16FusedMoeCompileResult | None = None,
+    topk_sum_launch: W4A16TopKSumCompileResult | None = None,
+    stream: cuda.CUstream | None = None,
+) -> torch.Tensor:
+    activation = normalize_moe_activation(activation)
+    is_gated = validate_activation(activation)
+    swiglu_limit, swiglu_alpha, swiglu_beta = _normalize_activation_swiglu_params(
+        activation,
+        swiglu_limit,
+        swiglu_alpha,
+        swiglu_beta,
+    )
+    element_dtype = _normalize_element_dtype(a_input.dtype)
+    if output.dtype != a_input.dtype:
+        raise TypeError(f"output must have dtype {a_input.dtype}, got {output.dtype}")
+    prepared_dtype = getattr(prepared, "params_dtype", a_input.dtype)
+    if prepared_dtype != a_input.dtype:
+        raise TypeError(
+            f"prepared weights were built for {prepared_dtype}, but a_input has dtype {a_input.dtype}"
+        )
+    weight_layout = getattr(prepared, "weight_layout", "packed")
+    if weight_layout not in _WEIGHT_LAYOUTS:
+        raise ValueError(f"unsupported W4A16 weight_layout {weight_layout!r}")
+    scale_format = _normalize_scale_format(
+        getattr(prepared, "scale_format", None)
+        or (
+            "e8m0_k32"
+            if getattr(prepared, "source_format", "") == "fp4_e8m0_k32"
+            else "e4m3_k16"
+        )
+    )
+    w13_layout = getattr(
+        prepared,
+        "w13_layout",
+        "w13" if weight_layout == "modelopt" else "packed",
+    )
+    if weight_layout == "modelopt":
+        if w13_layout not in _MODEL_OPT_W13_LAYOUTS:
+            raise ValueError(f"unsupported W4A16 w13_layout {w13_layout!r}")
+    else:
+        w13_layout = "packed"
+    if topk_weights.dtype != torch.float32:
+        raise TypeError("topk_weights must be torch.float32")
+    _validate_topk_ids(topk_ids, require_cuda=False, require_contiguous=False)
+    if (
+        not a_input.is_contiguous()
+        or not topk_weights.is_contiguous()
+        or not topk_ids.is_contiguous()
+    ):
+        raise ValueError("a_input, topk_weights, and topk_ids must be contiguous")
+    _validate_expert_map(expert_map, device=a_input.device)
+
+    m, hidden_size = a_input.shape
+    topk = int(topk_ids.shape[1])
+    if tuple(topk_weights.shape) != (m, topk):
+        raise ValueError(f"topk_weights must have shape {(m, topk)}")
+    if int(prepared.hidden_size) != hidden_size:
+        raise ValueError("prepared hidden_size does not match a_input")
+    if bool(prepared.is_gated) != is_gated:
+        raise ValueError("prepared weights do not match activation")
+    if tuple(output.shape) != (m, hidden_size):
+        raise ValueError(f"output must have shape {(m, hidden_size)}")
+    if expert_map is not None and int(expert_map.numel()) < int(prepared.num_experts):
+        raise ValueError("expert_map cannot be shorter than the local expert count")
+    layer_idx_int = _validate_activation_amax(
+        activation_amax,
+        layer_idx=layer_idx,
+        num_experts=int(prepared.num_experts),
+        device=a_input.device,
+    )
+    collect_activation_amax = activation_amax is not None
+
+    route_num_experts = (
+        int(expert_map.numel()) if expert_map is not None else int(prepared.num_experts)
+    )
+    if fused_launch is None:
+        block_size_m = select_route_block_size_m(m, topk, route_num_experts)
+    else:
+        block_size_m = int(fused_launch.moe_block_size)
+    if block_size_m not in _ALLOWED_ROUTED_SIZES:
+        raise ValueError(f"unsupported W4A16 moe_block_size={block_size_m}")
+
+    stream = current_cuda_stream() if stream is None else stream
+    if (not collect_activation_amax) and _small_m_direct_supported(
+        m=m,
+        hidden_size=hidden_size,
+        intermediate_size=int(prepared.intermediate_size),
+        num_experts=int(prepared.num_experts),
+        topk=topk,
+        activation=activation,
+        apply_router_weight_on_input=bool(apply_router_weight_on_input),
+        swiglu_limit=swiglu_limit,
+        swiglu_alpha=swiglu_alpha,
+        swiglu_beta=swiglu_beta,
+        element_dtype=element_dtype,
+        weight_layout=weight_layout,
+        w13_layout=w13_layout,
+        scale_format=scale_format,
+        expert_map=expert_map,
+    ):
+        if topk_ids.dtype not in (torch.int32, torch.int64):
+            raise TypeError("W4A16 small-M direct path requires int32/int64 topk_ids")
+        if not topk_ids.is_cuda:
+            raise ValueError("W4A16 small-M direct path requires CUDA topk_ids")
+        if not intermediate_cache2.is_contiguous() or not output.is_contiguous():
+            raise ValueError(
+                "W4A16 small-M direct path requires contiguous intermediate_cache2 and output"
+            )
+        if intermediate_cache2.dtype != a_input.dtype:
+            raise TypeError(f"intermediate_cache2 must be {a_input.dtype}")
+        if int(prepared.workspace.numel()) < 2:
+            raise ValueError("prepared W4A16 workspace is too small for small-M direct")
+        intermediate_size = int(prepared.intermediate_size)
+        fc2_n_chunks = ((intermediate_size // 2) + 127) // 128
+        inter_u32_per_m = fc2_n_chunks * 128 * topk
+        inter_u32 = intermediate_cache2.view(-1).view(torch.uint32)
+        if int(inter_u32.numel()) < m * inter_u32_per_m:
+            raise ValueError(
+                "intermediate_cache2 is smaller than the W4A16 small-M direct scratch "
+                f"requirement: have_u32={int(inter_u32.numel())}, "
+                f"need_u32={m * inter_u32_per_m}"
+            )
+        micro_w13_scale = getattr(prepared, "micro_w13_scale", None)
+        micro_w2_scale = getattr(prepared, "micro_w2_scale", None)
+        micro_w13_global = getattr(prepared, "micro_w13_global_scale", None)
+        micro_w2_global = getattr(prepared, "micro_w2_global_scale", None)
+        if (
+            micro_w13_scale is None
+            or micro_w2_scale is None
+            or micro_w13_global is None
+            or micro_w2_global is None
+        ):
+            raise RuntimeError(
+                "W4A16 small-M direct path requires prepared micro scale metadata"
+            )
+        barrier_count = prepared.workspace[-2:-1]
+        barrier_epoch = prepared.workspace[-1:]
+        barrier_count.zero_()
+        barrier_epoch.zero_()
+        torch.ops.b12x.w4a16_small_m_direct_launch(
+            a_input,
+            prepared.w13.view(torch.uint8),
+            micro_w13_scale,
+            micro_w13_global,
+            micro_w2_global,
+            inter_u32[: m * inter_u32_per_m],
+            prepared.w2.view(torch.uint8),
+            micro_w2_scale,
+            topk_ids,
+            topk_weights,
+            output,
+            barrier_count,
+            barrier_epoch,
+            m,
+            hidden_size,
+            intermediate_size,
+            int(prepared.num_experts),
+            topk,
+            activation,
+            bool(fast_math),
+            scale_format,
+            swiglu_limit is not None,
+            float(swiglu_limit or 0.0),
+            float(swiglu_alpha),
+            float(swiglu_beta),
+            w13_layout,
+            int(stream),
+        )
+        return output
+
+    # TC-decode: small-M packed decode that folds the top-k sum into the FC2
+    # store epilogue. Reuses the packed tensor-core MMA path; only the launch
+    # scheduling/epilogue changes. Requires the packed object, bf16 gated
+    # activation, int32 routes, no expert_map, and a runtime-compiled launch.
+    # A preplanned launch built with the TC-decode fused-sum epilogue carries
+    # ``tc_decode_fused_sum``; accept it through the binding path. A runtime
+    # ``fused_launch is None`` (e.g. the standalone benchmark) compiles its own.
+    preplanned_tc_decode = bool(getattr(fused_launch, "tc_decode_fused_sum", False))
+    use_tc_decode = bool(
+        (not collect_activation_amax)
+        and (fused_launch is None or preplanned_tc_decode)
+        and weight_layout in ("packed", "nf3_2p1")
+        and expert_map is None
+        and is_gated
+        and element_dtype == "bf16"
+        and topk_ids.dtype in (torch.int32, torch.int64)
+        and topk_ids.is_cuda
+        and int(m) <= _TC_DECODE_MAX_M
+    )
+    if use_tc_decode and topk_ids.dtype != torch.int32:
+        # The inline direct-topk route path needs int32 route indices.
+        topk_ids = topk_ids.to(torch.int32)
+
+    direct_topk_eligible = (
+        (not collect_activation_amax)
+        and (m <= _MAX_DIRECT_TOPK_ROUTE_M or use_tc_decode)
+        and weight_layout in ("packed", "nf3_2p1")
+        and expert_map is None
+    )
+    use_direct_topk_routes = bool(
+        direct_topk_eligible
+        and topk_ids.dtype == torch.int32
+        and (
+            fused_launch is None
+            or bool(getattr(fused_launch, "direct_topk_routes", False))
+        )
+    )
+    if (
+        bool(getattr(fused_launch, "direct_topk_routes", False))
+        and not use_direct_topk_routes
+    ):
+        raise RuntimeError(
+            "preplanned W4A16 direct top-k routing requires small-M packed "
+            "int32 topk_ids without expert_map"
+        )
+
+    # TC-decode requires the inline direct-topk route path (no route-pack).
+    use_tc_decode = bool(use_tc_decode and use_direct_topk_routes)
+
+    # A preplanned TC-decode launch atomically accumulates FC2 partials into the
+    # (pre-zeroed) output and emits no separate top-k sum. If it was selected but
+    # the decode preconditions don't hold, running it would corrupt the output,
+    # so fail loudly instead.
+    if preplanned_tc_decode and not use_tc_decode:
+        raise RuntimeError(
+            "preplanned TC-decode W4A16 launch requires small-M packed bf16 "
+            f"decode (m <= {_TC_DECODE_MAX_M}, cuda int32/int64 topk_ids, "
+            "no expert_map)"
+        )
+
+    route_slots_for_scratch = int(m) * int(topk) * int(block_size_m)
+    required_m_blocks = int(m) * int(topk) if use_direct_topk_routes else 0
+    if fused_launch is not None and not use_direct_topk_routes:
+        route_slots_capacity = max_packed_route_slots(
+            int(fused_launch.size_m) * int(topk),
+            int(block_size_m),
+            route_num_experts,
+        )
+        route_blocks_capacity = (route_slots_capacity + int(block_size_m) - 1) // int(
+            block_size_m
+        )
+        if packed_route_indices is not None:
+            if int(packed_route_indices.numel()) < route_slots_capacity:
+                raise ValueError(
+                    "packed_route_indices is smaller than the selected W4A16 launch capacity"
+                )
+            packed_route_indices = packed_route_indices[:route_slots_capacity]
+        if block_expert_ids is not None:
+            if int(block_expert_ids.numel()) < route_blocks_capacity:
+                raise ValueError(
+                    "block_expert_ids is smaller than the selected W4A16 launch capacity"
+                )
+            block_expert_ids = block_expert_ids[:route_blocks_capacity]
+    if use_direct_topk_routes:
+        packed_route_indices = topk_ids.view(-1)
+        if block_expert_ids is None:
+            block_expert_ids = packed_route_indices
+        if packed_route_count is None:
+            packed_route_count = packed_route_indices
+    else:
+        packed_route_indices, block_expert_ids, packed_route_count = (
+            pack_topk_routes_by_expert(
+                topk_ids,
+                block_size_m,
+                route_num_experts,
+                expert_map=expert_map,
+                packed_route_indices=packed_route_indices,
+                block_expert_ids=block_expert_ids,
+                packed_route_count=packed_route_count,
+                expert_offsets=expert_offsets,
+                stream=stream,
+            )
+        )
+        route_slots_for_scratch = int(packed_route_indices.numel())
+        required_m_blocks = int(block_expert_ids.numel())
+
+    props = torch.cuda.get_device_properties(a_input.device)
+    sms = int(props.multi_processor_count)
+    max_shared_mem = int(
+        getattr(props, "shared_memory_per_block_optin", _DEFAULT_MAX_SHARED_MEM)
+    )
+    buffer_plan = plan_w4a16_buffers(
+        prepared,
+        m=m,
+        topk=topk,
+        route_num_experts=route_num_experts,
+        sms=sms,
+    )
+    intermediate_size = int(prepared.intermediate_size)
+    fc1_cols = buffer_plan.fc1_cols
+
+    if intermediate_cache13.numel() < buffer_plan.intermediate_cache13_elements:
+        raise ValueError(
+            f"intermediate_cache13 has {intermediate_cache13.numel()} elements; "
+            f"need at least {buffer_plan.intermediate_cache13_elements}"
+        )
+    if intermediate_cache2.numel() < buffer_plan.intermediate_cache2_elements:
+        raise ValueError(
+            f"intermediate_cache2 has {intermediate_cache2.numel()} elements; "
+            f"need at least {buffer_plan.intermediate_cache2_elements}"
+        )
+    if (
+        intermediate_cache13.dtype != a_input.dtype
+        or intermediate_cache2.dtype != a_input.dtype
+    ):
+        raise TypeError(f"intermediate caches must be {a_input.dtype}")
+    if (
+        not intermediate_cache13.is_contiguous()
+        or not intermediate_cache2.is_contiguous()
+        or not output.is_contiguous()
+    ):
+        raise ValueError("intermediate caches and output must be contiguous")
+
+    intermediate_cache13_flat = intermediate_cache13.view(-1)
+    intermediate_cache2_flat = intermediate_cache2.view(-1)
+
+    if int(prepared.workspace.numel()) < sms * 4 + 2:
+        raise ValueError("prepared W4A16 workspace is too small for fused FC1+FC2")
+    if fused_launch is None:
+        fused = compile_w4a16_fused_moe(
+            size_m=m,
+            hidden_size=hidden_size,
+            intermediate_size=intermediate_size,
+            num_experts=int(prepared.num_experts),
+            top_k=topk,
+            activation=activation,
+            apply_router_weight_on_input=bool(apply_router_weight_on_input),
+            zero_fc2_output=expert_map is not None,
+            moe_block_size=block_size_m,
+            max_m_blocks=int(required_m_blocks),
+            element_dtype=element_dtype,
+            fast_math=bool(fast_math),
+            sms=sms,
+            max_shared_mem=max_shared_mem,
+            swiglu_limit=swiglu_limit,
+            swiglu_alpha=swiglu_alpha,
+            swiglu_beta=swiglu_beta,
+            weight_layout=weight_layout,
+            scale_format=scale_format,
+            w13_layout=w13_layout,
+            direct_topk_routes=use_direct_topk_routes,
+            tc_decode_fused_sum=use_tc_decode,
+            collect_activation_amax=collect_activation_amax,
+        )
+    else:
+        if int(fused_launch.size_m) < m:
+            raise RuntimeError(
+                "preplanned W4A16 fused MoE launch capacity is smaller than requested rows: "
+                f"requested={m}, planned={int(fused_launch.size_m)}"
+            )
+        expected_fused = (
+            hidden_size,
+            intermediate_size,
+            int(prepared.num_experts),
+            topk,
+            activation,
+            bool(apply_router_weight_on_input),
+            expert_map is not None,
+            element_dtype,
+            bool(fast_math),
+            swiglu_limit,
+            float(swiglu_alpha),
+            float(swiglu_beta),
+            weight_layout,
+            scale_format,
+            w13_layout,
+            bool(use_direct_topk_routes),
+            bool(collect_activation_amax),
+            block_size_m,
+        )
+        actual_fused = (
+            int(fused_launch.hidden_size),
+            int(fused_launch.intermediate_size),
+            int(fused_launch.num_experts),
+            int(fused_launch.top_k),
+            fused_launch.activation,
+            bool(fused_launch.apply_router_weight_on_input),
+            bool(fused_launch.zero_fc2_output),
+            fused_launch.element_dtype,
+            bool(fused_launch.fast_math),
+            fused_launch.swiglu_limit,
+            float(fused_launch.swiglu_alpha),
+            float(fused_launch.swiglu_beta),
+            getattr(fused_launch, "weight_layout", "packed"),
+            getattr(fused_launch, "scale_format", "e4m3_k16"),
+            getattr(
+                fused_launch,
+                "w13_layout",
+                "w13"
+                if getattr(fused_launch, "weight_layout", "packed") == "modelopt"
+                else "packed",
+            ),
+            bool(getattr(fused_launch, "direct_topk_routes", False)),
+            bool(getattr(fused_launch, "collect_activation_amax", False)),
+            int(fused_launch.moe_block_size),
+        )
+        if actual_fused != expected_fused or int(fused_launch.max_m_blocks) < int(
+            required_m_blocks
+        ):
+            raise RuntimeError(
+                "preplanned W4A16 fused MoE launch does not match requested contract: "
+                f"requested={expected_fused + (int(required_m_blocks),)}, "
+                f"planned={actual_fused + (int(fused_launch.max_m_blocks),)}"
+            )
+        fused = fused_launch
+    capacity_m = int(fused.size_m)
+    capacity_routed_rows = capacity_m * topk
+    if intermediate_cache13_flat.numel() < capacity_routed_rows * max(fc1_cols, hidden_size):
+        raise ValueError(
+            "intermediate_cache13 is smaller than the selected W4A16 launch capacity: "
+            f"capacity_rows={capacity_m}, topk={topk}"
+        )
+    if intermediate_cache2_flat.numel() < capacity_routed_rows * intermediate_size:
+        raise ValueError(
+            "intermediate_cache2 is smaller than the selected W4A16 launch capacity: "
+            f"capacity_rows={capacity_m}, topk={topk}"
+        )
+    fc1_out = intermediate_cache13_flat[: capacity_routed_rows * fc1_cols]
+    activated = intermediate_cache2_flat[: capacity_routed_rows * intermediate_size]
+    if use_tc_decode:
+        # FC2 atomically accumulates per-route partials directly into the
+        # per-token output, so the output is the FC2 store target and must be
+        # pre-zeroed. The fused tc_decode kernel now zeroes the output in its
+        # own prologue (before FC1, made visible by the existing post-FC1 grid
+        # barrier), so the separate host-side output.zero_() launch is removed
+        # from the decode critical path here. This drops the separate top-k-sum
+        # launch as well.
+        fc2_out = output.view(-1)
+    else:
+        fc2_out = intermediate_cache13_flat[: capacity_routed_rows * hidden_size]
+    fc1_scratch = _get_c_tmp(
+        packed_gemm_scratch_elements(
+            size_n=fc1_cols,
+            route_slots=int(route_slots_for_scratch),
+            moe_block_size=block_size_m,
+            sms=sms,
+        ),
+        device=a_input.device,
+        scratch=fc1_c_tmp,
+    )
+    fc2_scratch = _get_c_tmp(
+        packed_gemm_scratch_elements(
+            size_n=hidden_size,
+            route_slots=int(route_slots_for_scratch),
+            moe_block_size=block_size_m,
+            sms=sms,
+        ),
+        device=a_input.device,
+        scratch=fc2_c_tmp,
+    )
+    if weight_layout == "modelopt":
+        w13_arg = prepared.w13.view(torch.uint8).view(-1)
+        w2_arg = prepared.w2.view(torch.uint8).view(-1)
+    else:
+        w13_arg = prepared.w13.view(torch.int32).view(-1)
+        w2_arg = prepared.w2.view(torch.int32).view(-1)
+    launch_common = (
+        a_input,
+        w13_arg,
+        w2_arg,
+        fc1_out,
+        activated,
+        fc2_out,
+        prepared.w13_scale.view(torch.uint8).view(torch.int32).view(-1),
+        prepared.w2_scale.view(torch.uint8).view(torch.int32).view(-1),
+        prepared.w13_global_scale,
+        prepared.w2_global_scale,
+        packed_route_indices,
+        block_expert_ids,
+        packed_route_count,
+    )
+    launch_tail = (
+        topk_weights,
+        fc1_scratch,
+        fc2_scratch,
+        prepared.workspace,
+        m,
+        capacity_m,
+        hidden_size,
+        intermediate_size,
+        int(prepared.num_experts),
+        topk,
+        activation,
+        bool(apply_router_weight_on_input),
+        expert_map is not None,
+        block_size_m,
+        int(fused.max_m_blocks),
+        element_dtype,
+        bool(fast_math),
+        sms,
+        max_shared_mem,
+        swiglu_limit is not None,
+        float(swiglu_limit or 0.0),
+        float(swiglu_alpha),
+        float(swiglu_beta),
+        weight_layout,
+        scale_format,
+        w13_layout,
+    )
+    if collect_activation_amax:
+        assert activation_amax is not None
+        assert layer_idx_int is not None
+        torch.ops.b12x.w4a16_fused_moe_calibrated_launch(
+            *launch_common,
+            activation_amax,
+            int(layer_idx_int),
+            *launch_tail,
+            int(stream),
+        )
+    else:
+        torch.ops.b12x.w4a16_fused_moe_launch(
+            *launch_common,
+            *launch_tail,
+            bool(use_direct_topk_routes),
+            bool(use_tc_decode),
+            int(stream),
+        )
+
+    if use_tc_decode:
+        # FC2 already wrote the top-k-summed result into `output`.
+        return output
+
+    if topk_sum_launch is not None:
+        expected_sum = (topk, hidden_size)
+        actual_sum = (
+            int(topk_sum_launch.topk),
+            int(topk_sum_launch.hidden_size),
+        )
+        if actual_sum != expected_sum:
+            raise RuntimeError(
+                "preplanned W4A16 top-k sum launch does not match requested contract: "
+                f"requested={expected_sum}, planned={actual_sum}"
+            )
+    torch.ops.b12x.w4a16_topk_sum_launch(
+        fc2_out,
+        output,
+        m,
+        topk,
+        hidden_size,
+        element_dtype,
+        int(stream),
+    )
+    return output
+
+
+__all__ = [
+    "W4A16ActivationCompileResult",
+    "W4A16FusedMoeCompileResult",
+    "W4A16GemmCompileResult",
+    "W4A16TopKSumCompileResult",
+    "W4A16FusedMoeKernel",
+    "W4A16ActivationKernel",
+    "W4A16GemmKernel",
+    "W4A16TopKSumKernel",
+    "clear_w4a16_kernel_cache",
+    "compile_w4a16_activation",
+    "compile_w4a16_fused_moe",
+    "compile_w4a16_gemm",
+    "compile_w4a16_topk_sum",
+    "pack_topk_routes_by_expert",
+    "run_w4a16_moe",
+]

+ 1557 - 0
docker-images/glm52-nf3-hybrid/overlay/b12x/moe/fused/w4a16/prepare.py

@@ -0,0 +1,1557 @@
+"""Local NVFP4/BF16 weight preparation for the CuTeDSL W4A16 path."""
+
+from __future__ import annotations
+
+import math
+from dataclasses import dataclass
+
+import torch
+
+from b12x.moe.fused.w4a16.host import (
+    W4A16PackedBuffers,
+    make_w4a16_packed_buffers as _make_w4a16_packed_buffers,
+    unswizzle_expert_scales,
+    validate_nf3_moe_inputs,
+    validate_w4a16_packed_inputs,
+)
+
+
+_PACKED_TILE_SIZE = 16
+_PACKED_TILE_N_SIZE = 64
+_PACK_FACTOR_4BIT = 8
+_MODEL_OPT_W13_LAYOUTS = {"w13", "w31"}
+_SOURCE_FORMATS = {
+    "modelopt_nvfp4": "modelopt_nvfp4",
+    "fp4_e8m0_k32": "fp4_e8m0_k32",
+    "compressed_tensors": "compressed_tensors",
+}
+_E8M0_K32_BF16_MAX_SCALE_BYTE = 247
+_E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT = 64
+# Canonical W13 layout names are "w13"/"w31"; accept the physical FC1-half
+# spellings as aliases. Logical checkpoint order "w13" arrives up/gate and
+# needs a swap before the kernel's SwiGLU; "w31" is already kernel-native
+# gate/up order.
+_W13_LAYOUTS = {
+    "w13": "w13",
+    "w31": "w31",
+    "up_gate": "w13",
+    "gate_up": "w31",
+}
+_MODEL_OPT_NVFP4_FORMATS = {"modelopt_nvfp4"}
+# NF3 ("nf3_2p1") 3-bit codebook. Must match kernel._NF3_CODEBOOK. The scale
+# convention (see NF3_KERNEL_MODSPEC.md): weights decode to the FULL-precision
+# bf16 codebook value, the K/32 scale byte encodes t_s * 2**-4 (e4m3-style,
+# E4=0 arm), and the per-tensor global_scale carries the matching 2**116.
+_NF3_CODEBOOK = (-1.0, -0.6047, -0.3563, -0.1275, 0.1275, 0.3563, 0.6047, 1.0)
+_NF3_SCALE_GLOBAL = 2.0**116
+_NF3_SCALE_FLOOR = 2.0 ** -10  # f16(t_s*2^-4) must stay f16-NORMAL (>=2^-14) -> t_s >= 2^-10; real early-layer scales dip below the old 2^-7
+
+
+@dataclass(frozen=True)
+class W4A16PackedWeights:
+    w13: torch.Tensor
+    w13_scale: torch.Tensor
+    w13_global_scale: torch.Tensor
+    w2: torch.Tensor
+    w2_scale: torch.Tensor
+    w2_global_scale: torch.Tensor
+    workspace: torch.Tensor
+    hidden_size: int
+    intermediate_size: int
+    num_experts: int
+    is_gated: bool
+    params_dtype: torch.dtype
+    source_format: str = "modelopt_nvfp4"
+    w13_layout: str = "w13"
+    weight_layout: str = "packed"
+    scale_format: str = "e4m3_k16"
+
+
+@dataclass(frozen=True)
+class W4A16ModelOptWeights:
+    w13: torch.Tensor
+    w13_scale: torch.Tensor
+    w13_global_scale: torch.Tensor
+    w2: torch.Tensor
+    w2_scale: torch.Tensor
+    w2_global_scale: torch.Tensor
+    workspace: torch.Tensor
+    hidden_size: int
+    intermediate_size: int
+    num_experts: int
+    is_gated: bool
+    params_dtype: torch.dtype
+    source_format: str = "modelopt_nvfp4"
+    weight_layout: str = "modelopt"
+    scale_format: str = "e4m3_k16"
+    micro_w13_scale: torch.Tensor | None = None
+    micro_w13_global_scale: torch.Tensor | None = None
+    micro_w2_scale: torch.Tensor | None = None
+    micro_w2_global_scale: torch.Tensor | None = None
+    # Physical order of the two fused FC1 halves in source W13. "w13" (logical,
+    # == "up_gate" physical) needs a row rotation before W4A16 SwiGLU; "w31"
+    # (== "gate_up") is already in the kernel-native order.
+    w13_layout: str = "w13"
+
+
+@dataclass(frozen=True)
+class PreparedNF3MoeWeights:
+    """Runtime NF3 ("nf3_2p1") hybrid-expert W4A16 weights.
+
+    Mirrors W4A16PackedWeights so run_w4a16_moe consumes it identically. The
+    packed planes are int32 (3 words per 32-code unit); the K/32 scales are
+    e4m3-style bytes viewed uint8; the global scales carry the 2**116 the NF3
+    scale convention defers out of the codebook. fc1_tile_n / fc2_tile_n record
+    the CTA N-tile the flat-span packing was built for -- the kernel MUST be
+    compiled/launched with the SAME tile_n (read them back from the compiled
+    W4A16FusedMoeCompileResult).
+    """
+
+    w13: torch.Tensor
+    w13_scale: torch.Tensor
+    w13_global_scale: torch.Tensor
+    w2: torch.Tensor
+    w2_scale: torch.Tensor
+    w2_global_scale: torch.Tensor
+    workspace: torch.Tensor
+    hidden_size: int
+    intermediate_size: int
+    num_experts: int
+    is_gated: bool
+    params_dtype: torch.dtype
+    fc1_tile_n: int
+    fc2_tile_n: int
+    source_format: str = "nf3_2p1"
+    w13_layout: str = "packed"
+    weight_layout: str = "nf3_2p1"
+    scale_format: str = "e4m3_k32"
+
+
+def _make_workspace(
+    device: torch.device, *, max_blocks_per_sm: int = 4
+) -> torch.Tensor:
+    props = torch.cuda.get_device_properties(device)
+    sms = int(props.multi_processor_count)
+    return torch.zeros(
+        (sms * int(max_blocks_per_sm) + 2,),
+        dtype=torch.int32,
+        device=device,
+    )
+
+
+def _scale_perms() -> tuple[list[int], list[int]]:
+    scale_perm: list[int] = []
+    for i in range(8):
+        scale_perm.extend([i + 8 * j for j in range(8)])
+    scale_perm_single: list[int] = []
+    for i in range(4):
+        scale_perm_single.extend([2 * i + j for j in [0, 1, 8, 9, 16, 17, 24, 25]])
+    return scale_perm, scale_perm_single
+
+
+def _e8m0_logical_tail_scale_n(size_n: int) -> int:
+    return (
+        (int(size_n) + _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT - 1)
+        // _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT
+    ) * _E8M0_LOGICAL_TAIL_SCALE_N_ALIGNMENT
+
+
+def _permute_packed_scales(
+    scales: torch.Tensor,
+    *,
+    size_k: int,
+    size_n: int,
+    group_size: int,
+    output_size_n: int | None = None,
+) -> torch.Tensor:
+    scale_perm, scale_perm_single = _scale_perms()
+    if group_size < size_k and group_size != -1:
+        block = len(scale_perm)
+        if output_size_n is not None or int(size_n) % block != 0:
+            padded_n = (
+                ((int(size_n) + block - 1) // block) * block
+                if output_size_n is None
+                else int(output_size_n)
+            )
+            if padded_n < int(size_n) or padded_n % block != 0:
+                raise ValueError(
+                    f"output_size_n must be a multiple of {block} and >= size_n"
+                )
+            padded = scales.new_zeros((int(scales.shape[0]), padded_n))
+            padded[:, : int(size_n)] = scales
+            scales = padded.reshape((int(scales.shape[0]), -1, block))
+            scales = scales[:, :, scale_perm].reshape((int(scales.shape[0]), padded_n))
+            if output_size_n is None:
+                scales = scales[:, : int(size_n)]
+            return scales.contiguous()
+        scales = scales.reshape((-1, block))[:, scale_perm]
+    else:
+        block = len(scale_perm_single)
+        if output_size_n is not None or int(size_n) % block != 0:
+            padded_n = (
+                ((int(size_n) + block - 1) // block) * block
+                if output_size_n is None
+                else int(output_size_n)
+            )
+            if padded_n < int(size_n) or padded_n % block != 0:
+                raise ValueError(
+                    f"output_size_n must be a multiple of {block} and >= size_n"
+                )
+            padded = scales.new_zeros((int(scales.shape[0]), padded_n))
+            padded[:, : int(size_n)] = scales
+            scales = padded.reshape((int(scales.shape[0]), -1, block))
+            scales = scales[:, :, scale_perm_single].reshape(
+                (int(scales.shape[0]), padded_n)
+            )
+            if output_size_n is None:
+                scales = scales[:, : int(size_n)]
+            return scales.contiguous()
+        scales = scales.reshape((-1, block))[:, scale_perm_single]
+    return scales.reshape((-1, size_n)).contiguous()
+
+
+def _nvfp4_compute_scale_factor(
+    packed_scales: torch.Tensor,
+    a_dtype: torch.dtype,
+) -> float:
+    if a_dtype == torch.float16:
+        return 1.0
+    max_scalar = 0.0
+    for expert in range(int(packed_scales.shape[0])):
+        ws_float = packed_scales[expert].float() * (2**7)
+        nonzero_mask = ws_float > 0
+        if bool(nonzero_mask.any().item()):
+            max_scalar = max(max_scalar, float(ws_float[nonzero_mask].max().item()))
+    if max_scalar > 0.0 and max_scalar < 448 * (2**7):
+        return float(2 ** math.floor(math.log2((448 * (2**7)) / max_scalar)))
+    return 1.0
+
+
+def _process_nvfp4_packed_scales(
+    packed_scales: torch.Tensor,
+    *,
+    scale_factor: float,
+) -> torch.Tensor:
+    packed_scales = packed_scales.to(torch.float16)
+    packed_scales = packed_scales.view(-1, 4)[:, [0, 2, 1, 3]].view(
+        packed_scales.size(0),
+        -1,
+    )
+    if scale_factor > 1.0:
+        packed_scales = (packed_scales.float() * scale_factor).to(torch.float16)
+    packed_scales = packed_scales * (2**7)
+    packed_scales[packed_scales < 2] = 0
+    packed_scales = packed_scales.view(torch.int16) << 1
+    packed_scales = packed_scales.view(torch.float8_e4m3fn)
+    return packed_scales[:, 1::2].contiguous()
+
+
+def _process_nvfp4_packed_global_scale(
+    global_scale: torch.Tensor,
+    *,
+    a_dtype: torch.dtype,
+) -> torch.Tensor:
+    if a_dtype == torch.float16:
+        target_exponent = 5
+    elif a_dtype == torch.bfloat16:
+        target_exponent = 8
+    else:
+        raise TypeError(f"unsupported W4A16 activation dtype {a_dtype}")
+    fp4_exponent = 2
+    exponent_bias = 2 ** (target_exponent - 1) - 2 ** (fp4_exponent - 1)
+    return global_scale * (2.0 ** (exponent_bias - 7))
+
+
+def _process_nvfp4_micro_global_scale_from_packed(
+    packed_global_scale: torch.Tensor,
+    *,
+    a_dtype: torch.dtype,
+) -> torch.Tensor:
+    if a_dtype == torch.float16:
+        target_exponent = 5
+    elif a_dtype == torch.bfloat16:
+        target_exponent = 8
+    else:
+        raise TypeError(f"unsupported W4A16 activation dtype {a_dtype}")
+    fp4_exponent = 2
+    exponent_bias = 2 ** (target_exponent - 1) - 2 ** (fp4_exponent - 1)
+    return (packed_global_scale * (2.0 ** (-exponent_bias))).to(torch.float32).contiguous()
+
+
+def _normalize_source_format(source_format: str) -> str:
+    if source_format.lower() == "mxfp4_native":
+        raise ValueError(
+            "source_format='mxfp4_native' has been removed; use "
+            "source_format='fp4_e8m0_k32' for E8M0 K/32 scales, or add "
+            "a real MXFP4 source contract"
+        )
+    try:
+        return _SOURCE_FORMATS[source_format.lower()]
+    except KeyError as exc:
+        raise ValueError(
+            "source_format must be one of 'modelopt_nvfp4', "
+            "'fp4_e8m0_k32', or 'compressed_tensors', "
+            f"got {source_format!r}"
+        ) from exc
+
+
+def _normalize_w13_layout(w13_layout: str) -> str:
+    try:
+        return _W13_LAYOUTS[w13_layout.lower()]
+    except KeyError as exc:
+        raise ValueError(
+            "w13_layout must be one of 'w13'/'w31' (or the 'up_gate'/'gate_up' "
+            f"aliases), got {w13_layout!r}"
+        ) from exc
+
+
+def _source_global_scale(
+    global_scale: torch.Tensor, *, source_format: str
+) -> torch.Tensor:
+    if source_format == "compressed_tensors":
+        return (1.0 / global_scale).to(torch.float32).contiguous()
+    return global_scale.contiguous()
+
+
+def _validate_e8m0_k32_scales(
+    scales: torch.Tensor,
+    *,
+    rows: int,
+    cols: int,
+    name: str,
+    allow_k_tail: bool = False,
+) -> torch.Tensor:
+    """Validate source E8M0 K/32 scale tensor shape and dtype."""
+    if scales.ndim != 3:
+        raise ValueError(
+            f"{name} must be [E, N, ceil(K/32)], got {tuple(scales.shape)}"
+        )
+    if allow_k_tail:
+        if int(cols) % 8 != 0:
+            raise ValueError(
+                f"{name} compact E8M0 K-tail requires K divisible by 8, got "
+                f"{int(cols)}"
+            )
+        expected_cols = (int(cols) + 31) // 32
+    elif int(cols) % 32 != 0:
+        raise ValueError(f"{name} requires K divisible by 32, got {int(cols)}")
+    else:
+        expected_cols = int(cols) // 32
+    if tuple(scales.shape[1:]) != (int(rows), expected_cols):
+        raise ValueError(
+            f"{name} must have shape [E, {int(rows)}, {expected_cols}] for "
+            f"E8M0 K/32 scales, got {tuple(scales.shape)}"
+        )
+    e8m0_dtype = getattr(torch, "float8_e8m0fnu", None)
+    if scales.dtype == torch.uint8:
+        return scales.view(e8m0_dtype) if e8m0_dtype is not None else scales
+    if e8m0_dtype is not None and scales.dtype == e8m0_dtype:
+        return scales
+    raise TypeError(f"{name} must be torch.uint8 or torch.float8_e8m0fnu")
+
+
+def _pack_e8m0_k32_scales(
+    scales: torch.Tensor,
+    *,
+    size_k: int,
+    size_n: int,
+    row_rotation: int | None = None,
+    reuse_input_storage: bool = False,
+    allow_k_tail: bool = False,
+    padded_size_n: int | None = None,
+) -> torch.Tensor:
+    if allow_k_tail:
+        if int(size_k) % 8 != 0:
+            raise ValueError(
+                f"compact E8M0 K-tail requires K divisible by 8, got {size_k}"
+            )
+        scale_cols = (int(size_k) + 31) // 32
+    elif int(size_k) % 32 != 0:
+        raise ValueError(f"E8M0 K/32 scales require K divisible by 32, got {size_k}")
+    else:
+        scale_cols = int(size_k) // 32
+    if tuple(scales.shape[1:]) != (int(size_n), scale_cols):
+        raise ValueError(
+            f"expected E8M0 scale shape [E, {int(size_n)}, {scale_cols}], "
+            f"got {tuple(scales.shape)}"
+        )
+    output_size_n = int(size_n) if padded_size_n is None else int(padded_size_n)
+    if output_size_n < int(size_n):
+        raise ValueError(
+            f"padded_size_n must be >= size_n, got {output_size_n} < {int(size_n)}"
+        )
+    source = scales.view(torch.uint8)
+    if reuse_input_storage:
+        if output_size_n != int(size_n):
+            raise ValueError("reuse_input_storage requires unpadded E8M0 scales")
+        if allow_k_tail:
+            raise ValueError(
+                "reuse_input_storage is not supported for compact E8M0 K-tail scales"
+            )
+        if not source.is_contiguous():
+            raise ValueError("reuse_input_storage requires contiguous E8M0 scales")
+        source.clamp_(max=_E8M0_K32_BF16_MAX_SCALE_BYTE)
+        packed = source.reshape(
+            int(source.shape[0]),
+            scale_cols,
+            output_size_n,
+        )
+    else:
+        source = source.clamp(max=_E8M0_K32_BF16_MAX_SCALE_BYTE)
+        packed = torch.empty(
+            (int(source.shape[0]), scale_cols, output_size_n),
+            dtype=torch.uint8,
+            device=scales.device,
+        )
+    for expert in range(int(source.shape[0])):
+        expert_source = source[expert]
+        if row_rotation is not None:
+            expert_source = torch.cat(
+                [expert_source[row_rotation:], expert_source[:row_rotation]],
+                dim=0,
+            )
+        expert_packed = _permute_packed_scales(
+            expert_source.T.contiguous(),
+            size_k=size_k,
+            size_n=size_n,
+            group_size=32,
+            output_size_n=output_size_n,
+        )
+        expert_packed = (
+            expert_packed.view(-1, 4)[:, [0, 2, 1, 3]]
+            .reshape_as(expert_packed)
+            .contiguous()
+        )
+        packed[expert].copy_(expert_packed)
+    return packed.view(scales.dtype) if scales.dtype != torch.uint8 else packed
+
+
+def _repack_4bit_no_perm(
+    qweight_i32: torch.Tensor,
+    *,
+    size_k: int,
+    size_n: int,
+    out: torch.Tensor | None = None,
+    flat_scratch: torch.Tensor | None = None,
+    gather_scratch: torch.Tensor | None = None,
+) -> torch.Tensor:
+    """Pack 4-bit weights into the W4A16 A16 kernel layout."""
+    if qweight_i32.dtype != torch.int32:
+        raise TypeError("qweight_i32 must be torch.int32")
+    if tuple(qweight_i32.shape) != (size_k // _PACK_FACTOR_4BIT, size_n):
+        raise ValueError(
+            f"expected qweight shape {(size_k // _PACK_FACTOR_4BIT, size_n)}, "
+            f"got {tuple(qweight_i32.shape)}"
+        )
+    if size_k % _PACKED_TILE_SIZE != 0 or size_n % _PACKED_TILE_N_SIZE != 0:
+        raise ValueError(
+            f"W4A16 repack requires K,N multiples of 16,64; got {size_k},{size_n}"
+        )
+
+    k_tiles = size_k // _PACKED_TILE_SIZE
+    n_tiles = size_n // _PACKED_TILE_N_SIZE
+    packed_shape = (k_tiles, n_tiles, 128)
+    if out is not None and (
+        out.dtype != torch.int32 or tuple(out.shape) != packed_shape
+    ):
+        raise ValueError(
+            f"out must be int32 with shape {packed_shape}, got "
+            f"{out.dtype} {tuple(out.shape)}"
+        )
+    if flat_scratch is not None and (
+        flat_scratch.dtype != torch.int32
+        or tuple(flat_scratch.shape) != packed_shape
+    ):
+        raise ValueError(
+            f"flat_scratch must be int32 with shape {packed_shape}, got "
+            f"{flat_scratch.dtype} {tuple(flat_scratch.shape)}"
+        )
+    if gather_scratch is not None and (
+        gather_scratch.dtype != torch.int32
+        or tuple(gather_scratch.shape) != packed_shape
+    ):
+        raise ValueError(
+            f"gather_scratch must be int32 with shape {packed_shape}, got "
+            f"{gather_scratch.dtype} {tuple(gather_scratch.shape)}"
+        )
+
+    tiles = qweight_i32.view(
+        k_tiles,
+        2,
+        n_tiles,
+        _PACKED_TILE_N_SIZE,
+    )
+    if flat_scratch is None:
+        flat = tiles.permute(0, 2, 1, 3).reshape(
+            k_tiles,
+            n_tiles,
+            2 * _PACKED_TILE_N_SIZE,
+        )
+    else:
+        flat_scratch.view(k_tiles, n_tiles, 2, _PACKED_TILE_N_SIZE).copy_(
+            tiles.permute(0, 2, 1, 3)
+        )
+        flat = flat_scratch
+
+    device = qweight_i32.device
+    out_pos = torch.arange(128, device=device, dtype=torch.long)
+    th_id = out_pos // 4
+    warp_id = out_pos % 4
+    tc_col = th_id // 4
+    tc_row = (th_id % 4) * 2
+    offsets = torch.tensor([0, 1, 8, 9], device=device, dtype=torch.long)
+    pack_idx = torch.tensor([0, 2, 4, 6, 1, 3, 5, 7], device=device, dtype=torch.long)
+
+    elem = tc_row[:, None] + offsets[None, :]
+    row = elem // _PACK_FACTOR_4BIT
+    pos = elem % _PACK_FACTOR_4BIT
+    col1 = (warp_id * 16 + tc_col)[:, None].expand(-1, 4)
+    col2 = col1 + 8
+    source_index = torch.cat(
+        [row * _PACKED_TILE_N_SIZE + col1, row * _PACKED_TILE_N_SIZE + col2],
+        dim=1,
+    )[:, pack_idx]
+    source_shift = torch.cat([pos, pos], dim=1)[:, pack_idx] * 4
+
+    result = (
+        torch.empty(packed_shape, device=device, dtype=torch.int32)
+        if out is None
+        else out
+    )
+    result.zero_()
+    for slot in range(8):
+        gather_index = source_index[:, slot].view(1, 1, 128).expand(
+            k_tiles,
+            n_tiles,
+            128,
+        )
+        shift = source_shift[:, slot].view(1, 1, 128)
+        if gather_scratch is None:
+            gathered = flat.gather(2, gather_index)
+            nibble = (gathered >> shift) & 0xF
+            result |= nibble << (slot * 4)
+        else:
+            torch.gather(flat, 2, gather_index, out=gather_scratch)
+            torch.bitwise_right_shift(gather_scratch, shift, out=gather_scratch)
+            torch.bitwise_and(gather_scratch, 0xF, out=gather_scratch)
+            if slot:
+                torch.bitwise_left_shift(
+                    gather_scratch,
+                    slot * 4,
+                    out=gather_scratch,
+                )
+            torch.bitwise_or(result, gather_scratch, out=result)
+
+    return result.reshape(k_tiles, n_tiles * 128).contiguous()
+
+
+def _repack_weight(
+    weight: torch.Tensor,
+    *,
+    size_k: int,
+    size_n: int,
+    row_rotation: int | None = None,
+    reuse_input_storage: bool = False,
+) -> torch.Tensor:
+    num_experts = int(weight.shape[0])
+    if tuple(weight.shape[1:]) != (size_n, size_k // 2):
+        raise ValueError(
+            f"expected packed weight shape {(num_experts, size_n, size_k // 2)}, "
+            f"got {tuple(weight.shape)}"
+        )
+    if size_k % _PACKED_TILE_SIZE != 0 or size_n % _PACKED_TILE_N_SIZE != 0:
+        raise ValueError(
+            f"W4A16 repack requires K,N multiples of 16,64; got {size_k},{size_n}"
+        )
+
+    packed_shape = (
+        num_experts,
+        size_k // _PACKED_TILE_SIZE,
+        (size_n // _PACKED_TILE_N_SIZE) * 128,
+    )
+    if reuse_input_storage:
+        if not weight.is_contiguous():
+            raise ValueError("reuse_input_storage requires contiguous packed weights")
+        packed = weight.view(torch.int32).reshape(packed_shape)
+    else:
+        packed = torch.empty(packed_shape, device=weight.device, dtype=torch.int32)
+
+    k_tiles = size_k // _PACKED_TILE_SIZE
+    n_tiles = size_n // _PACKED_TILE_N_SIZE
+    qweight_scratch = torch.empty(
+        (size_k // _PACK_FACTOR_4BIT, size_n),
+        device=weight.device,
+        dtype=torch.int32,
+    )
+    flat_scratch = torch.empty(
+        (k_tiles, n_tiles, 128),
+        device=weight.device,
+        dtype=torch.int32,
+    )
+    gather_scratch = torch.empty_like(flat_scratch)
+
+    for expert in range(num_experts):
+        expert_weight = weight[expert].view(torch.int32)
+        if row_rotation is not None:
+            rotated_rows = int(size_n) - int(row_rotation)
+            qweight_scratch[:, :rotated_rows].copy_(expert_weight[row_rotation:].T)
+            qweight_scratch[:, rotated_rows:].copy_(expert_weight[:row_rotation].T)
+        else:
+            qweight_scratch.copy_(expert_weight.T)
+        _repack_4bit_no_perm(
+            qweight_scratch,
+            size_k=size_k,
+            size_n=size_n,
+            out=packed[expert].view(k_tiles, n_tiles, 128),
+            flat_scratch=flat_scratch,
+            gather_scratch=gather_scratch,
+        )
+    return packed
+
+
+def _permute_nvfp4_scales(
+    scales: torch.Tensor,
+    global_scales: torch.Tensor,
+    *,
+    size_k: int,
+    size_n: int,
+    a_dtype: torch.dtype,
+    row_rotation: int | None = None,
+) -> tuple[torch.Tensor, torch.Tensor]:
+    combined_scale_factor = _nvfp4_compute_scale_factor(scales, a_dtype)
+    packed_scales: torch.Tensor | None = None
+    for expert in range(scales.shape[0]):
+        expert_source = scales[expert].to(a_dtype)
+        if row_rotation is not None:
+            expert_source = torch.cat(
+                [expert_source[row_rotation:], expert_source[:row_rotation]],
+                dim=0,
+            )
+        expert_scales = _permute_packed_scales(
+            expert_source.T,
+            size_k=size_k,
+            size_n=size_n,
+            group_size=16,
+        )
+        expert_packed = _process_nvfp4_packed_scales(
+            expert_scales,
+            scale_factor=combined_scale_factor,
+        )
+        if packed_scales is None:
+            packed_scales = torch.empty(
+                (int(scales.shape[0]), *expert_packed.shape),
+                dtype=expert_packed.dtype,
+                device=expert_packed.device,
+            )
+        packed_scales[expert].copy_(expert_packed)
+    if packed_scales is None:
+        packed_scales = torch.empty(
+            (0, size_k // _PACKED_TILE_SIZE, size_n // 2),
+            dtype=torch.float8_e4m3fn,
+            device=scales.device,
+        )
+    packed_global = _process_nvfp4_packed_global_scale(
+        global_scales,
+        a_dtype=a_dtype,
+    ).to(torch.float32)
+    packed_global = packed_global / combined_scale_factor
+    return packed_scales, packed_global.contiguous()
+
+
+# ---------------------------------------------------------------------------
+# NF3 ("nf3_2p1") packing.
+#
+# The kernel's B operand is a stream of 32-code "units" (2 N-columns x 16 K),
+# each a 12-byte (lo0, lo1, hi) triple. The GEMM reads unit index
+#   unit = cur_group_id * (tile_n // 2) + (tid % (tile_n // 2))
+# from the pipe's B SMEM region (see kernel._load_b_scale_registers,
+# NF3-MAPPING-V1) which -- verified algebraically -- equals the stock staged
+# unit index; cur_group_id is the K16 row within the CTA-K tile, (tid %
+# (tile_n // 2)) is the N-pair. The flat-span staging copies the packer's
+# global bytes verbatim, so the packer must place, at global unit
+#   I = nt*(K/16)*(tile_n/2) + R*(tile_n/2) + p          (n_tile-major)
+# the codes for CTA N-tile nt, K16-row-global R, N-pair p. The 4 jj words in
+# the triple correspond to the stock 4-u32 group; per jj the 8 codes decode
+# (packed_dequant_nf3x8_to_bfloat2x4) to fragments
+#   frag[0,0]=(cb[c0],cb[c1]) frag[0,1]=(cb[c2],cb[c3])
+#   frag[1,0]=(cb[c4],cb[c5]) frag[1,1]=(cb[c6],cb[c7])
+# which must equal the stock fragment identity for this thread/jj:
+#   frag[0,0]=(C1@K0,   C1@K0+1)  frag[0,1]=(C1@K0+8, C1@K0+9)
+#   frag[1,0]=(C2@K0,   C2@K0+1)  frag[1,1]=(C2@K0+8, C2@K0+9)
+# where, from _repack_4bit_no_perm composed with the read mapping,
+#   wru = p + (tile_n/2)*nt ; n_tile_64 = wru // 32 ; th_id = wru % 32
+#   tc_col = th_id // 4 ; tc_row = (th_id % 4) * 2
+#   C1 = n_tile_64*64 + jj*16 + tc_col ; C2 = C1 + 8 ; K0 = R*16 + tc_row
+# => code order [c0..c7] =
+#   [ (C1,K0),(C1,K0+1),(C1,K0+8),(C1,K0+9),
+#     (C2,K0),(C2,K0+1),(C2,K0+8),(C2,K0+9) ].
+# This whole chain is asserted by _nf3_pack_selftest against an independent
+# torch simulation of the kernel read+dequant.
+# ---------------------------------------------------------------------------
+
+
+def _nf3_check_shapes(size_k: int, size_n: int, tile_n: int) -> None:
+    if int(size_k) % 32 != 0:
+        raise ValueError(f"NF3 requires K % 32 == 0, got {size_k}")
+    if int(size_n) % 64 != 0:
+        raise ValueError(f"NF3 requires N % 64 == 0, got {size_n}")
+    if int(tile_n) % 16 != 0 or int(tile_n) < 64:
+        raise ValueError(f"NF3 tile_n must be a multiple of 16 and >= 64, got {tile_n}")
+    if int(size_n) % int(tile_n) != 0:
+        raise ValueError(f"NF3 requires N ({size_n}) divisible by tile_n ({tile_n})")
+
+
+def _nf3_code_gather_index(
+    size_k: int, size_n: int, tile_n: int, device: torch.device
+) -> torch.Tensor:
+    """[units, 4, 8] flat indices into a contiguous [N, K] code tensor.
+
+    Entry [I, jj, v] is the (C * size_k + K) index of the v-th code (NF3 order)
+    of triple word jj at global unit I. Built from the exact _repack /
+    read-mapping math documented above so the packer and the kernel agree.
+    """
+    _nf3_check_shapes(size_k, size_n, tile_n)
+    npairs = int(tile_n) // 2
+    k16 = int(size_k) // 16
+    units = k16 * (int(size_n) // 2)
+    ntile_units = k16 * npairs
+    idx_i = torch.arange(units, device=device, dtype=torch.long)
+    nt = idx_i // ntile_units
+    within = idx_i % ntile_units
+    R = within // npairs
+    p = within % npairs
+    wru = p + npairs * nt
+    n_tile_64 = wru // 32
+    th_id = wru % 32
+    tc_col = th_id // 4
+    tc_row = (th_id % 4) * 2
+    jj = torch.arange(4, device=device, dtype=torch.long)
+    col1 = jj[None, :] * 16 + tc_col[:, None]  # [units, 4]
+    col2 = col1 + 8
+    C1 = n_tile_64[:, None] * 64 + col1  # [units, 4]
+    C2 = n_tile_64[:, None] * 64 + col2
+    K0 = (R * 16 + tc_row)[:, None]  # [units, 1]
+    k_off = torch.tensor([0, 1, 8, 9], device=device, dtype=torch.long)
+    idx = torch.empty((units, 4, 8), device=device, dtype=torch.long)
+    for t in range(4):
+        idx[:, :, t] = C1 * int(size_k) + (K0 + k_off[t])
+        idx[:, :, 4 + t] = C2 * int(size_k) + (K0 + k_off[t])
+    return idx
+
+
+def _nf3_pack_codes(
+    codes_nk: torch.Tensor, *, size_k: int, size_n: int, tile_n: int
+) -> torch.Tensor:
+    """Pack one expert's [N, K] codes (0..7) into int32 [units*3] NF3 planes."""
+    if tuple(codes_nk.shape) != (int(size_n), int(size_k)):
+        raise ValueError(
+            f"expected codes shape {(int(size_n), int(size_k))}, "
+            f"got {tuple(codes_nk.shape)}"
+        )
+    device = codes_nk.device
+    flat = codes_nk.reshape(-1).to(torch.int64)
+    if bool((flat < 0).any()) or bool((flat > 7).any()):
+        raise ValueError("NF3 codes must be integers in [0, 7]")
+    idx = _nf3_code_gather_index(size_k, size_n, tile_n, device)  # [units,4,8]
+    g = flat[idx.reshape(-1)].reshape(idx.shape)  # [units,4,8]
+    sh_lo = (torch.arange(4, device=device, dtype=torch.int64) * 2).view(1, 1, 4)
+    sh_hi = torch.arange(4, device=device, dtype=torch.int64).view(1, 1, 4)
+    la = ((g[:, :, 0:4] & 3) << sh_lo).sum(-1)  # [units,4]
+    lb = ((g[:, :, 4:8] & 3) << sh_lo).sum(-1)
+    lo16 = la | (lb << 8)
+    ha = (((g[:, :, 0:4] >> 2) & 1) << sh_hi).sum(-1)
+    hb = (((g[:, :, 4:8] >> 2) & 1) << sh_hi).sum(-1)
+    hi8 = ha | (hb << 4)
+    lo0 = lo16[:, 0] | (lo16[:, 1] << 16)
+    lo1 = lo16[:, 2] | (lo16[:, 3] << 16)
+    hi = hi8[:, 0] | (hi8[:, 1] << 8) | (hi8[:, 2] << 16) | (hi8[:, 3] << 24)
+    words = torch.stack([lo0, lo1, hi], dim=1).reshape(-1)  # int64 in [0, 2**32)
+    words = torch.where(words >= 2**31, words - 2**32, words)
+    return words.to(torch.int32).contiguous()
+
+
+def _process_nf3_packed_scales(packed_scales: torch.Tensor) -> torch.Tensor:
+    """[rows, N] float t_s -> [rows, N] uint8 e4m3-style byte = highbyte(f16(t_s*2**-4)<<1)."""
+    packed_scales = packed_scales.to(torch.float16)
+    packed_scales = packed_scales.view(-1, 4)[:, [0, 2, 1, 3]].view(
+        packed_scales.size(0),
+        -1,
+    )
+    packed_scales = (packed_scales.float() * (2.0**-4)).to(torch.float16)
+    packed_scales = packed_scales.view(torch.int16) << 1
+    packed_scales = packed_scales.view(torch.uint8)
+    return packed_scales[:, 1::2].contiguous()
+
+
+def _nf3_pack_scales(
+    t_s: torch.Tensor, *, size_k: int, size_n: int
+) -> torch.Tensor:
+    """Pack one expert's [N, K//32] scales into uint8 [K//32, N] (permuted)."""
+    if tuple(t_s.shape) != (int(size_n), int(size_k) // 32):
+        raise ValueError(
+            f"expected scale shape {(int(size_n), int(size_k) // 32)}, "
+            f"got {tuple(t_s.shape)}"
+        )
+    t_s = t_s.to(torch.float32)
+    # zero scales (whole group exactly zero in the checkpoint) MUST stay zero:
+    # stored byte 0 decodes to exact +0.0. Flooring them to _NF3_SCALE_FLOOR
+    # injects noise into all-zero groups (real early-layer experts have many)
+    # -> compounding early-layer error -> prompt-dependent degeneration.
+    zero_mask = t_s == 0
+    t_s = t_s.clamp(min=_NF3_SCALE_FLOOR)
+    t_s[zero_mask] = 0.0
+    if bool((t_s >= 32.0).any()):
+        raise ValueError("NF3 scales must be < 32 for the e4m3 K/32 encoding")
+    permuted = _permute_packed_scales(
+        t_s.T.contiguous(),
+        size_k=size_k,
+        size_n=size_n,
+        group_size=32,
+    )  # [K//32, N] float
+    return _process_nf3_packed_scales(permuted)
+
+
+def _nf3_pack_code_experts(
+    codes: torch.Tensor, *, size_k: int, size_n: int, tile_n: int
+) -> torch.Tensor:
+    packed = [
+        _nf3_pack_codes(codes[e], size_k=size_k, size_n=size_n, tile_n=tile_n)
+        for e in range(int(codes.shape[0]))
+    ]
+    return torch.stack(packed, dim=0).contiguous()
+
+
+def _nf3_pack_scale_experts(
+    t_s: torch.Tensor, *, size_k: int, size_n: int
+) -> torch.Tensor:
+    packed = [
+        _nf3_pack_scales(t_s[e], size_k=size_k, size_n=size_n)
+        for e in range(int(t_s.shape[0]))
+    ]
+    return torch.stack(packed, dim=0).contiguous()
+
+
+def _prepare_w4a16_packed_weights(
+    w13_fp4: torch.Tensor,
+    w13_blockscale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_blockscale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    source_format: str,
+    w13_layout: str = "w13",
+    reuse_input_storage: bool = False,
+) -> W4A16PackedWeights:
+    source_format = _normalize_source_format(source_format)
+    w13_layout = _normalize_w13_layout(w13_layout)
+    shape = validate_w4a16_packed_inputs(
+        w13_fp4,
+        w13_global_scale,
+        w2_fp4,
+        w2_global_scale,
+        activation=activation,
+    )
+    num_experts = shape.num_experts
+    hidden_size = shape.hidden_size
+    intermediate_size = shape.intermediate_size
+    w13_rows = shape.w13_rows
+    is_gated = shape.is_gated
+
+    w13 = w13_fp4
+    w13_scale = unswizzle_expert_scales(
+        w13_blockscale,
+        rows=w13_rows,
+        cols=hidden_size,
+    )
+    w13_row_rotation = None
+    if is_gated and w13_layout == "w13":
+        # In-place: the half-swap is folded into the repack via row_rotation;
+        # never materialize a second copy of the weights/scales.
+        w13_row_rotation = intermediate_size
+
+    w2_scale = unswizzle_expert_scales(
+        w2_blockscale,
+        rows=hidden_size,
+        cols=intermediate_size,
+    )
+
+    packed_w13 = _repack_weight(
+        w13 if reuse_input_storage else w13.contiguous(),
+        size_k=hidden_size,
+        size_n=w13_rows,
+        row_rotation=w13_row_rotation,
+        reuse_input_storage=reuse_input_storage,
+    )
+    packed_w2 = _repack_weight(
+        w2_fp4 if reuse_input_storage else w2_fp4.contiguous(),
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        reuse_input_storage=reuse_input_storage,
+    )
+    native_w13_global_scale = _source_global_scale(
+        w13_global_scale,
+        source_format=source_format,
+    )
+    native_w2_global_scale = _source_global_scale(
+        w2_global_scale,
+        source_format=source_format,
+    )
+    packed_w13_scale, packed_w13_global_scale = _permute_nvfp4_scales(
+        w13_scale,
+        native_w13_global_scale,
+        size_k=hidden_size,
+        size_n=w13_rows,
+        a_dtype=params_dtype,
+        row_rotation=w13_row_rotation,
+    )
+    packed_w2_scale, packed_w2_global_scale = _permute_nvfp4_scales(
+        w2_scale,
+        native_w2_global_scale,
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        a_dtype=params_dtype,
+    )
+
+    return W4A16PackedWeights(
+        w13=packed_w13,
+        w13_scale=packed_w13_scale,
+        w13_global_scale=packed_w13_global_scale,
+        w2=packed_w2,
+        w2_scale=packed_w2_scale,
+        w2_global_scale=packed_w2_global_scale,
+        workspace=_make_workspace(w13_fp4.device, max_blocks_per_sm=4),
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        is_gated=is_gated,
+        params_dtype=params_dtype,
+        source_format=source_format,
+        w13_layout=w13_layout,
+        scale_format="e4m3_k16",
+    )
+
+
+def prepare_w4a16_modelopt_nvfp4_weights(
+    w13_fp4: torch.Tensor,
+    w13_blockscale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_blockscale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    w13_layout: str = "w13",
+    reuse_input_storage: bool = False,
+) -> W4A16PackedWeights:
+    """Prepare ModelOpt NVFP4 tensors into the W4A16 packed runtime layout.
+
+    The per-block scales are the normal NVFP4 K/16 scale grid in b12x swizzled
+    storage. The global scales are raw ModelOpt weight global scales; activation
+    input scales are not folded into W4A16 weight preparation. For gated
+    activations, ``w13_layout`` describes whether fused W13 rows arrive in
+    checkpoint/logical W13 order or already swapped W31 order.
+    """
+    return _prepare_w4a16_packed_weights(
+        w13_fp4,
+        w13_blockscale,
+        w13_global_scale,
+        w2_fp4,
+        w2_blockscale,
+        w2_global_scale,
+        activation=activation,
+        params_dtype=params_dtype,
+        source_format="modelopt_nvfp4",
+        w13_layout=w13_layout,
+        reuse_input_storage=reuse_input_storage,
+    )
+
+
+def prepare_w4a16_modelopt_native_weights(
+    w13_fp4: torch.Tensor,
+    w13_blockscale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_blockscale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    source_format: str = "modelopt_nvfp4",
+    w13_layout: str = "w13",
+) -> W4A16ModelOptWeights:
+    """Prepare W4A16 metadata while keeping ModelOpt FP4 weights native.
+
+    This is the memory-safe path for GLM serving that needs A4 prefill and A16
+    decode in the same process. It keeps the checkpoint FP4 tensors resident
+    instead of materializing a second full W4A16 packed copy.
+    """
+    source_format = _normalize_source_format(source_format)
+    if source_format not in _MODEL_OPT_NVFP4_FORMATS:
+        raise ValueError(
+            "native W4A16 ModelOpt weights require source_format "
+            "'modelopt_nvfp4'"
+        )
+    w13_layout = _normalize_w13_layout(w13_layout)
+
+    shape = validate_w4a16_packed_inputs(
+        w13_fp4,
+        w13_global_scale,
+        w2_fp4,
+        w2_global_scale,
+        activation=activation,
+    )
+    num_experts = shape.num_experts
+    hidden_size = shape.hidden_size
+    intermediate_size = shape.intermediate_size
+    w13_rows = shape.w13_rows
+    is_gated = shape.is_gated
+
+    w13_scale = unswizzle_expert_scales(
+        w13_blockscale,
+        rows=w13_rows,
+        cols=hidden_size,
+    )
+    w2_scale = unswizzle_expert_scales(
+        w2_blockscale,
+        rows=hidden_size,
+        cols=intermediate_size,
+    )
+    native_w13_global_scale = _source_global_scale(
+        w13_global_scale,
+        source_format=source_format,
+    )
+    native_w2_global_scale = _source_global_scale(
+        w2_global_scale,
+        source_format=source_format,
+    )
+
+    # The W4A16 activation consumes FC1 output in gate/up logical order.
+    # Checkpoint-native ModelOpt GLM tensors are up/gate, while vLLM/FI can
+    # hand over gate/up tensors after its own W13 reorder. Keep that physical
+    # order explicit so source_format never implies a layout transformation.
+    w13_row_rotation = (
+        intermediate_size if is_gated and w13_layout == "w13" else None
+    )
+    packed_w13_scale, packed_w13_global_scale = _permute_nvfp4_scales(
+        w13_scale,
+        native_w13_global_scale,
+        size_k=hidden_size,
+        size_n=w13_rows,
+        a_dtype=params_dtype,
+        row_rotation=w13_row_rotation,
+    )
+    packed_w2_scale, packed_w2_global_scale = _permute_nvfp4_scales(
+        w2_scale,
+        native_w2_global_scale,
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        a_dtype=params_dtype,
+    )
+
+    return W4A16ModelOptWeights(
+        w13=w13_fp4,
+        w13_scale=packed_w13_scale,
+        w13_global_scale=packed_w13_global_scale,
+        w2=w2_fp4,
+        w2_scale=packed_w2_scale,
+        w2_global_scale=packed_w2_global_scale,
+        workspace=_make_workspace(w13_fp4.device, max_blocks_per_sm=4),
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        is_gated=is_gated,
+        params_dtype=params_dtype,
+        source_format=source_format,
+        micro_w13_scale=packed_w13_scale,
+        micro_w13_global_scale=_process_nvfp4_micro_global_scale_from_packed(
+            packed_w13_global_scale,
+            a_dtype=params_dtype,
+        ),
+        micro_w2_scale=packed_w2_scale,
+        micro_w2_global_scale=_process_nvfp4_micro_global_scale_from_packed(
+            packed_w2_global_scale,
+            a_dtype=params_dtype,
+        ),
+        w13_layout=w13_layout,
+    )
+
+
+def prepare_w4a16_e8m0_native_weights(
+    w13_fp4: torch.Tensor,
+    w13_e8m0_scale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_e8m0_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    w13_layout: str = "w13",
+) -> W4A16ModelOptWeights:
+    """Prepare native MXFP4 (E8M0 K/32) weights for the W4A16 path.
+
+    Keeps the FP4 weights resident as a single copy (``weight_layout="modelopt"``)
+    and carries two small scale forms so one object serves both kernels:
+    ``w13_scale``/``w2_scale`` are the packed E8M0 grid the main W4A16 GEMM reads
+    at med/large M, and ``micro_*`` are packed E8M0 grids in the native row order
+    that the small-M micro decode kernel reads. ``run_w4a16_moe`` routes small M
+    to micro and the rest to the main W4A16 kernel automatically.
+    """
+    w13_layout = _normalize_w13_layout(w13_layout)
+    shape = validate_w4a16_packed_inputs(
+        w13_fp4,
+        w13_global_scale,
+        w2_fp4,
+        w2_global_scale,
+        activation=activation,
+    )
+    num_experts = shape.num_experts
+    hidden_size = shape.hidden_size
+    intermediate_size = shape.intermediate_size
+    w13_rows = shape.w13_rows
+    is_gated = shape.is_gated
+    allow_w2_k_tail = intermediate_size % 32 != 0
+    padded_w13_scale_n = (
+        _e8m0_logical_tail_scale_n(w13_rows) if allow_w2_k_tail else w13_rows
+    )
+
+    w13_scale = _validate_e8m0_k32_scales(
+        w13_e8m0_scale,
+        rows=w13_rows,
+        cols=hidden_size,
+        name="w13_e8m0_scale",
+    )
+    w2_scale = _validate_e8m0_k32_scales(
+        w2_e8m0_scale,
+        rows=hidden_size,
+        cols=intermediate_size,
+        name="w2_e8m0_scale",
+        allow_k_tail=allow_w2_k_tail,
+    )
+    # Main-GEMM (med/large M) packed E8M0 scales. The "w13" (up_gate) layout
+    # needs the FC1 half-swap folded into the scale grid; the kernel applies the
+    # matching source_n_rotation to the native weights. micro reads the un-rotated
+    # grid and handles the layout itself (w13_gate_first).
+    w13_row_rotation = intermediate_size if (is_gated and w13_layout == "w13") else None
+    packed_w13_scale = _pack_e8m0_k32_scales(
+        w13_scale,
+        size_k=hidden_size,
+        size_n=w13_rows,
+        row_rotation=w13_row_rotation,
+        padded_size_n=padded_w13_scale_n,
+    )
+    micro_w13_scale = (
+        packed_w13_scale
+        if w13_row_rotation is None
+        else _pack_e8m0_k32_scales(
+            w13_scale,
+            size_k=hidden_size,
+            size_n=w13_rows,
+            padded_size_n=padded_w13_scale_n,
+        )
+    )
+    packed_w2_scale = _pack_e8m0_k32_scales(
+        w2_scale,
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        allow_k_tail=allow_w2_k_tail,
+    )
+    # Storage-compatible single grid: micro reads the SAME packed _pack_e8m0_k32
+    # scales the main GEMM reads (no separate K/16 micro grid).
+    w13_global = w13_global_scale.contiguous()
+    w2_global = w2_global_scale.contiguous()
+    return W4A16ModelOptWeights(
+        w13=w13_fp4,
+        w13_scale=packed_w13_scale,
+        w13_global_scale=w13_global,
+        w2=w2_fp4,
+        w2_scale=packed_w2_scale,
+        w2_global_scale=w2_global,
+        workspace=_make_workspace(w13_fp4.device, max_blocks_per_sm=4),
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        is_gated=is_gated,
+        params_dtype=params_dtype,
+        source_format="fp4_e8m0_k32",
+        scale_format="e8m0_k32",
+        micro_w13_scale=micro_w13_scale,
+        micro_w13_global_scale=w13_global,
+        micro_w2_scale=packed_w2_scale,
+        micro_w2_global_scale=w2_global,
+        w13_layout=w13_layout,
+    )
+
+
+def prepare_w4a16_compressed_tensors_weights(
+    w13_fp4: torch.Tensor,
+    w13_blockscale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_blockscale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    w13_layout: str = "w13",
+    reuse_input_storage: bool = False,
+) -> W4A16PackedWeights:
+    """Prepare CompressedTensors NVFP4 tensors into the W4A16 packed runtime layout.
+
+    The per-block scales are the normal NVFP4 K/16 scale grid in b12x swizzled
+    storage. The CT global scales are stored inverted relative to the ModelOpt
+    weight global scale convention, so they are inverted before packing.
+    """
+    return _prepare_w4a16_packed_weights(
+        w13_fp4,
+        w13_blockscale,
+        w13_global_scale,
+        w2_fp4,
+        w2_blockscale,
+        w2_global_scale,
+        activation=activation,
+        params_dtype=params_dtype,
+        source_format="compressed_tensors",
+        w13_layout=w13_layout,
+        reuse_input_storage=reuse_input_storage,
+    )
+
+
+def prepare_w4a16_fp4_e8m0_k32_weights(
+    w13_fp4: torch.Tensor,
+    w13_e8m0_scale: torch.Tensor,
+    w13_global_scale: torch.Tensor,
+    w2_fp4: torch.Tensor,
+    w2_e8m0_scale: torch.Tensor,
+    w2_global_scale: torch.Tensor,
+    *,
+    activation: str,
+    params_dtype: torch.dtype = torch.bfloat16,
+    w13_layout: str = "w13",
+    reuse_input_storage: bool = False,
+) -> W4A16PackedWeights:
+    """Prepare FP4 weights with E8M0 K/32 scales for W4A16.
+
+    The per-block source scales are [E, N, K/32] E8M0 bytes. They are only
+    saturated to the BF16 kernel's supported byte range and rearranged for
+    kernel access; they are not expanded to K/16 or folded into global scales.
+    """
+    w13_layout = _normalize_w13_layout(w13_layout)
+    shape = validate_w4a16_packed_inputs(
+        w13_fp4,
+        w13_global_scale,
+        w2_fp4,
+        w2_global_scale,
+        activation=activation,
+    )
+    num_experts = shape.num_experts
+    hidden_size = shape.hidden_size
+    intermediate_size = shape.intermediate_size
+    w13_rows = shape.w13_rows
+    is_gated = shape.is_gated
+
+    w13 = w13_fp4
+    w13_scale = _validate_e8m0_k32_scales(
+        w13_e8m0_scale,
+        rows=w13_rows,
+        cols=hidden_size,
+        name="w13_e8m0_scale",
+    )
+    w13_row_rotation = None
+    if is_gated and w13_layout != "w31":
+        w13_row_rotation = intermediate_size
+
+    w2_scale = _validate_e8m0_k32_scales(
+        w2_e8m0_scale,
+        rows=hidden_size,
+        cols=intermediate_size,
+        name="w2_e8m0_scale",
+    )
+
+    packed_w13 = _repack_weight(
+        w13 if reuse_input_storage else w13.contiguous(),
+        size_k=hidden_size,
+        size_n=w13_rows,
+        row_rotation=w13_row_rotation,
+        reuse_input_storage=reuse_input_storage,
+    )
+    packed_w2 = _repack_weight(
+        w2_fp4 if reuse_input_storage else w2_fp4.contiguous(),
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        reuse_input_storage=reuse_input_storage,
+    )
+    packed_w13_scale = _pack_e8m0_k32_scales(
+        w13_scale,
+        size_k=hidden_size,
+        size_n=w13_rows,
+        row_rotation=w13_row_rotation,
+        reuse_input_storage=reuse_input_storage,
+    )
+    packed_w2_scale = _pack_e8m0_k32_scales(
+        w2_scale,
+        size_k=intermediate_size,
+        size_n=hidden_size,
+        reuse_input_storage=reuse_input_storage,
+    )
+
+    return W4A16PackedWeights(
+        w13=packed_w13,
+        w13_scale=packed_w13_scale,
+        w13_global_scale=w13_global_scale.contiguous(),
+        w2=packed_w2,
+        w2_scale=packed_w2_scale,
+        w2_global_scale=w2_global_scale.contiguous(),
+        workspace=_make_workspace(w13_fp4.device, max_blocks_per_sm=4),
+        hidden_size=hidden_size,
+        intermediate_size=intermediate_size,
+        num_experts=num_experts,
+        is_gated=is_gated,
+        params_dtype=params_dtype,
+        source_format="fp4_e8m0_k32",
+        w13_layout=w13_layout,
+        scale_format="e8m0_k32",
+    )
+
+
+def prepare_w4a16_packed_weights(
+    *args,
+    source_format: str = "modelopt_nvfp4",
+    w13_layout: str = "w13",
+    **kwargs,
+) -> W4A16PackedWeights:
+    source_format = _normalize_source_format(source_format)
+    w13_layout = _normalize_w13_layout(w13_layout)
+    if source_format == "modelopt_nvfp4":
+        return prepare_w4a16_modelopt_nvfp4_weights(
+            *args, w13_layout=w13_layout, **kwargs
+        )
+    if source_format == "compressed_tensors":
+        return prepare_w4a16_compressed_tensors_weights(
+            *args, w13_layout=w13_layout, **kwargs
+        )
+    if source_format == "fp4_e8m0_k32":
+        return prepare_w4a16_fp4_e8m0_k32_weights(
+            *args, w13_layout=w13_layout, **kwargs
+        )
+    raise AssertionError(f"unhandled W4A16 source_format {source_format!r}")
+
+
+def make_w4a16_packed_buffers(
+    prepared: W4A16PackedWeights | W4A16ModelOptWeights,
+    *,
+    m: int,
+    topk: int,
+    dtype: torch.dtype,
+    device: torch.device,
+    route_num_experts: int | None = None,
+) -> W4A16PackedBuffers:
+    return _make_w4a16_packed_buffers(
+        prepared,
+        m=m,
+        topk=topk,
+        dtype=dtype,
+        device=device,
+        route_num_experts=route_num_experts,
+    )
+
+
+def prepare_nf3_moe_weights(
+    w13_codes: torch.Tensor,
+    w13_scale: torch.Tensor,
+    w2_codes: torch.Tensor,
+    w2_scale: torch.Tensor,
+    *,
+    activation: str,
+    fc1_tile_n: int,
+    fc2_tile_n: int,
+    params_dtype: torch.dtype = torch.bfloat16,
+) -> PreparedNF3MoeWeights:
+    """Pack NF3 codes/scales into the runtime "nf3_2p1" W4A16 layout.
+
+    Inputs are per-expert integer codes (0..7) in kernel-native output order
+    (gate/up already resolved for FC1) and per-group float scales ``t_s``:
+        w13_codes [E, 2*I, hidden]   w13_scale [E, 2*I, hidden//32]
+        w2_codes  [E, hidden, I]     w2_scale  [E, hidden, I//32]
+    ``fc1_tile_n`` / ``fc2_tile_n`` MUST equal the CTA N-tiles the kernel will
+    use (read them from the compiled W4A16FusedMoeCompileResult) -- the
+    flat-span layout is tile_n specific.
+    """
+    if params_dtype != torch.bfloat16:
+        raise ValueError("nf3_2p1 W4A16 weights are bf16-only for v1")
+    shape = validate_nf3_moe_inputs(
+        w13_codes,
+        w13_scale,
+        w2_codes,
+        w2_scale,
+        activation=activation,
+    )
+    device = w13_codes.device
+    packed_w13 = _nf3_pack_code_experts(
+        w13_codes, size_k=shape.hidden_size, size_n=shape.w13_rows, tile_n=fc1_tile_n
+    )
+    packed_w2 = _nf3_pack_code_experts(
+        w2_codes,
+        size_k=shape.intermediate_size,
+        size_n=shape.hidden_size,
+        tile_n=fc2_tile_n,
+    )
+    packed_w13_scale = _nf3_pack_scale_experts(
+        w13_scale, size_k=shape.hidden_size, size_n=shape.w13_rows
+    )
+    packed_w2_scale = _nf3_pack_scale_experts(
+        w2_scale, size_k=shape.intermediate_size, size_n=shape.hidden_size
+    )
+    global_scale = torch.full(
+        (shape.num_experts,), _NF3_SCALE_GLOBAL, dtype=torch.float32, device=device
+    )
+    return PreparedNF3MoeWeights(
+        w13=packed_w13,
+        w13_scale=packed_w13_scale,
+        w13_global_scale=global_scale,
+        w2=packed_w2,
+        w2_scale=packed_w2_scale,
+        w2_global_scale=global_scale.clone(),
+        workspace=_make_workspace(device, max_blocks_per_sm=4),
+        hidden_size=shape.hidden_size,
+        intermediate_size=shape.intermediate_size,
+        num_experts=shape.num_experts,
+        is_gated=shape.is_gated,
+        params_dtype=params_dtype,
+        fc1_tile_n=int(fc1_tile_n),
+        fc2_tile_n=int(fc2_tile_n),
+    )
+
+
+def _nf3_pack_selftest() -> None:
+    """Prove the packer matches the kernel's read+dequant chain (torch/CPU).
+
+    Packs random codes, then INDEPENDENTLY simulates the kernel's flat-span
+    staging + register read (unit = cur_group_id*(tile_n//2) + tid%(tile_n//2))
+    + packed_dequant_nf3x8 fragment placement in pure torch, and asserts the
+    reconstructed dequantized matrix equals codebook[codes] at every (N, K).
+    """
+    codebook = _NF3_CODEBOOK
+
+    def simulate(packed, size_k, size_n, tile_n, tile_k):
+        cta_threads = tile_n * tile_k // 64
+        b_sh_stride = tile_n // 2
+        cta_k_blocks = tile_k // 16
+        b_sh_stage = b_sh_stride * cta_k_blocks
+        b_sh_wr_iters = b_sh_stage // cta_threads
+        tb_n_warps = tile_n // 64
+        b_chunks = b_sh_stage * 12 // 16
+        wr_iters_nf3 = (b_chunks + cta_threads - 1) // cta_threads
+        ntile_stride = (size_k // 16) * (tile_n // 2)
+        n_tiles = size_n // tile_n
+        k_tiles = size_k // tile_k
+        packed = packed.tolist()
+        w = [[None] * size_n for _ in range(size_k)]
+
+        def u32(x):
+            return x & 0xFFFFFFFF
+
+        for nt in range(n_tiles):
+            for tile_idx in range(k_tiles):
+                span_base_unit = (
+                    nt * ntile_stride + tile_idx * cta_k_blocks * b_sh_stride
+                )
+                smem = {}
+                for i in range(wr_iters_nf3):
+                    for tid in range(cta_threads):
+                        c = i * cta_threads + tid
+                        if c >= b_chunks:
+                            continue
+                        for word in range(4):
+                            smem[c * 4 + word] = u32(
+                                packed[span_base_unit * 3 + c * 4 + word]
+                            )
+                for tid in range(cta_threads):
+                    warp_row = (tid // 32) // tb_n_warps
+                    for kk in range(b_sh_wr_iters):
+                        cur = b_sh_wr_iters * warp_row + kk
+                        unit = cur * b_sh_stride + (tid % b_sh_stride)
+                        lo0 = smem[unit * 3 + 0]
+                        lo1 = smem[unit * 3 + 1]
+                        hi = smem[unit * 3 + 2]
+                        R = tile_idx * cta_k_blocks + cur
+                        p = tid % b_sh_stride
+                        for jj in range(4):
+                            lo_w = lo0 if (jj // 2) == 0 else lo1
+                            lo16 = (lo_w >> (16 * (jj % 2))) & 0xFFFF
+                            hi8 = (hi >> (8 * jj)) & 0xFF
+                            la = lo16 & 0xFF
+                            lb = (lo16 >> 8) & 0xFF
+                            ha = hi8 & 0xF
+                            hb = (hi8 >> 4) & 0xF
+
+                            def code(byte2, nib1, j):
+                                return ((byte2 >> (2 * j)) & 3) | (
+                                    ((nib1 >> j) & 1) << 2
+                                )
+
+                            cds = [code(la, ha, j) for j in range(4)] + [
+                                code(lb, hb, j) for j in range(4)
+                            ]
+                            wru = p + (tile_n // 2) * nt
+                            n64 = wru // 32
+                            th = wru % 32
+                            tc_col = th // 4
+                            tc_row = (th % 4) * 2
+                            col1 = jj * 16 + tc_col
+                            c1 = n64 * 64 + col1
+                            c2 = c1 + 8
+                            k0 = R * 16 + tc_row
+                            w[k0 + 0][c1] = codebook[cds[0]]
+                            w[k0 + 1][c1] = codebook[cds[1]]
+                            w[k0 + 8][c1] = codebook[cds[2]]
+                            w[k0 + 9][c1] = codebook[cds[3]]
+                            w[k0 + 0][c2] = codebook[cds[4]]
+                            w[k0 + 1][c2] = codebook[cds[5]]
+                            w[k0 + 8][c2] = codebook[cds[6]]
+                            w[k0 + 9][c2] = codebook[cds[7]]
+        return w
+
+    torch.manual_seed(0)
+    cases = [
+        (256, 128, 128, 128),
+        (256, 128, 128, 64),
+        (64, 256, 256, 64),
+        (512, 256, 256, 64),
+    ]
+    for size_k, size_n, tile_n, tile_k in cases:
+        codes = torch.randint(0, 8, (size_n, size_k), dtype=torch.int64)
+        packed = _nf3_pack_codes(
+            codes, size_k=size_k, size_n=size_n, tile_n=tile_n
+        )
+        w = simulate(packed, size_k, size_n, tile_n, tile_k)
+        for k in range(size_k):
+            for n in range(size_n):
+                expect = _NF3_CODEBOOK[int(codes[n, k])]
+                got = w[k][n]
+                assert got is not None, f"unfilled ({k},{n}) for {(size_k, size_n, tile_n, tile_k)}"
+                assert abs(got - expect) < 1e-9, (
+                    f"mismatch at ({k},{n}) for {(size_k, size_n, tile_n, tile_k)}: "
+                    f"{got} != {expect}"
+                )
+    print("nf3 pack self-test PASSED")
+
+
+__all__ = [
+    "PreparedNF3MoeWeights",
+    "W4A16PackedBuffers",
+    "W4A16ModelOptWeights",
+    "W4A16PackedWeights",
+    "make_w4a16_packed_buffers",
+    "prepare_nf3_moe_weights",
+    "prepare_w4a16_compressed_tensors_weights",
+    "prepare_w4a16_e8m0_native_weights",
+    "prepare_w4a16_fp4_e8m0_k32_weights",
+    "prepare_w4a16_modelopt_native_weights",
+    "prepare_w4a16_modelopt_nvfp4_weights",
+    "prepare_w4a16_packed_weights",
+]

+ 1 - 0
docker-images/glm52-nf3-hybrid/overlay/hybrid.pth

@@ -0,0 +1 @@
+import hybrid_loader

+ 197 - 24
docker-images/glm52-nf3-hybrid/overlay/hybrid_loader.py

@@ -43,6 +43,12 @@ _HYBRID_PROFILE = os.environ.get("HYBRID_PROFILE", "0") == "1"  # per-tier CUDA-
 # top-k + fused sum. Measured standalone: 0.27ms vs prod 0.36-0.38ms/launch at
 # decode m, numerics rel<0.012. Gated OFF by default; flag-off = today's bytes.
 _HYBRID_TC_DECODE = os.environ.get("HYBRID_TC_DECODE", "0") == "1"
+# v2-lite fusion: tiers A+B share ONE fc2_out staging (disjoint (token,k)
+# route slots via the -1-dropping expert maps); tier B compiles with
+# zero_fc2_output=False so A's staged routes survive, and a SINGLE topk_sum
+# over the union replaces (sum_a, sum_b, add). Packed path only — tc-decode
+# steps keep the per-tier fused-sum + add.
+_HYBRID_FUSE_V2 = os.environ.get("HYBRID_FUSE_V2", "0") == "1"
 _prof_store = {"n": 0, "a_ms": 0.0, "b_ms": 0.0, "rows": 0, "pend": []}
 _dbg_first_build = [True]   # keep kept-tier originals for ONLY the first b12x layer (VRAM)
 _HBM = None  # cached hybrid_bit_map (per-process); read once from the checkpoint config.json
@@ -59,11 +65,21 @@ _HBM = None  # cached hybrid_bit_map (per-process); read once from the checkpoin
 _B12X_NF3_TILES = (64, 256, 64, 256)
 _B12X_NF3_DECODE_M = 8          # <=8 -> preplanned TC-decode launch (fused topk sum)
 _B12X_NF3_MAX_TOKENS = int(os.environ.get("HYBRID_B12X_MAX_TOKENS", "8192"))
+# v1.5 stream-fusion: run tier-A (NVFP4) and tier-B (NF3) launches on CONCURRENT
+# streams instead of sequentially. Tier B gets its OWN scratch set (buffers_b) so
+# nothing races; fork/join via pre-created events (graph-capture legal). Failure
+# mode if the kernel host ignores torch stream ctx = launches serialize on one
+# stream = no overlap, still correct. Default OFF.
+_HYBRID_FUSE_STREAMS = os.environ.get("HYBRID_FUSE_STREAMS", "0") == "1"
 _b12x_nf3_rt = {                # module-level, shared across ALL layers (one scratch set)
     "max_m": None,              # fixed at first apply: max(env, first-call m)
     "topk": None,
     "launches": {},             # (E, layout, scale_fmt, topk, max_m) -> (dec, pre)
     "buffers": None,            # W4A16PackedBuffers planned at max_m/route_E=256
+    "buffers_b": None,          # v1.5: tier-B scratch set (only when FUSE_STREAMS)
+    "stream_b": None,           # v1.5: side stream + fork/join events
+    "ev_fork": None,
+    "ev_join": None,
     "out_a": None,              # [max_m, H] bf16 per-tier outputs (fully overwritten
     "out_b": None,              #  by every run_w4a16_moe call that uses them)
 }
@@ -177,14 +193,19 @@ def _patch(mod):
     def _from_config(cls, config):
         obj = _orig_fc(cls, config)
         hbm = None
+        kf = None
         if isinstance(config, dict):
             hbm = config.get("hybrid_bit_map")
-            if hbm is None and isinstance(config.get("quantization"), dict):
-                hbm = config["quantization"].get("hybrid_bit_map")
+            kf = config.get("kept_format")
+            if isinstance(config.get("quantization"), dict):
+                hbm = hbm or config["quantization"].get("hybrid_bit_map")
+                kf = kf or config["quantization"].get("kept_format")
         try:
             obj.hybrid_bit_map = hbm
+            obj.kept_format = kf
             print(f"[hybrid_loader] hybrid_bit_map stashed: "
-                  f"{len(hbm) if hbm else 0} layers", flush=True)
+                  f"{len(hbm) if hbm else 0} layers"
+                  f"{' kept_format=' + kf if kf else ''}", flush=True)
         except Exception as e:
             print("[hybrid_loader] stash failed:", e, flush=True)
         return obj
@@ -209,6 +230,11 @@ def _patch(mod):
         def create_weights(self, layer, num_experts, hidden_size,
                            intermediate_size_per_partition, params_dtype, **extra):
             bits = self._bits(layer)
+            # v3: kept tier is MXFP4 (e2m1 + ue8m0/32) ONLY for hybrid-mapped
+            # layers; the MTP/uniform layer (bits None) stays NVFP4.
+            kept_mx = (bits is not None and
+                       getattr(self.quant_config, "kept_format", None)
+                       == "mxfp4_e8m0k32")
             if bits is None:
                 # Non-hybrid MoE (the MTP/nextn layer) — its experts are uniform NVFP4.
                 # Route it through OUR path as all-kept (bits=4) so it uses our Triton NVFP4
@@ -225,10 +251,12 @@ def _patch(mod):
             Kn, Km = len(kept), len(dem)
             layer.hyb = {"remap": {**{e: (0, i) for i, e in enumerate(kept)},
                                    **{e: (1, i) for i, e in enumerate(dem)}},
-                         "H": H, "I": I, "gs": gs, "E": num_experts}
+                         "H": H, "I": I, "gs": gs, "E": num_experts,
+                         "kept_mx": kept_mx}
             _pfx = getattr(layer, "prefix", None) or getattr(layer, "layer_name", "?")
             layer.hyb["lname"] = str(_pfx)
-            print(f"[hybrid] {_pfx}: {Kn}NVFP4 + {Km}NF3 (tp{tp_rank}/{tp_size} I={I})", flush=True)
+            print(f"[hybrid] {_pfx}: {Kn}{'MXFP4' if kept_mx else 'NVFP4'} + "
+                  f"{Km}NF3 (tp{tp_rank}/{tp_size} I={I})", flush=True)
 
             def wl(param, loaded, name_mapped=None, *, shard_id=None,
                    expert_id=None, return_success=False, **kw):
@@ -283,12 +311,15 @@ def _patch(mod):
             P("w2_weight_scale_2",  (mk(Kn),), torch.float32)
             P("w2_input_scale",     (1,), torch.float32)
             # --- real block-scale storage (filled by dispatcher; not mapping-routed) ---
-            for nm, sh in [("w13_nv_s", (mk(Kn), 2 * I, H // gs)),
-                           ("w13_nf_s", (mk(Km), 2 * I, H // 32)),
-                           ("w2_nv_s",  (mk(Kn), H, I // gs)),
-                           ("w2_nf_s",  (mk(Km), H, I // 32))]:
+            # mx kept tier: ue8m0 scales at group 32 (uint8) instead of e4m3/gs.
+            nv_gs = 32 if kept_mx else gs
+            nv_dt = torch.uint8 if kept_mx else torch.float8_e4m3fn
+            for nm, sh, dt_ in [("w13_nv_s", (mk(Kn), 2 * I, H // nv_gs), nv_dt),
+                                ("w13_nf_s", (mk(Km), 2 * I, H // 32), torch.float8_e4m3fn),
+                                ("w2_nv_s",  (mk(Kn), H, I // nv_gs), nv_dt),
+                                ("w2_nf_s",  (mk(Km), H, I // 32), torch.float8_e4m3fn)]:
                 layer.register_parameter(nm, torch.nn.Parameter(
-                    torch.zeros(sh, dtype=torch.float8_e4m3fn,
+                    torch.zeros(sh, dtype=dt_,
                                 device=torch.cuda.current_device()), requires_grad=False))
 
         def _build_kept_b12x(self, layer):
@@ -396,6 +427,70 @@ def _patch(mod):
                   f"kept_tp={kept_moe.moe_parallel_config.tp_size}, "
                   f"w13={tuple(KL.w13_weight.shape)})", flush=True)
 
+        def _build_kept_mxfp4(self, layer):
+            """v3 kept tier: MXFP4 (e2m1 + ue8m0/32) over the Kn kept experts
+            via the stock mxfp4 oracle chain. The B12X backend's convert is a
+            passthrough — repacking happens inside process_weights_after_loading.
+            A16 by default; A8 opt-in via HYBRID_MX_A8=1 (KLD-gate before daily).
+            Mirrors _build_kept_b12x's no-parallel-clone + keepalive shape."""
+            import dataclasses
+            import os as _os
+            import torch.nn as _nn
+            from vllm.model_executor.layers.fused_moe.oracle.mxfp4 import (
+                select_mxfp4_moe_backend, convert_weight_to_mxfp4_moe_kernel_format,
+                make_mxfp4_moe_quant_config, make_mxfp4_moe_kernel)
+            from vllm.model_executor.layers.fused_moe.config import FusedMoEParallelConfig
+            from vllm.model_executor.layers.fused_moe.activation import MoEActivation
+            E = layer.hyb["E"]
+            dev = layer.w13_weight.device
+            remap = layer.hyb["remap"]
+            Kn = sum(1 for (grp, li) in remap.values() if grp == 0)
+            ispp = self.moe.intermediate_size_per_partition
+            kept_moe = dataclasses.replace(
+                self.moe, num_experts=Kn, num_local_experts=Kn, num_logical_experts=Kn,
+                intermediate_size=ispp,
+                moe_parallel_config=FusedMoEParallelConfig.make_no_parallel())
+            act_key = None
+            if _os.environ.get("HYBRID_MX_A8", "0") == "1":
+                from vllm.model_executor.layers.quantization.utils.quant_utils import (
+                    kFp8StaticTensorSym)
+                act_key = kFp8StaticTensorSym
+            backend, experts_cls = select_mxfp4_moe_backend(
+                kept_moe, activation_key=act_key)
+            KL = _nn.Module()
+            KL.activation = getattr(layer, "activation", MoEActivation.SILU)
+            KL.moe_config = kept_moe
+            KL.local_num_experts = Kn
+            cw13, cw2, cw13s, cw2s, _b13, _b2 = (
+                convert_weight_to_mxfp4_moe_kernel_format(
+                    backend, KL, layer.w13_weight, layer.w2_weight,
+                    layer.w13_nv_s, layer.w2_nv_s))
+            for k, v in [("w13_weight", cw13), ("w13_weight_scale", cw13s),
+                         ("w2_weight", cw2), ("w2_weight_scale", cw2s)]:
+                setattr(KL, k, v)
+            qconf = make_mxfp4_moe_quant_config(backend, cw13s, cw2s, layer=KL)
+            kk = make_mxfp4_moe_kernel(qconf, kept_moe, experts_cls,
+                                       routing_tables=None)
+            kk.fused_experts.process_weights_after_loading(KL)
+            self.moe_kernel = kk
+            mx_remap = torch.full((E,), Kn, dtype=torch.int32, device=dev)
+            for g, (grp, li) in remap.items():
+                if grp == 0:
+                    mx_remap[g] = li
+            layer.hyb["kept_kernel"] = kk
+            layer.hyb["kept_KL"] = KL
+            layer.hyb["nvfp4_remap"] = mx_remap
+            layer.hyb["_keepalive_mx"] = (cw13, cw2, cw13s, cw2s)
+            for nm in ("w13_weight", "w2_weight", "w13_nv_s", "w2_nv_s"):
+                if hasattr(layer, nm):
+                    try:
+                        delattr(layer, nm)
+                    except Exception:
+                        setattr(layer, nm, None)
+            print(f"[hybrid] {getattr(layer, 'prefix', '?')}: kept MXFP4 kernel "
+                  f"built (Kn={Kn}, backend={backend}, a8={act_key is not None})",
+                  flush=True)
+
         def _build_b12x_nf3(self, layer):
             """HYBRID_KEPT=b12x_nf3: drive BOTH tiers through the b12x W4A16
             CuteDSL MoE kernel.
@@ -545,9 +640,10 @@ def _patch(mod):
             max_shared_mem = int(getattr(
                 props, "shared_memory_per_block_optin", 101_376))
 
-            def launches(prepared):
+            def launches(prepared, zero_out=True):
                 key = (prepared.num_experts, prepared.weight_layout,
-                       prepared.scale_format, st["topk"], st["max_m"], H, I)
+                       prepared.scale_format, st["topk"], st["max_m"], H, I,
+                       zero_out)
                 got = st["launches"].get(key)
                 if got is not None:
                     return got
@@ -569,7 +665,7 @@ def _patch(mod):
                 # ALU, not HBM bytes, and decode is bandwidth-bound.
                 cap_slots = max_packed_route_slots(st["max_m"] * st["topk"], 64, E)
                 pre = compile_w4a16_fused_moe(
-                    size_m=st["max_m"], zero_fc2_output=True,
+                    size_m=st["max_m"], zero_fc2_output=zero_out,
                     moe_block_size=64, max_m_blocks=(cap_slots + 63) // 64,
                     direct_topk_routes=False, tc_decode_fused_sum=False,
                     **common)
@@ -610,7 +706,13 @@ def _patch(mod):
             if hyb.get("prepA") is not None:
                 hyb["launchA"] = launches(hyb["prepA"])
             if hyb.get("prepB") is not None:
-                hyb["launchB"] = launches(hyb["prepB"])
+                # v2-lite: B must NOT zero the shared staging (A staged first).
+                # A-only / B-only debug tiers are incompatible with that.
+                if _HYBRID_FUSE_V2 and _HYBRID_TIER in ("a", "b"):
+                    raise RuntimeError("HYBRID_FUSE_V2 is incompatible with "
+                                       "HYBRID_TIER=a/b")
+                hyb["launchB"] = launches(hyb["prepB"],
+                                          zero_out=not _HYBRID_FUSE_V2)
             if st["buffers"] is None:
                 prep_any = hyb.get("prepA") or hyb.get("prepB")
                 if prep_any is None:
@@ -637,6 +739,38 @@ def _patch(mod):
                 st["buffers"] = buf
                 st["out_a"] = buf.output          # [max_m, H], fully overwritten per call
                 st["out_b"] = torch.empty_like(buf.output)
+                if _HYBRID_FUSE_STREAMS:
+                    # v1.5: tier-B gets its OWN scratch (no cross-stream races) +
+                    # a dedicated side stream + pre-created fork/join events
+                    # (event creation during graph capture is illegal -> here).
+                    buf_b = make_w4a16_packed_buffers(
+                        prep_any, m=st["max_m"], topk=st["topk"],
+                        dtype=torch.bfloat16, device=dev, route_num_experts=E)
+                    if (buf_b.packed_route_indices.numel() < need_slots
+                            or buf_b.block_expert_ids.numel() < need_blocks):
+                        buf_b = dataclasses.replace(
+                            buf_b,
+                            packed_route_indices=torch.empty(
+                                (need_slots,), dtype=torch.int32, device=dev),
+                            block_expert_ids=torch.empty(
+                                (need_blocks,), dtype=torch.int32, device=dev))
+                    st["buffers_b"] = buf_b
+                    st["out_b"] = buf_b.output
+                    st["stream_b"] = torch.cuda.Stream(device=dev)
+                    st["ev_fork"] = torch.cuda.Event()
+                    st["ev_join"] = torch.cuda.Event()
+                    print("[hybrid] v1.5 stream-fusion armed (tier-B scratch + "
+                          "side stream)", flush=True)
+                if _HYBRID_FUSE_V2:
+                    # dedicated union staging: fc2 results from BOTH tiers
+                    # live here across the A->B sequence. Must NOT alias the
+                    # fc1 workspace (kernel default) — B's FC1 would clobber
+                    # A's staged rows (learned the hard way: /Optics/ loops).
+                    st["fc2_union"] = torch.empty(
+                        (st["max_m"] * st["topk"] * H,),
+                        dtype=torch.bfloat16, device=dev)
+                    print("[hybrid] v2-lite fusion armed (dedicated union "
+                          "staging + single topk_sum)", flush=True)
                 print(f"[hybrid] b12x_nf3 runtime ready: max_m={st['max_m']} "
                       f"topk={st['topk']} sms={sms}", flush=True)
             hyb["_rt_ready"] = True
@@ -685,8 +819,10 @@ def _patch(mod):
                 tw = tw.contiguous()
             buf = st["buffers"]
 
-            def run(prepared, launch_pair, emap, out):
-                use_dec = (_HYBRID_TC_DECODE and decode
+            def run(prepared, launch_pair, emap, out, rbuf=None,
+                    skip_sum=False, force_pre=False, fc2u=None):
+                rbuf = buf if rbuf is None else rbuf
+                use_dec = (_HYBRID_TC_DECODE and decode and not force_pre
                            and launch_pair[0] is not launch_pair[1])
                 launch = launch_pair[0] if use_dec else launch_pair[1]
                 ids = (topk_ids if topk_ids.dtype == torch.int32
@@ -704,16 +840,21 @@ def _patch(mod):
                 return run_w4a16_moe(
                     x, prepared, tw, ids,
                     activation="silu",
-                    intermediate_cache13=buf.intermediate_cache13,
-                    intermediate_cache2=buf.intermediate_cache2,
+                    intermediate_cache13=rbuf.intermediate_cache13,
+                    intermediate_cache2=rbuf.intermediate_cache2,
                     output=out,
-                    fc1_c_tmp=buf.fc1_c_tmp, fc2_c_tmp=buf.fc2_c_tmp,
-                    packed_route_indices=buf.packed_route_indices,
-                    block_expert_ids=buf.block_expert_ids,
-                    packed_route_count=buf.packed_route_count,
-                    expert_offsets=buf.expert_offsets,
+                    fc1_c_tmp=rbuf.fc1_c_tmp, fc2_c_tmp=rbuf.fc2_c_tmp,
+                    packed_route_indices=rbuf.packed_route_indices,
+                    block_expert_ids=rbuf.block_expert_ids,
+                    packed_route_count=rbuf.packed_route_count,
+                    expert_offsets=rbuf.expert_offsets,
                     expert_map=em,
-                    fused_launch=launch)
+                    fused_launch=launch,
+                    # v2-lite kwargs exist only in our tcfix kernel; pass
+                    # them only when engaged so stock kernel dirs stay
+                    # boot-compatible with this loader.
+                    **({"skip_topk_sum": True} if skip_sum else {}),
+                    **({"fc2_out_override": fc2u} if fc2u is not None else {}))
 
             if hyb["Km"] == 0:
                 # uniform-NVFP4 layer (MTP/nextn): single tier through OUR launcher
@@ -731,6 +872,38 @@ def _patch(mod):
             elif _HYBRID_TIER == "b":
                 out = run(hyb["prepB"], hyb["launchB"], hyb["emap_b"],
                           st["out_b"][:m]).clone()
+            elif _HYBRID_FUSE_V2 and not (
+                    _HYBRID_TC_DECODE and decode
+                    and hyb["launchA"][0] is not hyb["launchA"][1]
+                    and hyb["launchB"][0] is not hyb["launchB"][1]):
+                # v2-lite: A zeros the shared fc2 staging and stages its
+                # routes; B (compiled zero_fc2_output=False) stages its
+                # disjoint routes; ONE topk_sum over the union -> out_b is
+                # the complete result. No out_a+out_b add. force_pre pins
+                # both tiers to the packed path (a lone tc-armed tier would
+                # bypass staging and double-count).
+                run(hyb["prepA"], hyb["launchA"], hyb["emap_a"],
+                    st["out_a"][:m], skip_sum=True, force_pre=True,
+                    fc2u=st["fc2_union"])
+                out = run(hyb["prepB"], hyb["launchB"], hyb["emap_b"],
+                          st["out_b"][:m], force_pre=True,
+                          fc2u=st["fc2_union"])
+            elif _HYBRID_FUSE_STREAMS and st["stream_b"] is not None:
+                # v1.5: fork tier-B onto the side stream so both grouped GEMMs
+                # co-schedule on the SMs; join before the sum. Events pre-created
+                # (graph-capture legal); tier-B uses its own scratch set.
+                s = torch.cuda.current_stream()
+                sb = st["stream_b"]
+                st["ev_fork"].record(s)
+                sb.wait_event(st["ev_fork"])
+                out_a = run(hyb["prepA"], hyb["launchA"], hyb["emap_a"],
+                            st["out_a"][:m])
+                with torch.cuda.stream(sb):
+                    out_b = run(hyb["prepB"], hyb["launchB"], hyb["emap_b"],
+                                st["out_b"][:m], rbuf=st["buffers_b"])
+                st["ev_join"].record(sb)
+                s.wait_event(st["ev_join"])
+                out = out_a + out_b
             else:
                 prof = _HYBRID_PROFILE and m > 64
                 if prof:

+ 1254 - 0
docker-images/glm52-nf3-hybrid/overlay/vllm/v1/attention/backends/mla/indexer.py

@@ -0,0 +1,1254 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
+import os
+from dataclasses import dataclass
+
+import numpy as np
+import torch
+
+import vllm.envs as envs
+from vllm.config import VllmConfig
+from vllm.logger import init_logger
+from vllm.platforms import current_platform
+from vllm.triton_utils import tl, triton
+from vllm.utils.math_utils import cdiv
+from vllm.utils.platform_utils import num_compute_units
+from vllm.v1.attention.backend import (
+    AttentionBackend,
+    AttentionCGSupport,
+    AttentionMetadataBuilder,
+    CommonAttentionMetadata,
+    MultipleOf,
+)
+from vllm.v1.attention.backends.mla.compressor_utils import get_compressed_slot_mapping
+from vllm.v1.attention.backends.utils import get_dcp_local_seq_lens
+from vllm.v1.kv_cache_interface import AttentionSpec, MLAAttentionSpec
+from vllm.v1.worker.cp_utils import get_total_cp_world_size
+
+logger = init_logger(__name__)
+
+_B12X_PAGED_INDEX_SUPERTILE_K_DEFAULT = 32768
+_B12X_PAGED_INDEX_TILE_BLOCK_K = 512
+
+
+def _get_b12x_paged_indexer_supertile_k() -> int:
+    raw = os.environ.get("B12X_PAGED_INDEX_SUPERTILE_K")
+    tokens = _B12X_PAGED_INDEX_SUPERTILE_K_DEFAULT if raw is None else int(raw)
+    tokens = max(tokens, _B12X_PAGED_INDEX_TILE_BLOCK_K)
+    return (
+        (tokens + _B12X_PAGED_INDEX_TILE_BLOCK_K - 1)
+        // _B12X_PAGED_INDEX_TILE_BLOCK_K
+        * _B12X_PAGED_INDEX_TILE_BLOCK_K
+    )
+
+
+@triton.jit
+def _prepare_uniform_decode_kernel(
+    seq_lens_ptr,
+    decode_seq_lens_ptr,
+    block_table_ptr,
+    block_table_stride,
+    expanded_block_table_ptr,
+    expanded_bt_stride,
+    decode_lens_ptr,
+    max_decode_len,
+    BLOCK_SIZE: tl.constexpr,
+):
+    idx = tl.program_id(0)
+    req_id = idx // max_decode_len
+    local_idx = idx % max_decode_len
+
+    # Compute number of KVs attended to by this token.
+    seq_len = tl.load(seq_lens_ptr + req_id)
+    per_token_seq_len = seq_len - max_decode_len + local_idx + 1
+    tl.store(decode_seq_lens_ptr + idx, per_token_seq_len)
+
+    # Copy block table row.
+    src = block_table_ptr + req_id * block_table_stride
+    dst = expanded_block_table_ptr + idx * expanded_bt_stride
+    for i in tl.range(0, expanded_bt_stride, BLOCK_SIZE):
+        off = i + tl.arange(0, BLOCK_SIZE)
+        mask = off < expanded_bt_stride
+        src_block = tl.load(src + off, mask=mask)
+        tl.store(dst + off, src_block, mask=mask)
+
+    # All reqs now have decode_len = 1.
+    tl.store(decode_lens_ptr + idx, 1)
+
+
+def split_indexer_prefill_chunks(
+    seq_lens_cpu: torch.Tensor | np.ndarray,
+    query_lens_cpu: torch.Tensor | np.ndarray,
+    workspace_size: int,
+    max_logits_bytes: int,
+    request_offset: int = 0,
+) -> list[tuple[slice, slice]]:
+    """
+    Split prefill requests into chunks for the sparse indexer, respecting:
+    - N constraint: total_seq_lens <= workspace_size (existing O(N) workspace)
+    - Logits constraint: M * N * 4 <= max_logits_bytes
+
+    When a single request-level chunk still exceeds the logits budget,
+    sub-chunks on the query dimension (M) to bound peak memory.
+
+    Returns list of (req_slice, query_slice) tuples.
+    """
+    if isinstance(seq_lens_cpu, torch.Tensor):
+        seq_lens_cpu = seq_lens_cpu.numpy()
+    if isinstance(query_lens_cpu, torch.Tensor):
+        query_lens_cpu = query_lens_cpu.numpy()
+
+    chunks: list[tuple[slice, slice]] = []
+    n = len(seq_lens_cpu)
+    max_logits_elems = max_logits_bytes // 4
+    end = 0
+
+    while end < n:
+        start, chunk_m, chunk_n = end, 0, 0
+
+        while end < n:
+            q, s = int(query_lens_cpu[end]), int(seq_lens_cpu[end])
+            new_m, new_n = chunk_m + q, chunk_n + s
+            if new_n <= workspace_size and new_m * new_n <= max_logits_elems:
+                chunk_m, chunk_n = new_m, new_n
+                end += 1
+            else:
+                break
+
+        # A single request can exceed the budget, requiring sub-chunking
+        # on the query dimension.
+        if end == start:
+            chunk_m, chunk_n = int(query_lens_cpu[end]), int(seq_lens_cpu[end])
+            end += 1
+
+        req_slice = slice(start + request_offset, end + request_offset)
+        max_q = max(1, max_logits_elems // chunk_n) if chunk_n > 0 else chunk_m
+        for q_off in range(0, chunk_m, max_q):
+            sub_m = min(max_q, chunk_m - q_off)
+            chunks.append((req_slice, slice(q_off, q_off + sub_m)))
+
+    return chunks
+
+
+class DeepseekV32IndexerBackend(AttentionBackend):
+    @staticmethod
+    def get_name() -> str:
+        return "DEEPSEEK_V32_INDEXER"
+
+    @staticmethod
+    def get_supported_kernel_block_sizes() -> list[int | MultipleOf]:
+        return [1, 64] if current_platform.is_rocm() else [64]
+
+    @classmethod
+    def get_supported_head_sizes(cls) -> list[int]:
+        return [32, 64, 128]
+
+    @staticmethod
+    def get_builder_cls() -> type["DeepseekV32IndexerMetadataBuilder"]:
+        return DeepseekV32IndexerMetadataBuilder
+
+    @staticmethod
+    def get_kv_cache_shape(
+        num_blocks: int,
+        block_size: int,
+        num_kv_heads: int,
+        head_size: int,
+        cache_dtype_str: str = "auto",
+    ) -> tuple[int, ...]:
+        assert num_kv_heads == 1
+        return (num_blocks, block_size, head_size)
+
+    @staticmethod
+    def get_kv_cache_stride_order(
+        include_num_layers_dimension: bool = False,
+    ) -> tuple[int, ...]:
+        if include_num_layers_dimension:
+            # DeepseekV32Indexer kernels do not support cross-layer
+            # KV cache layout. Identity permutation keeps num_layers
+            # first, signaling incompatibility.
+            return (0, 1, 2, 3)
+        return (0, 1, 2)
+
+
+class B12xNonCompressedIndexerBackend(DeepseekV32IndexerBackend):
+    @staticmethod
+    def get_name() -> str:
+        return "B12X_NON_COMPRESSED_INDEXER"
+
+
+class DeepseekV4IndexerBackend(DeepseekV32IndexerBackend):
+    @staticmethod
+    def get_name() -> str:
+        return "DEEPSEEK_V4_INDEXER"
+
+    @staticmethod
+    def get_supported_kernel_block_sizes() -> list[int | MultipleOf]:
+        return [256]
+
+
+@dataclass
+class DeepseekV32IndexerPrefillChunkMetadata:
+    block_table: torch.Tensor
+    cu_seqlen_ks: torch.Tensor
+    cu_seqlen_ke: torch.Tensor
+    cu_seq_lens: torch.Tensor
+    token_to_seq: torch.Tensor
+    total_seq_lens: int
+    token_start: int
+    token_end: int
+    num_reqs: int
+    skip_kv_gather: bool = False
+
+
+@dataclass
+class DeepseekV32IndexerPrefillMetadata:
+    chunks: list[DeepseekV32IndexerPrefillChunkMetadata]
+
+
+@dataclass
+class DeepSeekV32IndexerDecodeMetadata:
+    block_table: torch.Tensor
+    # seq_lens: per-token effective context lengths.
+    #   - flatten path / plain decode: 1D (batch_size,)
+    #   - native MTP path: 2D (B, next_n) where [b,j] = L_b - next_n + j + 1
+    # Both fp8_fp4_paged_mqa_logits and the topk kernels accept both shapes.
+    seq_lens: torch.Tensor
+    max_seq_len: int
+    decode_lens: torch.Tensor
+    requires_padding: bool
+    schedule_metadata: torch.Tensor | None
+    compress_ratio: int = 1
+    # Live scorer window (max compressed context across the batch) in cache
+    # tokens, computed host-side in build() — a metadata tensor read by the
+    # captured indexer kernel, never an in-kernel reduction. None => b12x uses
+    # the capacity cap.
+    active_width: torch.Tensor | None = None
+
+
+@dataclass
+class DeepseekV32IndexerMetadata:
+    # FIXME (zyongye)
+    # hacky way to access the data now, need to be in chunked meta
+    seq_lens: torch.Tensor
+    max_seq_len: int
+    slot_mapping: torch.Tensor
+
+    # New for MLA (compared to FlashAttention)
+    # For handling prefill decode split
+    num_decodes: int
+    num_decode_tokens: int
+    num_prefills: int
+    num_prefill_tokens: int
+
+    decode: DeepSeekV32IndexerDecodeMetadata | None = None
+    prefill: DeepseekV32IndexerPrefillMetadata | None = None
+    dcp_world_size: int = 1
+    dcp_rank: int = 0
+    cp_interleave_size: int = 1
+
+
+def get_max_prefill_buffer_size(vllm_config: VllmConfig):
+    max_model_len = vllm_config.model_config.max_model_len
+    # NOTE(Chen): 40 is a magic number for controlling the prefill buffer size.
+    # Each entry is 128 fp8 bytes and 4 scale bytes for a total of 132 bytes.
+    # The flashmla_sparse backend uses a workspace size of 5 * max_model_len.
+    # The memory usage of the workspace there is 576 * 2 bytes; so we size this as
+    # (576 * 2 // 132) * 5 = 40 to maximize this workspace size while still fitting
+    # within the flashmla_sparse workspace.
+    # For DeepSeek-V3.2, the max_model_len is 163840.
+    #   40 * 163840 * 132 = 865075200 bytes = 825 MB
+    return max_model_len * 40
+
+
+class DeepseekV32IndexerMetadataBuilder(AttentionMetadataBuilder):
+    reorder_batch_threshold: int = 1
+
+    @classmethod
+    def get_cudagraph_support(
+        cls,
+        vllm_config: VllmConfig,
+        kv_cache_spec: AttentionSpec,
+    ) -> AttentionCGSupport:
+        return AttentionCGSupport.UNIFORM_BATCH
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.storage_block_size = int(self.kv_cache_spec.storage_block_size)
+        scheduler_config = self.vllm_config.scheduler_config
+        parallel_config = self.vllm_config.parallel_config
+        self.dcp_world_size = parallel_config.decode_context_parallel_size
+        self.pcp_world_size = parallel_config.prefill_context_parallel_size
+        self.cp_kv_cache_interleave_size = (
+            parallel_config.cp_kv_cache_interleave_size
+        )
+        self.dcp_rank = 0
+        if self.dcp_world_size > 1:
+            assert self.pcp_world_size == 1, (
+                "DeepseekV32IndexerMetadataBuilder supports DCP but not PCP."
+            )
+            from vllm.distributed.parallel_state import get_dcp_group
+
+            self.dcp_rank = get_dcp_group().rank_in_group
+        # NOTE(Chen):an estimated max size of flattened_kv. Need to double check.
+        self.max_prefill_buffer_size = get_max_prefill_buffer_size(self.vllm_config)
+        self.num_speculative_tokens = (
+            self.vllm_config.speculative_config.num_speculative_tokens
+            if self.vllm_config.speculative_config
+            else 0
+        )
+        self.use_fp4_indexer_cache = (
+            self.vllm_config.attention_config.use_fp4_indexer_cache
+        )
+
+        assert (
+            current_platform.is_device_capability_family(100)
+            or not self.use_fp4_indexer_cache
+        ), (
+            "use_fp4_indexer_cache requires Blackwell datacenter GPUs "
+            "(sm_10x, e.g. B200/GB200); sm_120 (consumer Blackwell) and "
+            "earlier architectures are not supported."
+        )
+
+        next_n = self.num_speculative_tokens + 1
+        self.reorder_batch_threshold += self.num_speculative_tokens
+        # NOTE: SM100 datacenter GPUs support any next_n natively via the
+        # multi-atom paged MQA logits kernels (FP8 and FP4 indexer
+        # caches). Outside the SM100 family the FP8
+        # paged MQA logits kernel only supports next_n in (1, 2)
+        # (deepgemm smxx_fp8_fp4_paged_mqa_logits.hpp:233), so flatten there.
+        self.use_flattening = not current_platform.is_device_capability_family(
+            100
+        ) and next_n not in (1, 2)
+        logger.info_once(
+            "DSA indexer decode path: use_flattening=%s "
+            "(next_n=%d, use_fp4_indexer_cache=%s)",
+            self.use_flattening,
+            next_n,
+            self.use_fp4_indexer_cache,
+        )
+
+        sm_count = num_compute_units(self.device.index)
+        self.num_sms = sm_count
+
+        self.offsets_buffer = torch.arange(
+            next_n, device=self.device, dtype=torch.int32
+        )
+        self.decode_lens_buffer = torch.zeros(
+            (scheduler_config.max_num_batched_tokens,),
+            dtype=torch.int32,
+            device=self.device,
+        )
+        # Shared workspace for decode seq_lens. Native MTP views this as
+        # (B, max_decode_len) at runtime, keeping context_lens contiguous even
+        # when max_decode_len is smaller than next_n.
+        self.decode_seq_lens_buffer = torch.zeros(
+            (scheduler_config.max_num_batched_tokens,),
+            dtype=torch.int32,
+            device=self.device,
+        )
+        self.arange_buffer = torch.arange(
+            max(
+                scheduler_config.max_num_seqs * next_n,
+                scheduler_config.max_num_batched_tokens,
+            ),
+            dtype=torch.int32,
+            device=self.device,
+        )
+        max_num_blocks_per_req = cdiv(
+            self.vllm_config.model_config.max_model_len,
+            self.kv_cache_spec.block_size * get_total_cp_world_size(),
+        )
+        self.expanded_block_table_buffer = torch.zeros(
+            (
+                scheduler_config.max_num_batched_tokens,
+                max_num_blocks_per_req + 8,  # reaper fix: runner tables run wider (461 vs 462 off-by-one)
+            ),
+            dtype=torch.int32,
+            device=self.device,
+        )
+
+        # See: DeepGMM/csrc/apis/attention.hpp
+        self.scheduler_metadata_buffer = torch.empty(
+            (self.num_sms + 1, 2), dtype=torch.int32, device=self.device
+        )
+
+        # Persistent live-active-width buffer for the b12x indexer decode
+        # scorer window. Filled host-side each build() (outside cudagraph
+        # capture) and read by the captured kernel at a stable address.
+        self.b12x_active_width_buffer = torch.zeros(
+            (1,), dtype=torch.int32, device=self.device
+        )
+
+        # KV compression. Default to 1 for no compression.
+        self.compress_ratio = 1
+        # Get compress_ratio for DeepseekV4 support
+        if isinstance(self.kv_cache_spec, MLAAttentionSpec):
+            self.compress_ratio = self.kv_cache_spec.compress_ratio
+
+        _prewarm_prefill_chunk_metadata_kernel(
+            device=self.device,
+            dcp_world_size=self.dcp_world_size,
+            dcp_rank=self.dcp_rank,
+            cp_kv_cache_interleave_size=self.cp_kv_cache_interleave_size,
+            compress_ratio=self.compress_ratio,
+        )
+
+        # DCP writes the indexer KV cache through rank-local pages even when
+        # compress_ratio == 1 (GLM/Kimi). Keep the mapped slots graph-stable.
+        if self.compress_ratio > 1 or self.dcp_world_size > 1:
+            self.compressed_slot_mapping_buffer = torch.zeros(
+                (scheduler_config.max_num_batched_tokens,),
+                dtype=torch.int64,
+                device=self.device,
+            )
+
+        # Pre-allocate buffers for CUDA graph compatibility when
+        if self.compress_ratio > 1:
+            # compress_ratio > 1 (DeepseekV4)
+            # Buffer for compressed seq_lens in decode path
+            self.expanded_seq_lens_buffer = torch.zeros(
+                (scheduler_config.max_num_batched_tokens,),
+                dtype=torch.int32,
+                device=self.device,
+            )
+
+    def _maybe_build_b12x_schedule_metadata(
+        self,
+        seq_lens: torch.Tensor,
+        block_table: torch.Tensor,
+        num_decode_tokens: int,
+        requires_padding: bool,
+    ) -> torch.Tensor | None:
+        if not envs.VLLM_USE_B12X_SPARSE_INDEXER or requires_padding:
+            return None
+
+        schedule_seq_lens = seq_lens
+        if schedule_seq_lens.dim() == 2:
+            batch_size, next_n = schedule_seq_lens.shape
+            if num_decode_tokens != int(batch_size * next_n):
+                return None
+            schedule_seq_lens = schedule_seq_lens.reshape(-1)
+        if schedule_seq_lens.dim() != 1:
+            return None
+
+        from b12x.attention.indexer import (
+            build_paged_mqa_schedule_metadata,
+            uses_paged_mqa_schedule,
+        )
+
+        if not uses_paged_mqa_schedule(
+            q_rows=int(schedule_seq_lens.shape[0]),
+            max_pages=int(block_table.shape[1]),
+        ):
+            return None
+
+        return build_paged_mqa_schedule_metadata(
+            schedule_seq_lens.contiguous(),
+            self.storage_block_size,
+            self.num_sms,
+            out=self.scheduler_metadata_buffer,
+        )
+
+    def _maybe_build_deep_gemm_schedule_metadata(
+        self,
+        seq_lens: torch.Tensor,
+    ) -> torch.Tensor:
+        if current_platform.is_cuda():
+            from vllm.utils.deep_gemm import (
+                get_paged_mqa_logits_metadata,
+                has_deep_gemm,
+            )
+
+            if has_deep_gemm():
+                self.scheduler_metadata_buffer[:] = get_paged_mqa_logits_metadata(
+                    seq_lens,
+                    self.storage_block_size,
+                    self.num_sms,
+                )
+        return self.scheduler_metadata_buffer
+
+    def _decode_topk_max_seq_len_from_cpu(
+        self,
+        common_attn_metadata: CommonAttentionMetadata,
+        num_decodes: int,
+        decode_lens_np: np.ndarray,
+        max_decode_len: int,
+        use_native: bool,
+        dcp_local_seq_lens_cpu: torch.Tensor | None,
+    ) -> int | None:
+        """Return the exact decode max seq-len without reading CUDA tensors.
+
+        B12X needs a host scalar for metadata/scheduling.  Computing it with
+        ``seq_lens.max().item()`` synchronizes every decode step.  The model
+        runner already maintains CPU shadows for normal decode; use those
+        directly and mirror only the shape transforms that can affect the max.
+        If async-spec has made the CPU shadow non-authoritative, return None so
+        the caller can fall back to a safe graph-stable bound.
+        """
+        cpu_seq_lens = (
+            dcp_local_seq_lens_cpu
+            if dcp_local_seq_lens_cpu is not None
+            else common_attn_metadata._seq_lens_cpu
+        )
+        if cpu_seq_lens is None:
+            return None
+        if cpu_seq_lens.device.type != "cpu":
+            return None
+
+        seq_lens_np = cpu_seq_lens[:num_decodes].numpy()
+        if seq_lens_np.size == 0:
+            return 0
+
+        # Flattened variable-length MTP writes only real decode tokens and
+        # zero-fills the tail.  Ignore padded decode rows to match that max.
+        if not use_native and max_decode_len > 1:
+            valid_decode_rows = decode_lens_np[:num_decodes] > 0
+            if not bool(np.any(valid_decode_rows)):
+                return 0
+            seq_lens_np = seq_lens_np[valid_decode_rows]
+
+        max_seq_len = int(seq_lens_np.max())
+        if self.compress_ratio > 1:
+            max_seq_len //= self.compress_ratio
+        return max_seq_len
+
+    def _prepare_decode_tensors(
+        self,
+        seq_lens: torch.Tensor,
+        block_table: torch.Tensor,
+        decode_lens: torch.Tensor,
+        decode_lens_np: np.ndarray,
+        query_start_loc: torch.Tensor,
+        num_decodes: int,
+        num_decode_tokens: int,
+        use_native: bool,
+        next_n: int,
+        max_decode_len: int,
+        global_seq_lens: torch.Tensor | None = None,
+    ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, int, bool]:
+        """Expand seq_lens/block_table/decode_lens for the decode kernels.
+
+        Flatten path (not use_native, max_decode_len > 1):
+          Each multi-token decode request is expanded into individual
+          single-token entries so the kernel always sees next_n=1.
+
+        Native path (use_native or max_decode_len == 1):
+          Plain decode or spec-decode with 2D per-token context lengths.
+
+        Returns (seq_lens, block_table, decode_lens, batch_size, requires_padding).
+        seq_lens is 1D (batch_size,) for flatten/plain, 2D (B, max_decode_len)
+        for native MTP.
+        """
+        min_decode_len = int(decode_lens_np.min())
+        if not use_native and max_decode_len > 1:
+            assert self.decode_seq_lens_buffer.dim() == 1
+            if min_decode_len == max_decode_len:
+                # Uniform decode lengths.
+                num_decode_tokens = num_decodes * max_decode_len
+                _prepare_uniform_decode_kernel[(num_decode_tokens,)](
+                    seq_lens,
+                    self.decode_seq_lens_buffer,
+                    block_table,
+                    block_table.stride(0),
+                    self.expanded_block_table_buffer,
+                    self.expanded_block_table_buffer.stride(0),
+                    self.decode_lens_buffer,
+                    max_decode_len,
+                    BLOCK_SIZE=1024,
+                )
+                if global_seq_lens is not None and self.dcp_world_size > 1:
+                    expanded_global = (
+                        global_seq_lens[:num_decodes].unsqueeze(1)
+                        - max_decode_len
+                        + 1
+                        + self.offsets_buffer[:max_decode_len]
+                    ).reshape(-1)
+                    self.decode_seq_lens_buffer[:num_decode_tokens].copy_(
+                        get_dcp_local_seq_lens(
+                            expanded_global,
+                            self.dcp_world_size,
+                            self.dcp_rank,
+                            self.cp_kv_cache_interleave_size,
+                        ),
+                        non_blocking=True,
+                    )
+                self.decode_seq_lens_buffer[num_decode_tokens:] = 0
+                seq_lens = self.decode_seq_lens_buffer[:num_decode_tokens]
+                block_table = self.expanded_block_table_buffer[:num_decode_tokens]
+                decode_lens = self.decode_lens_buffer[:num_decode_tokens]
+                return seq_lens, block_table, decode_lens, num_decode_tokens, False
+            else:
+                # Variable decode lengths.
+                # Assume 4 requests with seq_lens [10, 7, 12, 0] (the final req is
+                # padding) and decode_lens [3, 1, 4, 0] in the below example comments.
+                # The context lengths are therefore
+                # [10-3, 7-1, 12-4, 0-0] = [7, 6, 8, 0].
+
+                # 3 + 1 + 4 + 0 = 8
+                actual_expanded = int(decode_lens_np.sum())
+
+                # Fuse expanded_base and expanded_starts into a single
+                # repeat_interleave:
+                # seq_len_i = (context_start[b] - query_start_loc[b]) + arange[i] + 1
+                # where context_start[b] = seq_lens[b] - decode_lens[b].
+                # Example: offsets = [7-0, 6-3, 8-4, 0-8] = [7, 3, 4, -8]
+                # expanded_offsets  = [7, 7, 7, 3, 4, 4, 4, 4]
+                # result            = [8, 9, 10, 7, 9, 10, 11, 12]
+                seq_lens_for_expansion = (
+                    global_seq_lens if global_seq_lens is not None else seq_lens
+                )
+                expanded_offsets = torch.repeat_interleave(
+                    seq_lens_for_expansion - decode_lens - query_start_loc,
+                    decode_lens,
+                    output_size=actual_expanded,
+                )
+
+                # [8, 9, 10, 7, 9, 10, 11, 12, ...] where ... is unused buffer space
+                expanded_seq_lens = (
+                    expanded_offsets + self.arange_buffer[:actual_expanded] + 1
+                )
+                if global_seq_lens is not None and self.dcp_world_size > 1:
+                    expanded_seq_lens = get_dcp_local_seq_lens(
+                        expanded_seq_lens,
+                        self.dcp_world_size,
+                        self.dcp_rank,
+                        self.cp_kv_cache_interleave_size,
+                    )
+                self.decode_seq_lens_buffer[:actual_expanded] = expanded_seq_lens
+                self.decode_seq_lens_buffer[actual_expanded:] = 0
+                seq_lens = self.decode_seq_lens_buffer[:num_decode_tokens]
+
+                # Give each of the flattened entries the same block table row as the
+                # original request.
+                if int(block_table.shape[1]) > int(
+                        self.expanded_block_table_buffer.shape[1]):
+                    # reaper fix: grow-on-demand if a batch arrives wider than alloc
+                    self.expanded_block_table_buffer = torch.zeros(
+                        (int(self.expanded_block_table_buffer.shape[0]),
+                         int(block_table.shape[1])),
+                        dtype=torch.int32,
+                        device=self.expanded_block_table_buffer.device,
+                    )
+                bt_w = int(block_table.shape[1])
+                self.expanded_block_table_buffer[:actual_expanded, :bt_w] = (
+                    torch.repeat_interleave(
+                        block_table, decode_lens, dim=0, output_size=actual_expanded
+                    )
+                )
+                if actual_expanded < num_decode_tokens:
+                    self.expanded_block_table_buffer[
+                        actual_expanded:num_decode_tokens, 0
+                    ] = 0
+                block_table = self.expanded_block_table_buffer[:num_decode_tokens]
+
+                # All reqs now have decode_len=1
+                self.decode_lens_buffer[:num_decode_tokens] = 1
+                decode_lens = self.decode_lens_buffer[:num_decode_tokens]
+                return seq_lens, block_table, decode_lens, num_decode_tokens, False
+        else:
+            # Native path: plain decode (next_n==1) or spec decode
+            # with 2D per-token context lengths (next_n > 1).
+            #
+            # When decode_lens are not truly uniform (e.g. some requests have
+            # decode_len < next_n due to padding or short prefills), the simple
+            # reshape in sparse_attn_indexer won't work. Use pack_seq_triton
+            # (requires_padding) instead.
+            requires_padding = min_decode_len != max_decode_len
+            if use_native and next_n > 1:
+                assert self.decode_seq_lens_buffer.dim() == 1
+                # (B, max_decode_len): token j attends to
+                # L - max_decode_len + j + 1 KV tokens.
+                seq_lens_buffer = self.decode_seq_lens_buffer[
+                    : num_decodes * max_decode_len
+                ].view(num_decodes, max_decode_len)
+                seq_lens_for_expansion = (
+                    global_seq_lens if global_seq_lens is not None else seq_lens
+                )
+                expanded_seq_lens = (
+                    seq_lens_for_expansion.unsqueeze(1)
+                    - max_decode_len
+                    + 1
+                    + self.offsets_buffer[:max_decode_len]
+                )
+                if global_seq_lens is not None and self.dcp_world_size > 1:
+                    expanded_seq_lens = get_dcp_local_seq_lens(
+                        expanded_seq_lens.reshape(-1),
+                        self.dcp_world_size,
+                        self.dcp_rank,
+                        self.cp_kv_cache_interleave_size,
+                    ).view(num_decodes, max_decode_len)
+                seq_lens_buffer[:] = expanded_seq_lens
+                seq_lens = seq_lens_buffer
+            return seq_lens, block_table, decode_lens, num_decodes, requires_padding
+
+    def build(
+        self,
+        common_prefix_len: int,
+        common_attn_metadata: CommonAttentionMetadata,
+        fast_build: bool = False,
+    ) -> DeepseekV32IndexerMetadata:
+        num_reqs = common_attn_metadata.num_reqs
+        num_tokens = common_attn_metadata.num_actual_tokens
+        query_start_loc = common_attn_metadata.query_start_loc
+        query_start_loc_cpu = common_attn_metadata.query_start_loc_cpu
+        if common_attn_metadata.batch_topology is not None:
+            query_start_loc_np = common_attn_metadata.batch_topology.query_start_loc_np[
+                : num_reqs + 1
+            ]
+            query_lens_np = common_attn_metadata.batch_topology.query_lens_np
+        else:
+            query_start_loc_np = query_start_loc_cpu.numpy()
+            query_lens_np = np.diff(query_start_loc_np)
+        seq_lens = common_attn_metadata.seq_lens
+        slot_mapping = common_attn_metadata.slot_mapping
+        block_table = common_attn_metadata.block_table_tensor
+        use_dcp_local_kv = (
+            self.dcp_world_size > 1
+            and common_attn_metadata.dcp_local_seq_lens is not None
+        )
+        effective_dcp_world_size = self.dcp_world_size if use_dcp_local_kv else 1
+        effective_dcp_rank = self.dcp_rank if use_dcp_local_kv else 0
+
+        num_decodes, num_prefills, num_decode_tokens, num_prefill_tokens = (
+            common_attn_metadata.split_decodes_and_prefills(
+                decode_threshold=self.reorder_batch_threshold,
+                require_uniform=not self.use_flattening,
+            )
+        )
+
+        if (num_decodes + num_prefills != num_reqs
+                or num_decode_tokens + num_prefill_tokens != num_tokens):
+            raise AssertionError(
+                f"[idxfix-diag] split mismatch: decodes={num_decodes} "
+                f"prefills={num_prefills} reqs={num_reqs} "
+                f"decode_toks={num_decode_tokens} prefill_toks={num_prefill_tokens} "
+                f"toks={num_tokens} threshold={self.reorder_batch_threshold} "
+                f"uniform={not self.use_flattening} "
+                f"qsl={common_attn_metadata.query_start_loc_cpu.tolist()[:12]} "
+                f"seq={common_attn_metadata._seq_lens_cpu.tolist()[:12] if common_attn_metadata._seq_lens_cpu is not None else None}"
+            )
+
+        compressed_slot_mapping = slot_mapping
+        logical_compressed_seq_lens = seq_lens
+        compressed_seq_lens = seq_lens
+        if self.compress_ratio > 1 or use_dcp_local_kv:
+            compressed_slot_mapping = get_compressed_slot_mapping(
+                num_tokens,
+                query_start_loc,
+                seq_lens,
+                block_table,
+                self.storage_block_size,
+                self.compress_ratio,
+                out=self.compressed_slot_mapping_buffer,
+                dcp_world_size=effective_dcp_world_size,
+                dcp_rank=effective_dcp_rank,
+                cp_kv_cache_interleave_size=self.cp_kv_cache_interleave_size,
+            )
+            logical_compressed_seq_lens = seq_lens // self.compress_ratio
+            compressed_seq_lens = logical_compressed_seq_lens
+        if use_dcp_local_kv:
+            compressed_seq_lens = get_dcp_local_seq_lens(
+                logical_compressed_seq_lens,
+                self.dcp_world_size,
+                self.dcp_rank,
+                self.cp_kv_cache_interleave_size,
+            )
+
+        prefill_metadata = None
+        if num_prefills > 0:
+            # This CPU value is an upper bound for async-spec extend rows.  It
+            # is safe for chunking/allocation because CUDA metadata below is
+            # built from exact device seq_lens and gather ignores the tail.
+            assert common_attn_metadata.seq_lens_cpu_upper_bound is not None
+            seq_lens_cpu = common_attn_metadata.seq_lens_cpu_upper_bound
+            logical_compressed_seq_lens_cpu = (
+                seq_lens_cpu // self.compress_ratio
+                if self.compress_ratio > 1
+                else seq_lens_cpu
+            )
+            compressed_seq_lens_cpu = logical_compressed_seq_lens_cpu
+            if use_dcp_local_kv:
+                compressed_seq_lens_cpu = get_dcp_local_seq_lens(
+                    logical_compressed_seq_lens_cpu,
+                    self.dcp_world_size,
+                    self.dcp_rank,
+                    self.cp_kv_cache_interleave_size,
+                )
+            compressed_seq_lens_cpu_np = compressed_seq_lens_cpu.numpy()
+            prefill_query_lens_cpu = query_lens_np[
+                num_decodes : num_decodes + num_prefills
+            ]
+            max_logits_bytes = envs.VLLM_SPARSE_INDEXER_MAX_LOGITS_MB * 1024 * 1024
+            if envs.VLLM_USE_B12X_SPARSE_INDEXER:
+                chunk_specs = []
+                b12x_budget_seq_lens = np.array(
+                    [_get_b12x_paged_indexer_supertile_k()],
+                    dtype=compressed_seq_lens_cpu_np.dtype,
+                )
+                for prefill_idx in range(num_prefills):
+                    req_idx = num_decodes + prefill_idx
+                    chunk_specs.extend(
+                        split_indexer_prefill_chunks(
+                            b12x_budget_seq_lens,
+                            prefill_query_lens_cpu[
+                                prefill_idx : prefill_idx + 1
+                            ],
+                            self.max_prefill_buffer_size,
+                            max_logits_bytes,
+                            request_offset=req_idx,
+                        )
+                    )
+            else:
+                chunk_specs = split_indexer_prefill_chunks(
+                    compressed_seq_lens_cpu_np[num_decodes:],
+                    prefill_query_lens_cpu,
+                    self.max_prefill_buffer_size,
+                    max_logits_bytes,
+                    request_offset=num_decodes,
+                )
+
+            chunks = []
+            for req_slice, query_slice in chunk_specs:
+                metadata = build_prefill_chunk_metadata(
+                    req_slice.start,
+                    req_slice.stop,
+                    query_start_loc,
+                    query_start_loc_cpu,
+                    seq_lens,
+                    compressed_seq_lens,
+                    compressed_seq_lens_cpu,
+                    common_attn_metadata.block_table_tensor,
+                    self.compress_ratio,
+                    query_slice=query_slice,
+                    query_start_loc_np=query_start_loc_np,
+                    compressed_seq_lens_np=compressed_seq_lens_cpu_np,
+                    skip_kv_gather=query_slice.start > 0,
+                    dcp_world_size=effective_dcp_world_size,
+                    dcp_rank=effective_dcp_rank,
+                    cp_kv_cache_interleave_size=self.cp_kv_cache_interleave_size,
+                )
+                # Skip when total_seq_lens is 0 (i.e., no compressed token).
+                if metadata is not None:
+                    chunks.append(metadata)
+            prefill_metadata = DeepseekV32IndexerPrefillMetadata(chunks)
+
+        decode_metadata = None
+        if num_decodes > 0:
+            torch.diff(
+                common_attn_metadata.query_start_loc[: num_decodes + 1],
+                out=self.decode_lens_buffer[:num_decodes],
+            )
+            decode_lens = self.decode_lens_buffer[:num_decodes]
+            decode_lens_np = query_lens_np[:num_decodes]
+
+            global_decode_seq_lens = common_attn_metadata.seq_lens[:num_decodes]
+            dcp_local_seq_lens = (
+                common_attn_metadata.dcp_local_seq_lens[:num_decodes]
+                if self.compress_ratio == 1
+                and use_dcp_local_kv
+                and common_attn_metadata.dcp_local_seq_lens is not None
+                else None
+            )
+            dcp_local_seq_lens_cpu = (
+                common_attn_metadata.dcp_local_seq_lens_cpu[:num_decodes]
+                if dcp_local_seq_lens is not None
+                and common_attn_metadata.dcp_local_seq_lens_cpu is not None
+                else None
+            )
+            seq_lens = (
+                dcp_local_seq_lens
+                if dcp_local_seq_lens is not None
+                else global_decode_seq_lens
+            )
+            block_table = common_attn_metadata.block_table_tensor[:num_decodes, ...]
+
+            max_decode_len = int(decode_lens_np.max())
+            next_n = 1 + self.num_speculative_tokens
+            use_native = not self.use_flattening and max_decode_len <= next_n
+
+            seq_lens, block_table, decode_lens, batch_size, requires_padding = (
+                self._prepare_decode_tensors(
+                    seq_lens=seq_lens,
+                    block_table=block_table,
+                    decode_lens=decode_lens,
+                    decode_lens_np=decode_lens_np,
+                    query_start_loc=common_attn_metadata.query_start_loc[:num_decodes],
+                    num_decodes=num_decodes,
+                    num_decode_tokens=num_decode_tokens,
+                    use_native=use_native,
+                    next_n=next_n,
+                    max_decode_len=max_decode_len,
+                    global_seq_lens=global_decode_seq_lens
+                    if dcp_local_seq_lens is not None
+                    else None,
+                )
+            )
+
+            # For DeepseekV4 (compress_ratio > 1), the indexer KV cache stores
+            # compressed tokens. Convert uncompressed seq_lens to compressed.
+            if self.compress_ratio > 1:
+                # True iff seq_lens aliases decode_seq_lens_buffer (flatten or
+                # native wrote it); False iff it aliases common_attn_metadata.
+                seq_lens_is_local_view = (use_native and next_n > 1) or (
+                    not use_native and max_decode_len > 1
+                )
+                if seq_lens_is_local_view:
+                    seq_lens //= self.compress_ratio
+                    if use_dcp_local_kv:
+                        if seq_lens.dim() == 1:
+                            dcp_seq_lens = get_dcp_local_seq_lens(
+                                seq_lens,
+                                self.dcp_world_size,
+                                self.dcp_rank,
+                                self.cp_kv_cache_interleave_size,
+                            )
+                        else:
+                            dcp_seq_lens = get_dcp_local_seq_lens(
+                                seq_lens.reshape(-1),
+                                self.dcp_world_size,
+                                self.dcp_rank,
+                                self.cp_kv_cache_interleave_size,
+                            ).view(seq_lens.shape)
+                        seq_lens.copy_(dcp_seq_lens)
+                else:
+                    # Copy to avoid mutating shared state; keeps CG address stable.
+                    compressed_decode_seq_lens = seq_lens // self.compress_ratio
+                    if use_dcp_local_kv:
+                        compressed_decode_seq_lens = get_dcp_local_seq_lens(
+                            compressed_decode_seq_lens,
+                            self.dcp_world_size,
+                            self.dcp_rank,
+                            self.cp_kv_cache_interleave_size,
+                        )
+                    self.expanded_seq_lens_buffer[:num_decodes] = (
+                        compressed_decode_seq_lens
+                    )
+                    self.expanded_seq_lens_buffer[num_decodes:num_decode_tokens] = 0
+                    seq_lens = self.expanded_seq_lens_buffer[:num_decode_tokens]
+            elif use_dcp_local_kv and dcp_local_seq_lens is None:
+                if seq_lens.dim() == 1:
+                    seq_lens = get_dcp_local_seq_lens(
+                        seq_lens,
+                        self.dcp_world_size,
+                        self.dcp_rank,
+                        self.cp_kv_cache_interleave_size,
+                    )
+                else:
+                    seq_lens_shape = seq_lens.shape
+                    seq_lens = get_dcp_local_seq_lens(
+                        seq_lens.reshape(-1),
+                        self.dcp_world_size,
+                        self.dcp_rank,
+                        self.cp_kv_cache_interleave_size,
+                    ).view(seq_lens_shape)
+
+            # Non-MTP: deep_gemm paged MQA logits requires 2D context_lens
+            # (csrc/apis/attention.hpp). Unsqueeze to (B, 1) so downstream
+            # kernels see the same (B, next_n) layout as the MTP path.
+            if seq_lens.dim() == 1:
+                seq_lens = seq_lens.unsqueeze(-1)
+
+            active_width = None
+            active_width_tokens = None
+            if self.compress_ratio > 1:
+                active_width_tokens = -(
+                    -int(common_attn_metadata.max_seq_len) //
+                    self.compress_ratio
+                )
+            if envs.VLLM_USE_B12X_SPARSE_INDEXER:
+                # Live scorer window in cache tokens. ceil(max_seq_len /
+                # compress_ratio) is an upper bound on the max compressed
+                # context across the batch, so windowing to it is top-k-identical
+                # to the capacity cap and only skips wasted k-tiles. Computed on
+                # the host here (metadata-prep, outside cudagraph capture) and
+                # filled into the persistent buffer the captured kernel reads.
+                if active_width_tokens is None:
+                    active_width_tokens = int(common_attn_metadata.max_seq_len)
+                self.b12x_active_width_buffer.fill_(active_width_tokens)
+                active_width = self.b12x_active_width_buffer
+                if self.compress_ratio > 1:
+                    # Compressed-MLA models already bound the B12X scorer with
+                    # active_width. Avoiding a host reduction here removes a
+                    # per-decode sync without changing the scorer window.
+                    decode_topk_max_seq_len = active_width_tokens
+                else:
+                    # GLM/Kimi-style uncompressed indexer rows need the exact
+                    # scalar for best throughput; use the CPU shadow maintained
+                    # by the runner instead of synchronizing on seq_lens.
+                    decode_topk_max_seq_len = (
+                        self._decode_topk_max_seq_len_from_cpu(
+                            common_attn_metadata,
+                            num_decodes,
+                            decode_lens_np,
+                            max_decode_len,
+                            use_native,
+                            dcp_local_seq_lens_cpu,
+                        )
+                    )
+                    if decode_topk_max_seq_len is None:
+                        # Async-spec can make GPU seq_lens authoritative.  In
+                        # that mode there is no exact host scalar without a
+                        # sync, so use the same graph-stable live-window bound
+                        # already consumed by the B12X scorer.
+                        decode_topk_max_seq_len = active_width_tokens
+            elif active_width_tokens is not None:
+                # DeepGEMM still receives exact per-row seq_lens on device.
+                # The scalar max_seq_len is only a host scorer bound; using the
+                # metadata upper bound avoids a per-token CUDA scalar sync.
+                decode_topk_max_seq_len = active_width_tokens
+            else:
+                decode_topk_max_seq_len = int(seq_lens.max().item())
+
+            if envs.VLLM_USE_B12X_SPARSE_INDEXER:
+                schedule_metadata = self._maybe_build_b12x_schedule_metadata(
+                    seq_lens,
+                    block_table,
+                    num_decode_tokens,
+                    requires_padding,
+                )
+            else:
+                # DeepGEMM is required for paged MQA logits on CUDA devices.
+                schedule_metadata = self._maybe_build_deep_gemm_schedule_metadata(
+                    seq_lens
+                )
+
+            decode_metadata = DeepSeekV32IndexerDecodeMetadata(
+                block_table=block_table,
+                seq_lens=seq_lens,
+                max_seq_len=decode_topk_max_seq_len,
+                decode_lens=decode_lens,
+                requires_padding=requires_padding,
+                schedule_metadata=schedule_metadata,
+                compress_ratio=self.compress_ratio,
+                active_width=active_width,
+            )
+
+        attn_metadata = DeepseekV32IndexerMetadata(
+            seq_lens=common_attn_metadata.seq_lens,
+            max_seq_len=common_attn_metadata.max_seq_len,
+            slot_mapping=compressed_slot_mapping,
+            num_decodes=num_decodes,
+            num_decode_tokens=num_decode_tokens,
+            num_prefills=num_prefills,
+            num_prefill_tokens=num_prefill_tokens,
+            prefill=prefill_metadata,
+            decode=decode_metadata,
+            dcp_world_size=effective_dcp_world_size,
+            dcp_rank=effective_dcp_rank,
+            cp_interleave_size=self.cp_kv_cache_interleave_size,
+        )
+
+        return attn_metadata
+
+
+def build_prefill_chunk_metadata(
+    start_idx: int,
+    end_idx: int,
+    query_start_loc: torch.Tensor,
+    query_start_loc_cpu: torch.Tensor,
+    uncompressed_seq_lens: torch.Tensor,
+    compressed_seq_lens: torch.Tensor,
+    compressed_seq_lens_cpu: torch.Tensor,
+    block_table: torch.Tensor,
+    compress_ratio: int,
+    query_slice: slice | None = None,
+    query_start_loc_np: np.ndarray | None = None,
+    compressed_seq_lens_np: np.ndarray | None = None,
+    skip_kv_gather: bool = False,
+    dcp_world_size: int = 1,
+    dcp_rank: int = 0,
+    cp_kv_cache_interleave_size: int = 1,
+) -> DeepseekV32IndexerPrefillChunkMetadata | None:
+    if compressed_seq_lens_np is not None:
+        total_seq_lens = int(compressed_seq_lens_np[start_idx:end_idx].sum())
+    else:
+        total_seq_lens = compressed_seq_lens_cpu[start_idx:end_idx].sum().item()
+    if total_seq_lens == 0:
+        return None
+
+    num_reqs = end_idx - start_idx
+    device = block_table.device
+    token_to_seq = torch.empty(total_seq_lens, dtype=torch.int32, device=device)
+
+    cu_seq_lens = torch.empty(num_reqs + 1, dtype=torch.int32, device=device)
+    # Assigning to slice avoids cpu sync.
+    cu_seq_lens[:1] = 0
+    torch.cumsum(compressed_seq_lens[start_idx:end_idx], dim=0, out=cu_seq_lens[1:])
+
+    query_start_loc = (
+        query_start_loc[start_idx : end_idx + 1] - query_start_loc[start_idx]
+    )
+
+    if query_start_loc_np is not None:
+        total_query_len = int(
+            query_start_loc_np[end_idx] - query_start_loc_np[start_idx]
+        )
+    else:
+        total_query_len = int(
+            (query_start_loc_cpu[end_idx] - query_start_loc_cpu[start_idx]).item()
+        )
+    if query_slice is not None:
+        qs_start = query_slice.start
+        qs_stop = query_slice.stop
+    else:
+        qs_start = 0
+        qs_stop = total_query_len
+    output_query_len = qs_stop - qs_start
+
+    cu_seq_len_ks = torch.empty(output_query_len, dtype=torch.int32, device=device)
+    cu_seq_len_ke = torch.empty(output_query_len, dtype=torch.int32, device=device)
+
+    _build_prefill_chunk_metadata_kernel[(num_reqs,)](
+        query_start_loc,
+        uncompressed_seq_lens[start_idx:end_idx],
+        cu_seq_lens,
+        token_to_seq,
+        cu_seq_len_ks,
+        cu_seq_len_ke,
+        qs_start,
+        qs_stop,
+        DCP_WORLD_SIZE=dcp_world_size,
+        DCP_RANK=dcp_rank,
+        CP_KV_CACHE_INTERLEAVE_SIZE=cp_kv_cache_interleave_size,
+        BLOCK_SIZE=1024,
+        COMPRESS_RATIO=compress_ratio,
+    )
+
+    token_start = (
+        int(query_start_loc_np[start_idx])
+        if query_start_loc_np is not None
+        else query_start_loc_cpu[start_idx].item()
+    )
+    if query_slice is not None:
+        token_end = token_start + qs_stop
+        token_start = token_start + qs_start
+        skip_kv_gather = skip_kv_gather or qs_start > 0
+    else:
+        token_end = (
+            int(query_start_loc_np[end_idx])
+            if query_start_loc_np is not None
+            else query_start_loc_cpu[end_idx].item()
+        )
+
+    return DeepseekV32IndexerPrefillChunkMetadata(
+        cu_seqlen_ks=cu_seq_len_ks,
+        cu_seqlen_ke=cu_seq_len_ke,
+        cu_seq_lens=cu_seq_lens,
+        token_to_seq=token_to_seq,
+        total_seq_lens=total_seq_lens,
+        block_table=block_table[start_idx:end_idx],
+        token_start=token_start,
+        token_end=token_end,
+        num_reqs=num_reqs,
+        skip_kv_gather=skip_kv_gather,
+    )
+
+
+@triton.jit(do_not_specialize=["query_slice_start", "query_slice_stop"])
+def _build_prefill_chunk_metadata_kernel(
+    # Inputs
+    query_start_loc_ptr,
+    uncompressed_seq_lens_ptr,
+    cu_compressed_seq_lens_ptr,
+    # Outputs
+    token_to_seq_ptr,
+    cu_compressed_seq_len_ks_ptr,
+    cu_compressed_seq_len_ke_ptr,
+    query_slice_start,
+    query_slice_stop,
+    DCP_WORLD_SIZE: tl.constexpr,
+    DCP_RANK: tl.constexpr,
+    CP_KV_CACHE_INTERLEAVE_SIZE: tl.constexpr,
+    BLOCK_SIZE: tl.constexpr,
+    COMPRESS_RATIO: tl.constexpr,
+):
+    batch_idx = tl.program_id(0)
+
+    query_start = tl.load(query_start_loc_ptr + batch_idx)
+    query_end = tl.load(query_start_loc_ptr + batch_idx + 1)
+    query_len = query_end - query_start
+
+    seq_start = tl.load(cu_compressed_seq_lens_ptr + batch_idx)
+    seq_end = tl.load(cu_compressed_seq_lens_ptr + batch_idx + 1)
+    compressed_seq_len = seq_end - seq_start
+
+    uncompressed_seq_len = tl.load(uncompressed_seq_lens_ptr + batch_idx)
+    start_pos = uncompressed_seq_len - query_len
+
+    for i in range(0, query_len, BLOCK_SIZE):
+        offset = i + tl.arange(0, BLOCK_SIZE)
+        abs_pos = query_start + offset
+        mask = (
+            (offset < query_len)
+            & (abs_pos >= query_slice_start)
+            & (abs_pos < query_slice_stop)
+        )
+        out_pos = abs_pos - query_slice_start
+
+        # Compute cu_seq_len_ks
+        tl.store(cu_compressed_seq_len_ks_ptr + out_pos, seq_start, mask=mask)
+
+        # Compute cu_seq_len_ke
+        seq_len_per_token = (start_pos + 1 + offset) // COMPRESS_RATIO
+        if DCP_WORLD_SIZE > 1:
+            base = (
+                seq_len_per_token
+                // CP_KV_CACHE_INTERLEAVE_SIZE
+                // DCP_WORLD_SIZE
+                * CP_KV_CACHE_INTERLEAVE_SIZE
+            )
+            remainder = seq_len_per_token - base * DCP_WORLD_SIZE
+            rank_remainder = tl.minimum(
+                tl.maximum(
+                    remainder - DCP_RANK * CP_KV_CACHE_INTERLEAVE_SIZE,
+                    0,
+                ),
+                CP_KV_CACHE_INTERLEAVE_SIZE,
+            )
+            seq_len_per_token = base + rank_remainder
+        tl.store(
+            cu_compressed_seq_len_ke_ptr + out_pos,
+            seq_start + seq_len_per_token,
+            mask=mask,
+        )
+
+    # Compute token_to_seq
+    for i in range(0, compressed_seq_len, BLOCK_SIZE):
+        offset = i + tl.arange(0, BLOCK_SIZE)
+        mask = offset < compressed_seq_len
+        tl.store(token_to_seq_ptr + seq_start + offset, batch_idx, mask=mask)
+
+
+def _prewarm_prefill_chunk_metadata_kernel(
+    *,
+    device: torch.device,
+    dcp_world_size: int,
+    dcp_rank: int,
+    cp_kv_cache_interleave_size: int,
+    compress_ratio: int,
+) -> None:
+    if not current_platform.is_cuda():
+        return
+
+    query_start_loc = torch.tensor([0, 1], dtype=torch.int32, device=device)
+    uncompressed_seq_lens = torch.tensor([1], dtype=torch.int32, device=device)
+    cu_seq_lens = torch.tensor([0, 1], dtype=torch.int32, device=device)
+    token_to_seq = torch.empty((1,), dtype=torch.int32, device=device)
+    cu_seq_len_ks = torch.empty((1,), dtype=torch.int32, device=device)
+    cu_seq_len_ke = torch.empty((1,), dtype=torch.int32, device=device)
+
+    _build_prefill_chunk_metadata_kernel[(1,)](
+        query_start_loc,
+        uncompressed_seq_lens,
+        cu_seq_lens,
+        token_to_seq,
+        cu_seq_len_ks,
+        cu_seq_len_ke,
+        0,
+        1,
+        DCP_WORLD_SIZE=int(dcp_world_size),
+        DCP_RANK=int(dcp_rank),
+        CP_KV_CACHE_INTERLEAVE_SIZE=int(cp_kv_cache_interleave_size),
+        BLOCK_SIZE=1024,
+        COMPRESS_RATIO=int(compress_ratio),
+    )

文件差異過大導致無法顯示
+ 0 - 34
docker-images/glm52-nf3-hybrid/patches/draft-quant-packed-mapping.patch


文件差異過大導致無法顯示
+ 0 - 34
docker-images/glm52-nf3-hybrid/patches/pr72-1.patch


文件差異過大導致無法顯示
+ 0 - 34
docker-images/glm52-nf3-hybrid/patches/pr72-2.patch


部分文件因文件數量過多而無法顯示