4 · The Python side, line by line

This chapter reads every line of submission.py that is plain Python: the header, the configuration tables, how the CUDA code gets compiled, prepare(), and the dispatcher kernel_fn(). The CUDA kernels (lines 42–472) and the Triton kernels (475–583) get their own chapters. Each code block below is followed by notes keyed to its line numbers.

ON THIS PAGE

4.1 Header and interface

submission.py, lines 1–10
1
2
3
4
5
6
7
8
9
10
# okc: problem=muse_bf16_proj
"""Dense projections for Muse Spark Open.

m <= 32 (decode and 8-token verify): a CUDA tensor-core GEMV, on losslessly compressed weights (12 bits per BF16
weight: raw low byte + sign/exponent-window code, exact fp32 corrections for out-of-window weights) where that is
faster, else on plain BF16. Weights are repacked in prepare() into mma
A-fragment order so every lane streams its own 16B per fragment; one CTA owns a 16-row block, its warps split
K and reduce through smem (optionally split across CTAs with a semaphore-fused reduction). The router runs on
a BF16 hi+lo split of its FP32 weights with FP32 accumulation, fused into one launch.
m > 32: cuBLAS for the dense layers; the router uses a fused hi+lo Triton GEMM (TMA, semaphore split-K)."""
submission.py, lines 12–18
12
13
14
15
16
17
18
from typing import TypedDict

import torch
import triton
import triton.language as tl
from torch.utils.cpp_extension import load_inline
from triton.tools.tensor_descriptor import TensorDescriptor
submission.py, lines 21–38
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Weights(TypedDict):
    qkv_gate: torch.Tensor  # bfloat16 [2304, 8192]
    o: torch.Tensor         # bfloat16 [8192, 1024]
    pooler: torch.Tensor    # bfloat16 [4096, 8192]
    unpooler: torch.Tensor  # bfloat16 [8192, 4096]
    router: torch.Tensor    # float32 [256, 8192]


class Config(TypedDict):
    m: int
    n: int      # output width; the unpooler's is 1024 up to 8 tokens (this GPU's slice), else 8192
    k: int
    layer: str  # which weight: "qkv_gate", "o", "pooler", "unpooler" or "router"


class Inputs(TypedDict):
    x: torch.Tensor  # bfloat16 [m, k]
    config: Config
submission.py, line 41 · the CUDA source starts here
41
CUDA_SRC = r'''
submission.py, line 473
473
'''

4.2 The three configuration tables

submission.py, lines 586–606 · CTABLE: plain BF16 GEMV
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
# (layer, m) -> (NW, S, U, P): warps per CTA, K-splits across CTAs, loads in flight per warp, software-pipeline mode
CTABLE: dict = {('o', 1): (4, 1, 4, 2),
 ('o', 8): (4, 1, 2, 3),
 ('o', 16): (8, 1, 2, 0),
 ('o', 32): None,
 ('pooler', 1): (8, 1, 2, 3),
 ('pooler', 8): (8, 1, 2, 3),
 ('pooler', 16): (16, 1, 8, 0),
 ('pooler', 32): (16, 1, 8, 0),
 ('qkv_gate', 1): (8, 1, 4, 2),
 ('qkv_gate', 8): (16, 1, 2, 2),
 ('qkv_gate', 16): (16, 1, 8, 0),
 ('qkv_gate', 32): None,
 ('router', 1): (16, 4, 4, 3),
 ('router', 8): (4, 16, 2, 2),
 ('router', 16): (8, 16, 2, 3),
 ('router', 32): (16, 8, 2, 3),
 ('unpooler', 1): (16, 1, 2, 3),
 ('unpooler', 8): (16, 1, 8, 3),
 ('unpooler', 16): None,
 ('unpooler', 32): None}
submission.py, lines 607–619 · ZTABLE: compressed GEMV
607
608
609
610
611
612
613
614
615
616
617
618
619
# (layer, m) -> (NW, S, UG, P) for the compressed-weight GEMV (UG = 64-wide K groups in flight per warp)
ZTABLE: dict = {('o', 1): (4, 1, 2, 3),
 ('o', 8): (4, 1, 2, 3),
 ('o', 16): (8, 1, 2, 0),
 ('pooler', 1): (16, 1, 1, 2),
 ('pooler', 8): (16, 1, 1, 2),
 ('pooler', 16): (8, 1, 2, 3),
 ('pooler', 32): (8, 1, 1, 3),
 ('qkv_gate', 1): (16, 1, 1, 2),
 ('qkv_gate', 8): (16, 1, 1, 2),
 ('qkv_gate', 16): (4, 4, 1, 1),
 ('unpooler', 16): (4, 1, 2, 3),
 ('unpooler', 32): (4, 1, 1, 3)}
submission.py, lines 620–623 · TABLE: Triton split-K GEMM
620
621
622
623
# (layer, m) -> (BN, BM, BK, SPLIT, num_warps, num_stages, tma)
TABLE: dict = {('pooler', 128): (64, 128, 128, 2, 4, 4, 1, 0),
 ('router', 128): (64, 128, 128, 16, 4, 3, 1, 1),
 ('router', 256): (64, 64, 128, 8, 4, 3, 1, 1)}
submission.py, lines 624–626
624
625
626
WS_FLOATS = 8 * 1024 * 1024
_MOD = None
_LAYERS = ("qkv_gate", "o", "pooler", "unpooler", "router")

4.3 Compiling the CUDA code

submission.py, lines 629–637 · _cuda()
629
630
631
632
633
634
635
636
637
def _cuda():
    global _MOD
    if _MOD is None:
        _MOD = load_inline(
            "okc_gemv_proj",
            cpp_sources="#include <torch/extension.h>\nvoid gemv(torch::Tensor x, torch::Tensor w, torch::Tensor w2, torch::Tensor out, torch::Tensor ws, torch::Tensor sem, int64_t N, int64_t K, int64_t NW, int64_t S, int64_t U, int64_t NB, bool dual, int64_t P);\n"
            "void gemvz(torch::Tensor x, torch::Tensor w, torch::Tensor esc, int64_t capr, torch::Tensor out, torch::Tensor ws, torch::Tensor sem, int64_t N, int64_t K, int64_t NW, int64_t S, int64_t UG, int64_t NB, int64_t P, int64_t TL, int64_t TH, int64_t dbg);",
            cuda_sources=CUDA_SRC, functions=["gemv", "gemvz"], extra_cuda_cflags=["-O3", "-arch=sm_90a"], verbose=False)
    return _MOD
submission.py, lines 640–647
640
641
642
643
644
645
646
647
def _pack(w: torch.Tensor) -> torch.Tensor:
    """[N, K] bf16 -> [RB, KB, step, lane(g,t), (j,h,e)]: each lane's 16B is one m16n8k16 A fragment."""
    n, k = w.shape
    return w.reshape(n // 16, 2, 8, k // 32, 4, 2, 2, 2).permute(0, 3, 5, 2, 4, 6, 1, 7).contiguous()


def nb_of(m):
    return 1 if m <= 8 else 2 if m <= 16 else 4

Lines 650–708 are pack_z, the 12-bit compressor, explained in chapter 7.

4.4 prepare(): everything that may be slow

submission.py, lines 711–722
711
712
713
714
715
716
717
718
719
720
721
722
def prepare(weights: Weights):
    state = {name: w.contiguous() for name, w in weights.items()}
    r = weights["router"]
    hi = r.to(torch.bfloat16)
    lo = (r - hi.float()).to(torch.bfloat16)
    state["router_hi"] = hi.contiguous()
    state["router_lo"] = lo.contiguous()
    for name in ("qkv_gate", "o", "pooler", "unpooler"):
        state["p_" + name] = _pack(state[name])
    state["p_unpooler_s"] = _pack(state["unpooler"][:1024].contiguous())
    state["p_router_hi"] = _pack(state["router_hi"])
    state["p_router_lo"] = _pack(state["router_lo"])
submission.py, lines 723–726
723
724
725
726
    for (layer, m) in ZTABLE:
        key = "z_" + layer + ("_s" if layer == "unpooler" and m <= 8 else "")
        if key not in state:
            state[key] = pack_z(state[layer][:1024].contiguous() if key == "z_unpooler_s" else state[layer])
submission.py, lines 727–731
727
728
729
730
731
    dev = r.device
    state["ws"] = torch.empty(WS_FLOATS, dtype=torch.float32, device=dev)
    state["sem"] = torch.zeros(4096, dtype=torch.int32, device=dev)
    state["racc"] = torch.zeros(256 * 8192, dtype=torch.float32, device=dev)  # zeroed split-K accumulator
    state["desc"] = {}
submission.py, lines 732–741
732
733
734
735
736
737
738
739
740
741
    _cuda()
    # compile everything the tables (and defaults) can hit, outside the timed calls
    ms = {m for (_, m) in CTABLE} | {m for (_, m) in TABLE} | {1, 8, 16, 32, 128, 256}
    for layer in _LAYERS:
        k = state[layer].shape[1]
        for m in sorted(ms):
            n = 1024 if layer == "unpooler" and m <= 8 else state[layer].shape[0]
            kernel_fn({"x": torch.zeros(m, k, dtype=torch.bfloat16, device=dev), "config": {"m": m, "n": n, "k": k, "layer": layer}}, state)
    torch.cuda.synchronize()
    return state

4.5 Launch helpers for Triton

submission.py, lines 744–749 · _desc
744
745
746
747
748
749
def _desc(state, name, t, block):
    key = (name, tuple(block))
    d = state["desc"].get(key)
    if d is None:
        d = state["desc"][key] = TensorDescriptor.from_tensor(t, block_shape=list(block))
    return d
submission.py, lines 752–771 · _launch
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
def _launch(x, name, w, w2, out, state, N, K, cfg):
    bn, bm, bk, split, nw, ns, tma = cfg[:7]
    atom = len(cfg) > 7 and cfg[7] and split > 1
    M = x.shape[0]
    grid = (N // bn, split, triton.cdiv(M, bm))
    if tma:
        xd = TensorDescriptor.from_tensor(x, block_shape=[bm, bk])
        wd = _desc(state, name, w, [bn, bk])
        w2d = _desc(state, name + "2", w2, [bn, bk]) if w2 is not None else wd
        _proj_tma_kernel[grid](
            xd, wd, w2d, out, state["racc"] if atom else state["ws"], state["sem"], M, N, K,
            BN=bn, BM=bm, BK=bk, SPLIT=split, DUAL=w2 is not None, OUT_F32=out.dtype == torch.float32, NS=ns,
            ATOM=bool(atom), num_warps=nw, num_stages=ns,
        )
        return
    _proj_kernel[grid](
        x, w, w2, out, state["ws"], state["sem"], M, N, K,
        BN=bn, BM=bm, BK=bk, SPLIT=split, DUAL=w2 is not None, OUT_F32=out.dtype == torch.float32,
        num_warps=nw, num_stages=ns,
    )

4.6 kernel_fn(): the timed call

submission.py, lines 774–786 · 1. Triton
774
775
776
777
778
779
780
781
782
783
784
785
786
def kernel_fn(data: Inputs, state) -> torch.Tensor:
    x = data["x"]
    cfg = data["config"]
    layer, n, k = cfg["layer"], cfg["n"], cfg["k"]
    m = x.shape[0]
    router = layer == "router"
    if (layer, m) in TABLE:
        out = torch.empty((m, n), dtype=torch.float32 if router else torch.bfloat16, device=x.device)
        if router:
            _launch(x, "router_hi", state["router_hi"], state["router_lo"], out, state, n, k, TABLE[(layer, m)])
        else:
            _launch(x, layer, state[layer], None, out, state, n, k, TABLE[(layer, m)])
        return out
submission.py, lines 787–793 · 2. compressed GEMV
787
788
789
790
791
792
793
    zc = ZTABLE.get((layer, m))
    if zc is not None:
        z = state["z_" + layer + ("_s" if layer == "unpooler" and m <= 8 else "")]
        out = torch.empty((m, n), dtype=torch.bfloat16, device=x.device)
        _cuda().gemvz(x, z["w"], z["esc"], z["capr"], out, state["ws"], state["sem"], n, k, zc[0], zc[1], zc[2],
                      nb_of(m), zc[3], z["TL"], z["TH"], 0)
        return out
submission.py, lines 794–803 · 3. plain GEMV
794
795
796
797
798
799
800
801
802
803
    if m <= 32 and CTABLE.get((layer, m), 0) is not None:
        nb = 1 if m <= 8 else 2 if m <= 16 else 4
        nw, s, u, p = CTABLE.get((layer, m)) or ((8, 8, 2, 0) if router else (4, 1, 2, 0))
        out = torch.empty((m, n), dtype=torch.float32 if router else torch.bfloat16, device=x.device)
        if router:
            w, w2 = state["p_router_hi"], state["p_router_lo"]
        else:
            w, w2 = state["p_unpooler_s" if layer == "unpooler" and n < 8192 else "p_" + layer], state["ws"]
        _cuda().gemv(x, w, w2, out, state["ws"], state["sem"], n, k, nw, s, u, nb, router, p)
        return out
submission.py, lines 804–807 · 4. cuBLAS fallbacks
804
805
806
807
    if router:
        acc = torch.mm(x, state["router_hi"].t(), out_dtype=torch.float32)
        return acc + torch.mm(x, state["router_lo"].t(), out_dtype=torch.float32)
    return x @ state[layer][:n].t()
Try it · lab0_dispatch.py — Lab 0: which engine runs each shape? The tables are read straight out of submission.py.
cd ~/projects/okc/muse_bf16_proj/learn/labs
python3 lab0_dispatch.py
The file is already on your Mac at ~/projects/okc/muse_bf16_proj/learn/labs/lab0_dispatch.py; you can also view or download it here.

Exercise. Copy submission.py to /tmp/mine.py and delete the line ('pooler', 1): (16, 1, 1, 2), from ZTABLE. Run python3 lab0_dispatch.py /tmp/mine.py. Which engine and configuration does pooler at m = 1 get now, and from which table? Chapter 10's experiment A runs exactly this change on the real H200.

Check yourself

If a (layer, m) is in both ZTABLE and CTABLE, which one is used?

ZTABLE, because kernel_fn checks it first (line 787, before line 794). For example, ('o', 1) appears in both and runs compressed.

What would go wrong if prepare() skipped the warm-up loop?

The first call with each new Triton configuration would compile it, which takes seconds, and cuBLAS would initialize on first use. That work would land inside the judge's capture or timing instead of in the untimed prepare().

Why does every split-K kernel reset its counter to 0 itself, instead of Python calling sem.zero_() before each launch?

zero_() is another kernel launch: about 1–2 µs more per call, inside the timed region. Having the last CTA reset the counter costs nothing and leaves the state ready for the next graph replay.