Expand description
2026-09-25: Kernel launch wrappers that the layers compose into forward
passes, grouped into the submodules under ops/ and re-exported here
(most by glob).
Owner: model-layers (ops). Invariants: none beyond the types.
Re-exports§
pub use model_stats::ModelStats;pub use moe_lora_grouped::*;
Modules§
- dense_
gemv_ tc - 2026-09-25: Routes the MTP drafter’s BF16 small-M GEMM rows to the
tensor-core GEMV entries of
dense_gemv_bf16_tc.cu. - gemv_tc
- 2026-09-25: Routing of the narrow NVFP4 batched GEMV to its tensor-core kernels (
w4a16_gemv_tc8/w4a16_gemv_tc16in kernels/gb10/common/w4a16_gemv_tc.cu). - lora_
delta - 2026-09-25: Runtime LoRA delta
y += scale * (x @ A^T) @ B^Ton BF16 activations: the single-adapter path and the per-request routed path. - model_
stats - 2026-09-25:
ModelStats: diagnostic counters and one-shot latches owned by one model. - moe_
lora_ grouped - 2026-09-25: Launchers for the device-side MoE expert LoRA folds:
moe_lora_grouped_downover the expert-sorted prefill rows andmoe_lora_gather_bgmvover the slot-major decode rows, plus the host packing of their per-expert tables. - target_
defaults - 2026-09-25: The compiled target’s serving defaults, resolved against the
environment: the target’s declaration first, a
METRALE_*override second. - token_
overlay - 2026-09-25: Launchers for the LoRA token-overlay kernels in
kernels/gb10/common/token_overlay.cu: - w4a4_
proj - 2026-09-28: W4A4 small-M projection on FP4 tensor cores (
w4a4_gemv_mx.cu, modulew4a4_gemv_mx).
Structs§
- Attn
Fa128 Kernels - 2026-09-27: The two twins’ handles; 0 when the target lacks the module or
METRALE_NO_ATTN_FA128is present (the originals then run, for A/B measurement). - BaGates
Pick - 2026-09-25: The kernel a launch runs, and why the other did not.
- Cublas
Scope - 2026-09-25: Which projection families take a cuBLASLt GEMM arm, so one family can be armed without the others.
- Decode
W8a8 Plan - 2026-09-25: The shape and output of one decode projection, as
decode_w8a8_selectedjudges it. The route is taken only when all of these hold: - Decode
W8a8 Scratch - 2026-09-25: The activation-quant scratch buffers with their capacities, and the quantizer and scale-layout adapter kernels.
- Dense
MmKernels - 2026-09-25: The three BF16 dense kernels
dense_mm_bf16chooses from, resolved once per projection site (the GLM-5.3 mixer and MLP sites bind one each). - Derived
Weights - 2026-09-25: Per-model memo of derived weight encodings, one map per
Derivation. - E4m3
Saturation - 2026-09-30: An unscaled E4M3 cast whose saturation is disclosed or known, with the
largest
|x|the disclosure covers. - E4m3
Saturation Scope - 2026-09-30: See
allow_e4m3_saturation. - Fp8Act
Quant - 2026-09-25: The FP8 activation quantizer a layer launches: the shared kernel, plus the Hopper twin when the image has one.
- Fp8Grouped
Geometry - 2026-09-28: The launch shape of a grouped gate+up or down kernel: output columns per
CTA (
grid.x = ceil(n / cols_per_cta)), rows per pass (the shared expert takesceil(num_tokens / rows_per_pass)block rows) and threads per CTA. - Fp8Grouped
Sort Out - 2026-09-27: The outputs of
moe_fp8_grouped_sort:moe_sort_by_expert’s four and the active-expert list with its length. - Fp8Grouped
W8a8 Layout - 2026-09-28: Byte offsets of the W8A8 activations inside the grouped decode’s buffers.
The routed SiLU buffer (
expert_gate_out, sized for[te, inter]FP32) holds the routed E4M3 products[te, inter], their scales[te, inter / 128]FP32, the quantized layer input[m, hidden]E4M3 and its scales[m, hidden / 128]; the shared SiLU buffer (logits,[m, inter]FP32) holds the shared products and their scales. - Fp8Grouped
W8a8 Rows - 2026-09-28: The routed expert tables and the grouped decode’s sort outputs the two W8A8 kernels read.
- Fp8Quant
Pick - 2026-09-25: Which kernel a launch runs, on what grid, and why the other did
not.
super::Fp8ActQuant::pick_withsets the handle and the grid from one decision. - GdnCarry
Sizes - 2026-10-01: The device allocations
TransformerModel::gdn_carry_bindmakes forlayersGDN layers andslotscarry slots (the MTP slots plus the dummy), in bytes, one field per allocation. The binder allocates exactly these and the preflight reserve planstotal(). - Gemm
Dispatch - 2026-09-25: Which GEMM implementation each projection takes, resolved by
GemmDispatch::from_env. - Model
Levers - 2026-09-25: Kernel-path levers for one loaded model.
TransformerModel::newresolves its own copy withModelLevers::from_env; other readers use the process-wideModelLevers::get. - MoeCutlass
Down Host Tables - 2026-09-25: The down-projection tables of
MoeCutlassHostTables. - MoeCutlass
Host Tables - 2026-09-25: Host copies of the per-expert pointer and scale tables for the CUTLASS grouped
path, which takes them on the host.
MoeLayer::build_cutlass_grouped_sfbbuilds them at load into the layer’scutlass_grouped_host, so they are dropped with the layer. - MoeE4m3
Tile - 2026-09-27: One entry point of
kernels/gb10/common/moe_w8a8_grouped_gemm_e4m3.cu: its work-list item shape (m_tilerows byn_tilecolumns, so the builder takesn_tiles = N / n_tile), its dynamic shared memory and how many of its 256-thread CTAs fit on one SM. - Nvfp4
Expert Tables - 2026-09-27: One NVFP4 projection across the routed experts: device tables of each expert’s packed and block-scale pointers, and its per-tensor scales as f32.
- W8a8
Kernels - 2026-09-28: The quantizers and the ten GEMV entry points (2 scale layouts
x the five row entries,
mb1_ku8tomb16). A handle is 0 when its module is not compiled. - W8a8
Scratch - 2026-09-28: Device scratch for one quantized activation:
[rows, k]E4M3 and its FP32 scales. One per model; every W8A8 projection on the stream quantizes into it immediately before its GEMV. - W8a8
Weight - 2026-09-28: One W8A8 projection: up to three E4M3 weights with the same K and scale layout, stacked by rows into one output (attention Q|K|V, GDN QKV|Z, FFN gate|up). The checkpoint’s tensors are read in place.
Enums§
- BaGates
LogSlot - 2026-09-25: The once-flag slot a verdict logs under in
ba_gates_log; one slot per outcome, so an early small request cannot hide a later line about the other outcome. - Derivation
- 2026-09-25: Which derivation a lookup is for.
- F16Chain
States - 2026-10-01: Where the FP16 exact chain finds its states: per-sequence pointer tables (the verify’s WY tables: h, Hi0, Hi1, Hi2), or the bases of a single sequence.
- Fp8Quant
LogSlot - 2026-09-25: Which once-flag
fp8_quant_loguses for a verdict. There is one per branch because the verdict changes with M, so one process can log both the twin line and a refusal. - GdnScalar
Spine - 2026-09-28: The scalar spine a process binds (
init_kernels::fused_spine_kernel) and launches (ops::gdn_prefill_fla, whose block size and shared memory depend on it). Both read it throughgdn_scalar_spine, so they cannot disagree. - HcVariant
- 2026-09-25: Which family a site’s weights select. Callers use it to decide whether the
block’s
input_normruns onhc_pre’s output (HcVariant::applies_block_input_norm): in the low-rank familyhc_norminsidehc_preis the block’s input norm, and a second RMS pass with a ones-filled weight is not an identity. - Resident
Mat - 2026-09-25: A resident
[N, K]row-major projection from the GGUF path: expanded bf16, or the rawQ2_K/Q3_Kblocks (WeightDtype::Q2K/Q3K) that the K-quant GEMV and MMQ kernels read. - W8a8
Scale - 2026-09-28: How a W8A8 weight carries its scales, and so how the activation is quantized: one scale per output row with one per token, or one per 128x128 weight block with one per (token, 128-wide K group).
Constants§
- BA_
GATES_ BLOCK - 2026-09-25: Threads per block, as in the parent (
BAH_BLOCKin the twin). The reduction order depends on it,BA_GATES_LANESandBA_GATES_OUTS. - BA_
GATES_ FALLBACK_ SM_ COUNT - 2026-09-25: SM count used when
GpuBackend::sm_count()fails: thesm_countinkernels/hopper/HARDWARE.toml. A wrong value moves only the guard’s threshold. - BA_
GATES_ GROUPS - 2026-09-25:
BAH_GROUPSin the twin: output groups a thread accumulates per read of the activation row. The row is readceil(ceil(N/4)/8) * 4times per token, 12 atN = 96. The kernel source records the register and occupancy table behind the choice of 8. - BA_
GATES_ LANES - 2026-09-25: Threads that reduce one BA output: the parent’s
threads_per_out. - BA_
GATES_ LOG_ SLOTS - 2026-09-25: Once-flags
ba_gates_logkeeps: one per guard, plus the twin’s. - BA_
GATES_ OUTS - BA_
GATES_ REJECTS - 2026-09-25: Every string
ssm_ba_gates_hopper_rejectcan return, in the order it tests them.ba_gates_loggives each its own once-flag by index here; the testevery_reject_reason_has_its_own_log_slotchecks that every returned reason has an index. - BA_
GATES_ TOO_ FEW_ TOKENS - 2026-09-25: The token-count guard’s string, named so tests can match it.
- BA_
GATES_ WARPS - 2026-09-25: Warps per block: the width of one row of the twin’s cross-warp
scratch
red. - BF16_
GROUPED_ DOWN_ TC - 2026-10-02:
moe_expert_down_act_bf16_grouped_tc(BTC_DOWN_COLScolumns per CTA). - BF16_
GROUPED_ GATE_ UP_ TC - 2026-10-02:
moe_expert_gate_up_act_bf16_grouped_tc(BTC_GU_COLScolumns per CTA; writes the SiLU product as BF16 hi + lo). - DECODE_
W8A8_ ROWS - 2026-09-25: The padded decode row counts this route takes. Any other count stays on the caller’s own kernels.
- DENSE_
GEMM_ M16_ BF16_ K_ STEP - 2026-09-25: K granularity: the kernel’s 4-stage cp.async pipeline advances 64
elements per step (
DGM16_K_STEP), which also keeps every weight row 16-byte aligned. - DENSE_
GEMM_ M16_ BF16_ MAX_ M - 2026-09-25: The kernel’s M tile. Rows past it are not computed, so the wrapper returns an error rather than leave part of the output stale.
- DENSE_
GEMM_ M16_ BF16_ N_ TILE - 2026-09-25: N columns one CTA owns in the default instantiation. It must equal the
kernel’s
DGM16_N_TILE. - DENSE_
GEMM_ M16_ BF16_ N_ TILE_ WIDE - 2026-09-25: N tile of the wide instantiation
dense_gemm_m16_bf16_n64(kernelDGM16_N_TILE_WIDE), selected byMETRALE_LM_HEAD_M16_TC_NTILE=64. It launches half the CTAs for a given N, so the A tile is re-read from L2 half as many times. - DENSE_
GEMV_ BATCHM_ DECODE_ MAX_ M - 2026-09-25: The widest batch that the MTP row dispatch
(
mtp_head/row_dispatch.rs) and the BF16 arm of the model’slm_head_batched(impl_a3_lm_head.rs) hand todense_gemv_bf16_batchm;target_defaults::BASELINE_BATCHM_MAXis set from it. Above it those paths choose other kernels, some of which accumulate in a different order, so this value decides which bits a decode of a given width produces. - DENSE_
GEMV_ BATCHM_ MAX_ M - 2026-09-25: Rows
dense_gemv_bf16_batchmcomputes:MAX_Minkernels/gb10/common/dense_gemv_bf16_batchm.cu. The kernel clamps a larger M, sodense_gemv_batchmrefuses above this value. Each row’s accumulation does not depend on M, so a row’s result is the same at every batch width. - E4M3_
MAX - 2026-09-29: E4M3’s largest finite magnitude; an unscaled cast saturates above it.
- FEED_
HOST_ BIT - 2026-09-25: Bit of a
feed_resolvesource word that marks an inline host token id in the low 31 bits; without it the word indexes the previous step’s feed cell (argmax_feed.cu). - FP8_
GROUPED_ DOWN_ COLS_ PER_ CTA - 2026-09-25: Output columns per down CTA. Must equal
DOWN_CTA_COLSin the.cu: 2026-09-27, four column groups of 32. - FP8_
GROUPED_ DOWN_ ROWS_ PER_ PASS - 2026-09-26: Rows per down pass. Must equal
GROUP_ROWSin the.cu. - FP8_
GROUPED_ DOWN_ SCALAR - 2026-09-28:
moe_expert_down_act_fp8_grouped(reads FP32 SiLU products). - FP8_
GROUPED_ DOWN_ TC - 2026-09-28:
moe_expert_down_act_fp8_grouped_tc(reads FP32 SiLU products as BF16 hi + lo). - FP8_
GROUPED_ DOWN_ TC_ W8A8 - 2026-09-28:
moe_expert_down_act_fp8_grouped_tc_w8a8(TC8_DOWN_COLS). - FP8_
GROUPED_ GATE_ UP_ COLS_ PER_ CTA - 2026-09-26: Output columns per gate+up CTA. Must equal
GU_COLS_PER_CTAin the.cu. - FP8_
GROUPED_ GATE_ UP_ ROWS_ PER_ PASS - 2026-09-26: Rows per gate+up pass. Must equal
GU_GROUP_ROWSin the.cu: the shared expert takesceil(num_tokens / this)block rows. - FP8_
GROUPED_ GATE_ UP_ SCALAR - 2026-09-28:
moe_expert_gate_up_act_fp8_grouped(FP32 SiLU products). - FP8_
GROUPED_ GATE_ UP_ TC - 2026-09-28:
moe_expert_gate_up_act_fp8_grouped_tc(FP32 SiLU products). - FP8_
GROUPED_ GATE_ UP_ TC_ W8A8 - 2026-09-28:
moe_expert_gate_up_act_fp8_grouped_tc_w8a8(TC8_GU_COLS: one 128-column quantization group of the down projection’s K per CTA). - FP8_
GROUPED_ SORT_ MAX_ EXPERTS - 2026-09-27: Experts
moe_fp8_grouped_sorthandles (PMS_MAX_EXPERTS). - FP8_
GROUPED_ TC_ DOWN_ COLS_ PER_ CTA - 2026-09-28: Output columns per tensor-core down CTA (
TC_DOWN_COLS). - FP8_
GROUPED_ TC_ GATE_ UP_ COLS_ PER_ CTA - 2026-09-28: Output columns per tensor-core gate+up CTA (
TC_GU_COLS). - FP8_
GROUPED_ TC_ ROWS_ PER_ PASS - 2026-09-28: Rows per pass of the tensor-core kernels (
moe_fp8_grouped_tc.cu,TC_ROWS), gate+up and down alike. - FP8_
QUANT_ ENTRY - 2026-09-25: Entry point of the shared quantizer.
- FP8_
QUANT_ HOPPER_ ENTRY - 2026-09-25: Entry point of the Hopper twin. It differs from the shared entry point, so a Hopper image carries both kernels.
- FP8_
QUANT_ HOPPER_ GROUPS_ PER_ CTA - 2026-09-25: K-groups one Hopper CTA covers: 128 threads / 16 threads per
group, as
HQ_GROUPS_PER_CTAin the.cu. The kernel derives its group span fromgridDim.y, so this value sets only the grid’s Y extent. - FP8_
QUANT_ HOPPER_ MODULE - 2026-09-25: Module (file stem) of the Hopper twin.
- FP8_
QUANT_ LOG_ SLOTS - 2026-09-25: Once-flags
fp8_quant_logkeeps: one per refusal reason, plus the twin’s. - FP8_
QUANT_ MIN_ CTAS_ PER_ SM - 2026-09-25: CTAs per SM the twin’s grid must reach before it takes a
launch. The same value as
ssm_ba_gates_hopper::MIN_CTAS_PER_SM. - FP8_
QUANT_ MODULE - 2026-09-25: Module of the shared quantizer; the file and the kernel share this name.
- FP8_
QUANT_ REJECTS - 2026-09-25: Every reason
fp8_act_quant_hopper_rejectcan return.fp8_quant_logkeeps one once-flag per entry, by index. - FP8_
QUANT_ TOO_ FEW_ CTAS - 2026-09-25: The floor’s refusal reason.
- GDN_
CARRY_ CAP - 2026-09-26: Rows the carry stash holds per (layer, slot):
CARRY_CAPin gated_delta_rule_carry.cu. A verify whose K rows might not fit behind the pending ones (pending + K > GDN_CARRY_CAP) writes the state back and restarts the stash. - GDN_
CARRY_ EAGER_ MAX_ PENDING - 2026-09-26: Most pending rows an eager verify kernel folds; a slot holding more (only
after lazy verifies) is folded by
gdn_carry_flushfirst. - GDN_
CARRY_ LAZY_ MIN_ SEQS - 2026-09-26: Launch width (sequences) from which a run takes the lazy verify kernels, which write the state back only when the stash is full. Measured on dgx3 (k=1, –mtp-gate force): from 16 the lazy form is 2.5 % faster end to end at C=16; a threshold of 8 instead of 16 gives C=8 214.4 -> 216.2 tok/s (three reps each) with C=4 unchanged; at 2 and 4 sequences the eager form is ahead.
- GDN_
DECODE_ STRIDED_ SMEM_ CAP_ BYTES - 2026-09-29: Dynamic shared memory each
gdn_decode_f32_stridedCTA reserves and does not use, fromGDN_DECODE_STRIDED_SMEM_CAP_MIN_BATCHsequences: it caps the CTAs resident per SM (3 on GB10’s 100 KB), so a CTA’s 64 KB head state is still in L2 when its update pass re-reads it; uncapped, the second pass of a wide launch misses L2. Measured 2026-09-29 on dgx2 (gdn_decode_strided_microtest, per layer, uncapped / capped / per-sequence launches), 32 value heads: B=16 365 / 362 / 428 us, B=64 1904 / 1362 / 1740, B=128 3857 / 2641 / 3541; 48 value heads: B=16 672 / 507 / 589, B=128 5737 / 3902 / 4766. The output and state bits do not depend on it. - GDN_
DECODE_ STRIDED_ SMEM_ CAP_ MIN_ BATCH - 2026-09-29: Smallest batch that takes the cap. Below it the cap costs more than the L2 it saves (32 value heads, B=4: 34.1 us uncapped, 43.7 us capped).
- GDN_
SCALAR_ SPINE_ PIPE - 2026-09-25: The scalar spine entries
init_kernels::fused_spine_kernelbinds, asgdn_scalar_spinepicks them. The init route line and the handle are built from the same strings. 2026-09-28: The default:_vfused’s arithmetic with W, K and U double-buffered through cp.async (bit-identical to_vfused, 1.4x faster on GB10 at 1.6k-8k tokens per chunk). - GDN_
SCALAR_ SPINE_ VFUSED - 2026-09-25: SPLIT=2, 256 threads, single-buffered;
METRALE_GDN_PIPE=0. - GDN_
SCALAR_ SPINE_ VTILE - 2026-09-25: SPLIT=4, 512 threads. Not the default;
fused_spine_kernel’s doc says why. - GDN_
TC_ SPINE_ ENTRY - 2026-09-25: The spine entry the
gdn_prefill_tclever launches: two bf16 limbs ofS_c. Both entries take the same arguments, grid, block and shared memory, so nothing downstream depends on which one is bound. - GDN_
TC_ SPINE_ MODULE - 2026-09-25: The module the entry lives in:
kernels/hopper/common/gated_delta_rule_chunk_tc.cu. - KQUANT_
MODULE - MAX_
DYNAMIC_ SMEM - 2026-09-25: Largest dynamic shared memory, in bytes, one block may opt into on the GB10 target (sm_121).
- MIN_
CTAS_ PER_ SM - 2026-09-25: Tokens per SM the twin requires before it takes a launch. It is a judgement, not a contract: set high, it only sends more launches to the parent, which computes the same bits.
- MOE_
E4M3_ DN - 2026-09-27:
moe_w8a8_grouped_gemm_e4m3_dn(down: N = hidden, K = inter). - MOE_
E4M3_ GU - 2026-09-27:
moe_w8a8_grouped_gemm_e4m3_gu(gate/up: N = inter, K = hidden). - MOE_
ROUTED_ DOWN_ KNOWN - 2026-09-30: The routed experts’ down projection reads the SiLU product. On Qwen3.6-35B-A3B-NVFP4 it reaches 510 at position 0 of the last layer (measured 2026-09-29, no effect on the output); every other certified model stays under 448. The scaled cast that removes it is follow-up work, so this covers exactly the known value.
- MOE_
ROUTER_ GEMM_ COLS - 2026-09-26: Output columns per block of
moe_router_gemm_bf16(RC_COLSinkernels/gb10/common/moe_router_gemm.cu). - MOE_
ROUTER_ GEMM_ MAX_ PREFILL_ ROWS - 2026-10-01: Most rows for which the MoE prefill router takes
moe_router_gemm(the decode routers’ kernel, the same bits asdense_gemm_router); the decode routers run it at 2 to 64 rows. - MOE_
ROUTER_ GEMM_ ROWS - 2026-09-26: Activation rows per block of
moe_router_gemm_bf16(RC_ROWS). - MOE_
ROUTER_ RT_ MIN_ ROWS - 2026-09-28: Fewest rows for which
moe_router_gemm_rtbeatsdense_gemm_routeron GB10 (measured: 0.82x at 300 rows, 2.5x at 1000, 3.0-3.5x at 4k-32k). - MOE_
TOPK_ SIGMOID_ MAX_ EXPERTS - 2026-09-25: Largest
num_expertsthe sigmoid routing kernel holds, from#define MAX_EXPERTSin the same file. Beyond it the kernel considers only the firstMAX_EXPERTSexperts (actual_nis amin). - MOE_
TOPK_ SIGMOID_ MAX_ TOP_ K - 2026-09-25: Largest
top_kthe sigmoid routing kernel holds:#define MAX_TOP_Kinkernels/gb10/common/moe_topk_sigmoid.cu, which sizes its shareds_top_vals/s_top_idxs. The kernel clamps a largertop_kto it, andNemotronMoeLayerconstruction refuses one (nemotron_moe.rs).crates/model-engine/tests/moe_topk_sigmoid_bounds.rspins this mirror to the define and fails if a directory other thancommon/holds a copy of the kernel. - NEMOTRON_
SHARED_ EXPERT_ E4M3 - 2026-09-30:
--nemotron-shared-expert-e4m3: the Nemotron-H shared expert’s prefill tile GEMM casts its activations to E4M3 unscaled. The flag’s help discloses the saturation (1-30% local error measured on Nemotron-3-Nano), so any magnitude is covered. - NVFP4_
BLOCK_ BYTES - NVFP4_
GROUPED_ DOWN_ COLS_ PER_ CTA - 2026-09-27: Output columns per down CTA. Must equal
NG_DOWN_COLS_PER_CTAin the.cu. - NVFP4_
GROUPED_ DOWN_ ROWS_ PER_ PASS - 2026-09-27: Rows per down pass. Must equal
NG_DOWN_ROWSin the.cu. - NVFP4_
GROUPED_ DOWN_ SCALAR - 2026-10-02:
moe_expert_down_act_nvfp4_grouped(reads FP32 SiLU products). - NVFP4_
GROUPED_ DOWN_ TC - 2026-10-02:
moe_expert_down_act_nvfp4_grouped_tc(NTC_DOWN_COLScolumns per CTA; reads the hi + lo SiLU rows). - NVFP4_
GROUPED_ GATE_ UP_ COLS_ PER_ CTA - 2026-09-27: Output columns per gate+up CTA. Must equal
NG_GU_COLS_PER_CTAin the.cu. - NVFP4_
GROUPED_ GATE_ UP_ ROWS_ PER_ PASS - 2026-09-27: Rows per gate+up pass. Must equal
NG_GU_ROWSin the.cu. - NVFP4_
GROUPED_ GATE_ UP_ SCALAR - 2026-10-02:
moe_expert_gate_up_act_nvfp4_grouped(CUDA cores, FP32 SiLU products). - NVFP4_
GROUPED_ GATE_ UP_ TC - 2026-10-02:
moe_expert_gate_up_act_nvfp4_grouped_tc(NTC_GU_COLScolumns per CTA; writes the SiLU product as BF16 hi + lo). - NVFP4_
GROUPED_ TC_ ROWS_ PER_ PASS - 2026-10-02: Rows per pass of the tensor-core kernels (
moe_nvfp4_grouped_tc.cu,TC_ROWS), gate+up and down alike. - NVFP4_
LEAN_ REPACK_ SMEM_ PER_ K - 2026-10-04: Shared bytes
nvfp4_tc_lean_repackstages per unit of K: a 16-row tile’s packed (16 * K / 2) and scale (16 * K / 16) bytes. - NVFP4_
MMQ_ SMEM - 2026-09-25: Dynamic shared memory of the 128-wide M tile.
- NVFP4_
PIPE_ SMEM - 2026-09-28: Dynamic shared memory of
metrale_nvfp4_gemm_pipe: two stages of 128 weight rows and 192 activation rows, 144 bytes each. - Q2K_
BLOCK_ BYTES - 2026-09-25: Bytes per 256-value super-block:
block_q2_K,block_q3_K,block_q6_K. - Q2K_
MMQ_ SMEM - 2026-09-25: Dynamic shared memory of the 128x128 MMQ tile on the MMA path, as the vendored
mmq_get_nbytes_sharedcomputes it withMMQ_TILE_NE_K = 32: ids 512 B + tile_x (128 rows x tile_x_k ints) + tile_y (128 x 144 B).MMQ_MMA_TILE_X_K_Q2_K= 232 + 32 + 4 = 100;MMQ_MMA_TILE_X_K_Q3_K= 232 + 16 + 4 = 84. - Q2_
0_ BLOCK_ BYTES - 2026-09-25:
sizeof(block_q2_0): an fp16 scaledand 128 codes at 4 per byte. - Q2_
BATCHM_ MAX_ M - 2026-09-25: Row cap of the
q2_0_gemv_vec_batchmkernel (MAX_Min the .cu). The kernel stagesMactivation rows intos_A[MAX_M * TILE_K], soM > MAX_Mwrites past that tile, and its compute and store loops stop atMAX_M, so rows from 8 on are never written.q2_0_gemv_vec_batchmchunks largermitself. - Q3K_
BLOCK_ BYTES - Q3K_
MMQ_ SMEM - Q4K_
BLOCK_ BYTES - 2026-09-25:
sizeof(block_q4_K). - Q4K_
MMQ_ SMEM - 2026-09-25: Dynamic shared memory of the Q4_K MMQ kernel at
mmq_x = mmq_y = 128:mmq_get_nbytes_sharedinq4k_vendor/mmq.cuhwith an x tile of 76 ints per row. Above 48 KiB, so the registry raises the kernel’s dynamic shared memory limit (registry.rs). - Q6K_
BLOCK_ BYTES - Q8_
1_ BLOCK_ BYTES - 2026-09-25:
block_q8_1: 32 int8 + half2 (d, sum). - QK2_0
- 2026-09-25: Weights per
block_q2_0. - QK_K
- 2026-09-25: Weights per
block_q4_K. - QK_
NVFP4 - 2026-09-25: Weights per repacked NVFP4 block: 36 bytes, 32 of E2M1 nibbles and 4 UE4M3 scales.
- SSD_L
- 2026-09-25: SSD chunk length. Must equal
SSD_Linmamba2_ssd_chunk.cu. - SSD_PT
- 2026-09-25: head_dim rows per SSD scan block. Must equal
SSD_PTinmamba2_ssd_chunk.cu. - W4A16_
GEMV_ OUTS_ PER_ BLOCK - 2026-09-25: Outputs per 256-thread block of
w4a16_gemv; equals#define N_PER_BLOCKin kernels/gb10/common/w4a16_gemv.cu. - W4A16_
GEMV_ SW_ OUTS_ PER_ BLOCK - 2026-09-25: Outputs per 256-thread block of the single-warp kernels (
w4a16_gemv_swand the_swkernels in w4a16_gemv_fused.cu); equals#define N_PER_BLOCK_SW. - W4A16_
TC_ ROWS_ COLS - 2026-10-02: Output columns per CTA (
TR_COLS). - W4A16_
TC_ ROWS_ MAX_ M - 2026-10-02: Widest row count of one launch (
8 * NTofw4a16_tc_rows_64). - W4A16_
TC_ ROWS_ MODULE - 2026-10-02: The kernel module.
- W4A16_
VIA_ FP8_ MIN_ M - 2026-09-28: Rows at or above which
w4a16_t_via_fp8_ldmabbeatsw4a16_gemm_t_m128on the dense 27B attention projections (dgx2: x1.23-1.35 at 1024 rows, x0.69 at 300, x2.15 at 8192): below it the per-call weight dequant dominates. - W8A8_
K_ UNIT - 2026-09-28: The K width of one scale group and of one kernel K unit.
- W8A8_
LAUNCH_ ROWS - 2026-09-28: The most rows one GEMV launch serves (16 token tiles of 8).
- W8A8_
MAX_ ROWS - 2026-09-28: The most rows one W8A8 projection serves: 128-row launches, the weight read once per launch (a C128 verify step has 256 rows).
- W8A16_
GEMM_ M16_ N_ TILE - 2026-09-25: N columns one CTA owns on the default instantiation. The launch
grid and
m16_tc_kernel(dense_ffn_m16_tc.rs) both use it; the kernel’sM16_N_TILEmust equal it. - W8A16_
GEMM_ M16_ N_ TILE_ WIDE - 2026-09-25: The wide instantiation’s N tile (
w8a16_gemm_m16_n64, kernelM16_N_TILE_WIDE), selected for the dense FFN byMETRALE_FFN_M16_TC_NTILE=64. It halves the CTA count for a given N. - W8A16_
M16_ MAX_ K - 2026-09-27: Largest
Kof the skinny body (PM16_MAX_K): one 1152-byte shared slot per 128-K step within 48 KiB. - W8A16_
M16_ MAX_ ROWS - 2026-09-27: Rows the skinny body of the same kernel takes (
PM16_MAX_M), whenKis at mostW8A16_M16_MAX_K. It gives each 8-column block the canonical tile’s per-output arithmetic with the 128-K steps’ products computed in parallel by 8 warps and added in step order. - W8A16_
M32_ K_ BLOCK - 2026-09-25: K granularity: one FP8 scale block per K-step (
PM32_K_STEP == PM32_FP8_BLOCK), which is whyK % 128 == 0is required rather than padded. - W8A16_
M32_ TILE_ ROWS - 2026-09-25: Rows one M tile covers (
PM32_M_TILE). Above it the kernel still runs, withgrid.y = ceil(M / 32)and one weight pass per tile;w8a16_pipelined_prefers_m32sends contiguous callers to the 128-tile kernel past this bound. - W8A16_
M64_ TILE_ ROWS - 2026-09-26: Rows of the
w8a16_gemm_pipelined_m64tile. - W8A16_
TC_ ROWS_ COLS - 2026-09-28: Output columns per CTA (
TR_COLS). - W8A16_
TC_ ROWS_ MAX_ M - 2026-09-28: Widest row count of one row chunk (
8 * NTofw8a16_tc_rows_64); more rows run as chunks of it (w8a16_tc_rows_64c).
Functions§
- allow_
e4m3_ saturation - 2026-09-30: While the returned scope lives, a saturation on this thread up to
saturation.boundis logged once and counted instead of panicking. Scopes nest; the innermost one applies. - argmax_
bf16 - 2026-09-25: Index of the largest of
vocab_sizeBF16 logits, written as one u32 toout, by a single block. - argmax_
bf16_ batch - 2026-09-25:
argmax_bf16forn_rowsrowsrow_strideapart, one block per row. Each block runs the per-row body ofargmax_bf16(argmax_bf16.cu), so a row’s index equals whatargmax_bf16returns for it. - argmax_
bf16_ batch_ feed - 2026-09-25: Batched argmax into the feed
cells(device u32 per row) with a per-row pair of masked idsmasks([m0, m1]per row,u32::MAX= none): when the plain argmax is a masked id, the row gets the argmax with both ids excluded.argmax_feed.custates the tie rules. One block per row. - argmax_
bf16_ batch_ lp - 2026-09-25:
argmax_bf16_batchthat also writes each row’s top-1 log-probability,out_logprob[row] = log softmax(row)[argmax]in FP32, from an online softmax in the same pass over the row. D-Cut ranks verification depths by prefix sums of these values. - ba_
gates_ cross_ warp_ pair - 2026-09-25: The two warp partials summed for output
local_out, in order: the parent’ssmem[local_out * 2] + smem[local_out * 2 + 1]. - ba_
gates_ lane_ kv - 2026-09-25: The
kvindices lanelaneaccumulates, in order: the parent’sfor (kv = lane; kv < K_VEC; kv += threads_per_out). The order is the reduction order. - ba_
gates_ log - 2026-09-25: Log which kernel runs and, when the lever asked for the twin and
a guard refused, which guard, once per process per slot. The call runs once
per layer per step and its verdict depends on
m, so each outcome keeps its own flag and names themit was first reached at. - ba_
gates_ log_ slot - 2026-09-25: The slot a verdict belongs to, or
Nonewhen the lever was not requested. Pure, so tests can replay a call sequence on the CPU. - ba_
gates_ min_ tokens - 2026-09-25: The smallest token count the twin accepts with
sm_countSMs (0 is treated as 1). - ba_
gates_ output - 2026-09-25: The BA output a thread owns:
group * BA_GATES_OUTS + local_out. The parent’s group isblockIdx.x; the twin’s isg0 + g, walking0..ceil(N/4)in tiles ofBA_GATES_GROUPS. - ba_
gates_ pick - 2026-09-25: Choose between the gb10 parent and the Hopper twin. Its one
caller is
ssm_preproc::dense_gemm_ba_gates_prefill, which the five BA-gate call sites share, so the rule exists once. - ba_
gates_ slot - 2026-09-25: Where output
nlands in the[gate(nv), beta(nv)]row:Ok(vh)for a gate (alpha) element,Err(vh)for a beta element, split as the parent splits them onwithin_group < vheads_per_group. - ba_
gates_ sm_ count - 2026-09-25: The device’s SM count, or
BA_GATES_FALLBACK_SM_COUNTwhen the query fails; at least 1. - ba_
gates_ warp - 2026-09-25: The block-wide warp that holds lane
laneof outputlocal_out. The parent writes its warp partial tosmem[local_out * 2 + lane / 32]and the twin tored[g * BA_GATES_WARPS + threadIdx.x / 32]; they match becausethreadIdx.x / 32 == local_out * 2 + lane / 32. - batched_
chunk_ zero_ admitted - 2026-09-28: The pure rule behind
prefill_batched_chunk_zero_admitted. - batched_
embed - 2026-09-25: Gather the BF16 embedding rows of
num_tokenstoken ids (token_ids_dev, device[num_tokens]u32) intooutput, one block per token. - batched_
embed_ fp8 - 2026-09-25:
batched_embedover an FP8 E4M3 table with one f32 scale per row (thequantize_bf16_to_fp8layout); rows are dequantized to BF16 on read. - bf16_
absmax - 2026-09-25: Max absolute value of
n_elemsBF16 values, folded into the f32 atout_maxwith an atomic max. The caller zeroesout_maxfirst; the FP8 KV calibration (fp8_calibration.rs) does so before each K/V pair. - bf16_
concat - 2026-09-25: BF16 concatenation (kernel
bf16_concat):out[0..N] = a[0..N],out[N..2N] = b[0..N]. - bf16_
grouped_ tc_ shape_ ok - 2026-10-02: Whether the BF16 tensor-core kernels take an
n-column,k-deep projection:kin whole load groups (two 32-K chunks; 128 for margin),nin whole CTAs ofgeometry. - bf16_
to_ fp8 - 2026-09-25: Cast
total_elementsBF16 values to FP8 E4M3, two per thread.total_elementsmust be even: the kernel reads and writes pairs. - check_
e4m3_ activation_ range - 2026-09-29: When
kernelcasts its A operand to E4M3 with no scale, check the[m, k]BF16inputit reads (seecheck_e4m3_range). A no-op otherwise, and in release builds. - check_
e4m3_ grouped - 2026-09-30: The grouped (pointer-table) MoE form of
check_e4m3_activation_range. The kernel reads A rowsorted_token_ids[p], or rowpwhensorted_token_idsis null, for every positionpinexpert_offsets[e]..expert_offsets[e + 1],e < num_experts; only those rows are checked, eachkBF16 values wide. A no-op for a kernel that keeps A in BF16, in release builds, and under graph capture. - check_
e4m3_ range - 2026-09-29: Debug builds: copy the
elementsBF16 values atinputto the host onstreamand panic when one exceedsE4M3_MAXin magnitude, unless anallow_e4m3_saturationscope covers it. NaN is not checked here. Skipped under graph capture, where a copy to the host cannot run. Release builds: a no-op. - compute_
gdn_ gates - 2026-09-25: GDN gates from the interleaved BA projection and the learned
A_log/dt_bias: FP32 gate (decay) and beta (write gate) per value head and token. - conv1d_
fwd - 2026-09-25: Causal depthwise conv1d followed by SiLU over a full sequence
(kernel
causal_conv1d_fwd), launched without a bias. Input[batch, dim, seq_len]BF16 (channel-first), weight[dim, d_conv]BF16, output[batch, dim, seq_len]BF16. - conv1d_
update - 2026-09-25: Causal conv1d update + SiLU for one decode token per sequence
(
causal_conv1d_update).conv_state,inputandoutputare contiguous per sequence:[batch, d_inner, d_conv],[batch, d_inner],[batch, d_inner]. - conv1d_
update_ chunk2 - 2026-09-25: Conv1d update + SiLU for two tokens per sequence in one launch
(
causal_conv1d_update_chunk2), one thread per channel. The conv state after the first token goes toconv_state_intermediate, for rollback. - conv1d_
update_ l2norm - 2026-09-25: Conv1d update + SiLU, then an L2 norm per
head_dimgroup over the Q and K channels (0..qk_channels), in one kernel (causal_conv1d_update_l2norm). The V channels get SiLU only. - conv1d_
update_ l2norm_ strided - 2026-09-25: Conv1d update + SiLU + L2 norm for
batch_sizedecode sequences in one launch, with FP32 output (causal_conv1d_update_l2norm_f32_strided). The input and output row strides are separate arguments because the concurrent-decode input rows are the QKVZ projection’s,qkvz_sizeapart, while the output rows ared_innerapart; a kernel that usedd_innerfor both would read sequenceb >= 1from the wrong row. - conv1d_
update_ prefill - 2026-09-25: Conv1d update + SiLU over
seq_lenprefill tokens, with separate per-token input and output strides. Runs the token-parallel kernel (conv1d_prefill_tp_k) when its handle is non-zero andMETRALE_CONV1D_TPis not0, elsecausal_conv1d_update_prefill, one thread per channel walking the tokens. - cublas_
bf16_ proj_ dense - 2026-09-25: Route a projection
out[M,N] = act[M,K] @ weightᵀthrough cuBLASLt BF16 for a weight that is already BF16[N,K]. - cublas_
bf16_ proj_ dense_ f32_ out - 2026-09-25:
cublas_bf16_proj_densewriting an FP32 output buffer, for consumers whose next kernel reads FP32. - cublas_
fp8_ m_ pad - 2026-09-25: The M extent
cublas_fp8_proj_prequanthands cuBLASLt; callers bound their output buffers against it. - cublas_
fp8_ proj - 2026-09-25: Quantize the activation with
per_token_group_quant_fp8(FP8 plus one scale per token and 128 of K), then runcublas_fp8_proj_prequant. The FP8 weight and its 128x128 block scales go to cuBLASLt as they are, with no dequant. - cublas_
fp8_ proj_ prequant - 2026-09-25:
cublas_fp8_projfor an activation the caller already ran throughper_token_group_quant_fp8, so one quantization can feed several projections (the dense FFN’s gate and up share one). - cublas_
fp8_ rowwise_ proj - 2026-09-25: Route a projection through row-wise FP8 cuBLASLt. The weight
pair comes from
requant_weight_rowwise_fp8_cached; the activation is quantized per token on every call. - cublas_
scale_ layout_ kmajor - 2026-09-25: Which VEC128 activation-scale layout the cuBLASLt block-scaled
arm passes, from
METRALE_CUBLAS_SCALE_LAYOUT, read once per process. - cutlass_
bf16_ proj - 2026-09-25: Route a projection
out[M,N] = act[M,K] @ weightᵀthrough CUTLASS BF16, against the FP8 weight’s memoized BF16 copy. - cutlass_
nvfp4_ proj - 2026-09-25: Route a projection
out[M,N] = act[M,K] @ weightᵀthrough CUTLASS NVFP4.weight_tis an NVFP4 weight with[K/2,N]packed bytes; the bytes are transposed once to[N,K/2]and memoized. - cutlass_
nvfp4_ proj_ from_ fp8 - 2026-09-25: CUTLASS NVFP4 projection for an FP8 weight. On first use the weight is dequantized into a transient BF16 buffer, packed into NVFP4 data and scales, and the pair is memoized for later calls.
- decode_
w8a8_ gemm - 2026-09-25:
out[m_pad, n] = act_fp8[m_pad, k] @ weight[n, k]ᵀat row pitchplan.ldc, with both sets of scales applied. The activation must already be throughdecode_w8a8_quant_act. - decode_
w8a8_ quant_ act - 2026-09-25: Quantize BF16
act[rows, k]into the scratch: FP8 E4M3 bytes and one FP32 scale per token and 128 of K, with the pad rowsrows..ceil16(rows)zeroed, and the scales transposed for cuBLASLt when the layout is K-major. - decode_
w8a8_ selected - 2026-09-25: Whether one decode projection takes the W8A8 cuBLASLt route;
DecodeW8a8Planlists the conditions. - deinterleave_
qg - 2026-09-25: Deinterleave Q/gate from per-head interleaved to contiguous
layout, in place, per token. Rows are
strideelements apart. - deinterleave_
qg_ split - 2026-09-25:
deinterleave_qgwith Q written toq_out(contiguous[num_tokens, num_heads * head_dim]) instead of in place. The gate is written back intodataat offsetnum_heads * head_dimof each row. - deinterleave_
qg_ split_ qnorm - 2026-09-25:
deinterleave_qg_splitfused with the per-head Q RMS norm. - deinterleave_
qg_ split_ qnorm_ mrope - 2026-09-25:
deinterleave_qg_split_qnormplus rotate-half MRoPE on the firstrotary_dimdimensions of each Q head, using the per-token positionspos_t/pos_h/pos_w. - deinterleave_
qkvz - 2026-09-25: Deinterleave the QKVZ projection output from GQA-grouped to sequential layout, per token.
- dense_
gemm - 2026-09-25: Scalar BF16 GEMM,
C = A @ B^T(kerneldense_gemm_bf16(A, B, C, M, N, K)): A[M, K]row-major, B[N, K]row-major (HuggingFace layout), C[M, N]row-major. - dense_
gemm_ ba_ gates_ prefill - 2026-09-25: BA GEMM and the GDN gate transforms for
mtokens in one kernel, with no intermediate BA buffer. - dense_
gemm_ ba_ gates_ prefill_ hopper - 2026-09-25: Launch
dense_gemm_ba_gates_prefill_hopper, one block per token. It takes the parent’s arguments in the parent’s order; only the grid differs. - dense_
gemm_ bf16_ pipelined - 2026-09-25: Tensor-core BF16 GEMM (kernel
dense_gemm_bf16_pipelined): m16n8k16 MMAs fed by a 2-stagecp.asyncpipeline on a 128x128 tile, with the inputs and output layout ofdense_gemm. - dense_
gemm_ m16_ bf16 - 2026-09-25: The default 32-wide CTA.
inputis[m, a_row_stride]BF16 withkused,weight.weightis the[n, k]BF16 weight as loaded, andoutputis[m, c_row_stride]BF16 withnused. - dense_
gemm_ m16_ bf16_ n64 - 2026-09-25: The
N_TILE = 64instantiation of the same kernel template: the same arguments asdense_gemm_m16_bf16,ceil(n / 64)CTAs instead ofceil(n / 32). - dense_
gemm_ prefill - 2026-09-25: Dense BF16 prefill GEMM:
dense_gemm_bf16_pipelinedwhenpipelined_kernelis loaded, otherwisedense_gemmwithfallback_kernel. - dense_
gemm_ router - 2026-09-25: Register-blocked BF16 GEMM (kernel
dense_gemm_bf16_router) that keeps the scalardense_gemm_bf16’s per-output FP32 accumulation order, strict k = 0..K-1, and with it the scalar kernel’s results under the--fmad=falsebuild (kernels/gb10/common/KERNEL.toml).router_gate_gemm_denseuses it for the MoE router gate GEMM. - dense_
gemm_ splitk - 2026-09-25: Split-K BF16 GEMM:
partial_kernelwrites FP32 partial products fork_splitsK chunks intoworkspace, andreduce_kernelsums them into BF16output.workspaceholdsk_splits * m * nFP32 values. - dense_
gemm_ tc - 2026-09-25: Tensor-core BF16 GEMM,
C = A @ B^T, with m16n8k16 MMAs (kerneldense_gemm_tc). - dense_
gemm_ tc_ scaled_ acc - 2026-09-25:
output[m, n] += scale * bf16(input[m, k] @ weight[n, k]^T)in one pass:dense_gemm_tcwith an accumulating epilogue, used for the LoRA expand+fold (lora_delta.rs). It saves the[m, n]scratch that a GEMM followed bybf16_scaled_addwrites and reads back. - dense_
gemv - 2026-09-25: Dense BF16 GEMV for one row,
C = A @ B^T: A[1, K], B[N, K], C[1, N]. Each 256-thread block computes 4 outputs, 64 threads per output (kerneldense_gemv_bf16(A, B, C, N, K)). - dense_
gemv_ ba_ gates - 2026-09-25: BA projection GEMV and the GDN gate/beta transforms in one kernel, for one token, with no intermediate BA buffer.
- dense_
gemv_ batch2 - 2026-09-25: Dense BF16 GEMV for two rows in one pass over the weight. Each
row follows
dense_gemv_bf16’s K order and reduction (gb10 kernels). - dense_
gemv_ batchm - 2026-09-25: Dense BF16 GEMV for M rows,
C[t] = A[t] @ B^Tfortin[0, M), reading the weight once for all rows. Each row followsdense_gemv_bf16’s K order and reduction (gb10 kernels). - dense_
gemv_ batchm_ split - 2026-09-27:
dense_gemv_batchmovermrows split intoy_blocksblock rows ofceil(m / y_blocks)rows each (at mostDENSE_GEMV_BATCHM_MAX_M): more blocks for a narrow weight such as the MoE router, and one launch past 16 rows. Each row’s result is the same as in any other split. - dense_
gemv_ fp8w - 2026-09-25: FP8-weight GEMV for one row,
C = A @ (dequant(B_fp8) * row_scale)^T: A[1, K]BF16, B[N, K]FP8 E4M3, row_scale[N]f32, C[1, N]BF16. One byte per weight, against two fordense_gemv. Each 256-thread block computes 4 outputs, 64 threads per output (kerneldense_gemv_fp8w(A, B, row_scale, C, N, K)). - dense_
gemv_ fp8w_ batch2 - 2026-09-25: FP8-weight GEMV for two rows in one pass over the weight:
input[2, K]BF16,output[2, N]BF16, scaled byweight.row_scale. Not bit-identical to twodense_gemv_fp8wlaunches: the kernel adds four products to the accumulator at once, wheredense_gemv_fp8wadds each product separately. - dense_
mm_ bf16 - 2026-09-25:
C[M, N] = A[M, K] @ B[N, K]^T, BF16 in and out, output row strideN, dispatched on M:dense_gemv_bf16at M == 1,dense_gemv_bf16_batchmat 2..=DENSE_GEMV_BATCHM_MAX_M, and the tile GEMM otherwise or when the chosen GEMV kernel is missing. - dequant_
fp8_ bf16_ bytes - 2026-09-25: BF16 bytes
dequant_fp8_bf16_intowrites forfp8w. - dequant_
fp8_ bf16_ into - 2026-09-25: Dequantize a block-scaled or per-row FP8 weight
[N,K]to BF16 intodst, a caller-owned buffer ofdequant_fp8_bf16_bytesbytes. - dequant_
nvfp4_ to_ bf16 - 2026-09-25: Dequantize an NVFP4 weight
[n, k](packed E2M1, E4M3 group scales and the per-tensorscale2) to BF16[n, k], one block per row. - dequant_
q2_ 0_ gn_ to_ bf16 - 2026-09-25: Dequantize a packed Q2_0 weight
[N, K]into the caller’s BF16 buffer[N, K]onstream, with no allocation and no host sync (kerneldequant_q2_0_gn_to_bf16in kernels/gb10/common/dequant_gguf_bf16.cu). Packed-Q2 prefill uses it to feed a BF16 GEMM while the resident weight stays packed (dense_ffn.rs,qwen3_attention/prefill_weights.rs). - e4m3_
saturations - 2026-09-30: Saturating launches counted under
sitein this process (debug builds only). - embed_
from_ argmax - 2026-09-25: Read the token id at
argmax_out, copy its BF16 row ofembed_tabletoembed_out, and copy the id totoken_id_out, all on the device. - feed_
resolve - 2026-09-25:
ids_out[i]is the inline id whensources[i]hasFEED_HOST_BITset, elsecells[sources[i]]. - fill_
slots_ from_ block_ table - 2026-09-25: Fill
countslot-mapping entries on the device from a block table:slots[i] = block_table[(start_pos + i) / block_size] * block_size + (start_pos + i) % block_size.count == 0launches nothing. - fp4_
act_ scratch_ bytes - 2026-09-25:
block_fp4_mmqactivation bytes for[m, k], withkrounded up to 256, plus 1 MiB of slack. It never exceedsq8_1_scratch_bytes(m, k), the size of theffn_act_q8scratch it is written into. - fp8_
act_ quant_ hopper_ enabled - 2026-09-25: Is the twin requested? The compiled target’s
[defaults] fp8_act_quant_hopper, overridden byMETRALE_FP8_ACT_QUANT_HOPPERwhen it is set (super::target_defaults). - fp8_
act_ quant_ hopper_ reject - 2026-09-25: Why the twin is not running;
Nonemeans it runs. - fp8_
act_ scale_ to_ kmajor - 2026-09-25: Launch
fp8_act_scale_to_kmajor: copy the quantizer’s row-major[M, K/128]FP32 activation scales into[K/128, M_pad], with zeros in theM..M_padpad rows.a_scaleis only read. - fp8_
fp8_ gemm_ m128_ mfast - 2026-09-25: FP8 x FP8 GEMM through
fp8_fp8_gemm_t_m128_mfast: a 128-row M tile with M on the fast grid axis. A must already be FP8 E4M3 (bf16_to_fp8). - fp8_
fp8_ gemm_ n128 - 2026-09-25: FP8 x FP8 GEMM: A
[M, K]FP8 E4M3 and B[N, K]FP8 E4M3 give C[M, N]BF16. - fp8_
fp8_ gemm_ n128_ m128 - 2026-09-25:
fp8_fp8_gemm_n128with a 128-row CTA (two 64-row chunks); each CTA loads a B tile once for both chunks. - fp8_
gemm_ m128_ mfast - 2026-09-25: FP8-weight GEMM through
fp8_gemm_t_m128_mfast: a 128-row M tile (two 64-row chunks per CTA) with M on the fast grid axis. - fp8_
gemm_ n128 - 2026-09-25: FP8-weight prefill GEMM,
C = A @ B_fp8^T: A[M, K]BF16, B_fp8[N, K]FP8 E4M3 (frompredequant_nvfp4_to_fp8), C[M, N]BF16. - fp8_
gemm_ n128_ m128 - 2026-09-25: FP8-weight GEMM with a 128-row CTA (two 64-row chunks); each CTA loads a B tile once for both chunks.
- fp8_
gemm_ n128_ mfast - 2026-09-25: FP8-weight GEMM through the
fp8_gemm_t_mfastkernel, with M on the fast grid axis (blockIdx.x= M block), so consecutive CTAs share a B panel. - fp8_
gemm_ n128_ row_ scaled - 2026-09-25: Row-scaled FP8 GEMM,
C[M, N] = A[M, K] @ (dequant(B_fp8[N, K]) * row_scale[N])^T; the scale multiplies each output column before the BF16 store. Takes theFp8DenseWeightfromcrate::weight_map::DenseWeight::quantize_to_fp8. The DFlash drafter calls it when its quantization isFp8Weights(dflash_head/forward_block_layer_paged.rs). - fp8_
gemm_ n128_ row_ scaled_ m16 - 2026-09-25:
fp8_gemm_n128_row_scaledthrough the single-warp kernelfp8_gemm_t_row_scaled_m16, whose M tile is 16 rows. The grid has no M dimension, sommust be at most 16: rows past the tile are not computed. - fp8_
gemm_ t_ blockscaled - 2026-09-25: W8A8 GEMM with per-token activation scales and per-block weight scales, applied in an FP32 epilogue per 128-element K-group:
- fp8_
gemv_ rowscale_ batch8_ rt2 - 2026-09-25: Register-tiled row-scaled FP8 GEMV for up to 8 rows, two
outputs per 64-lane group (kernel
fp8_gemv_rowscale_batch8_rt2, modulefp8_gemv_rt).input[M, K]BF16,output[M, N]BF16; the kernel appliesrow_scale[n]at write-out. The DFlash drafter’s FP8 path calls it (dflash_head/forward_block.rs). Refusesmoutside1..=8and akthat is not a multiple of 16. - fp8_
gemv_ rowscale_ batch16_ rt2 - 2026-09-25: The 16-row instantiation of the same kernel template
(
fp8_gemv_rowscale_batch16_rt2, modulefp8_gemv_rt), with the launch geometry offp8_gemv_rowscale_batch8_rt2. Refusesmoutside1..=16and akthat is not a multiple of 16. - fp8_
grouped_ active_ cap - 2026-09-25: Cap on active experts, which sizes the grouped grids’ Y extent:
num_tokens * top_krows can reach at most that many distinct experts. It does not depend on the routing, so a captured graph stays valid for every routing. - fp8_
grouped_ tc_ shape_ ok - 2026-09-28: Whether the tensor-core kernels take an
n-column,k-deep projection: both in whole 128 blocks (the FP8 scale blocks) andnin whole CTAs ofgeometry. - fp8_
quant_ grid - 2026-09-25: Grid for one quantizer launch. Pure, so
fp8_act_quant_tests.rschecks both arms without a GPU. - fp8_
quant_ hopper_ ctas - 2026-09-25: CTAs the twin’s grid launches for
(m, k): the product ofsuper::fp8_quant_grid’s Hopper arm, so the floor measures the grid the launch uses. - fp8_
quant_ hopper_ lane - 2026-09-25: The group slot thread
tidof a Hopper CTA works on, and the half-open range[start, end)of 8 elements it owns within that 128-element group, assub/lanein the.cu.Nonewhen the slot is past the CTA’s span. - fp8_
quant_ hopper_ min_ m - 2026-09-25: The smallest
mthe twin accepts at thisk: the table in this module’s header, as a function. - fp8_
quant_ hopper_ span - 2026-09-25: The half-open K-group range one Hopper CTA owns, computed as
the
.cucomputesgpc/g0/g_end.fp8_act_quant_tests.rsuses it to check on the host that the grid’s Y extent and the kernel’s span partition the groups. - fp8_
quant_ log - 2026-09-25: Log which quantizer runs and, when the lever requested the twin
and did not get it, which reason refused it: once per process per slot.
per_token_group_quant_fp8calls this on every launch. - fp8_
quant_ log_ slot - 2026-09-25: The slot a verdict belongs to, or
Nonewhen it is not logged. Pure, so tests replay a call order on the CPU. - fp8_
quant_ min_ ctas - 2026-09-25: The smallest twin grid, in CTAs, the floor accepts for this SM
count; an
sm_countof 0 counts as 1. - fused_
k_ norm_ rope_ cache_ write_ bf16 - 2026-09-25: K norm (
x * rsqrt(mean(x^2) + eps) * (1 + w)), RoPE and the paged BF16 cache write in one kernel. K stays in FP32 from the BF16 load to the single BF16 rounding at the store. One block per (token, KV head) withhead_dimthreads; the kernel supportshead_dim <= 256. - fused_
k_ norm_ rope_ cache_ write_ bf16_ mrope - 2026-09-25: The interleaved-MRoPE variant (kernel
fused_k_norm_rope_mrope_cache_write_bf16): rotation pairitakes its position frompos_t,pos_horpos_wbyi % 3. The rest of the kernel is the scalar-position one, so equal position streams give its results. - fused_
k_ norm_ rope_ cache_ write_ fp8 - 2026-09-25:
fused_k_norm_rope_cache_write_bf16writing an FP8 E4M3 cache. The FP32 result timesinv_scale(1 / k_scale) goes through one saturating FP8 cast, with no BF16 rounding. - fused_
k_ norm_ rope_ cache_ write_ fp8_ kv - 2026-09-25: Decode-path fusion of
rms_norm+rope_forward+reshape_and_cache_flash_fp8for an FP8 KV cache: writes K (normed, rotated, quantized) and V (quantized) in one launch, leavingrope_forwardfor Q only. - gated_
rms_ norm - 2026-09-25: Gated RMS norm of
num_tokensrows, one block per row; the gate row of tokentstarts att * gate_stride. The order of norm and gate is the resolved kernel’s.gated_rms_normandgated_rms_norm_f32_inputinkernels/gb10/common/rms_norm.cucomputerms_norm(input) * weight * silu(gate)and ignoregroup_size. The per-group shadows, e.g.kernels/gb10/minimax-m2-229b/nvfp4/rms_norm.cu, gate first and normalise eachgroup_sizeslice. - gated_
rms_ norm_ prefill - 2026-09-25: Gated RMS norm of every
(head, token)row of a prefill chunk in one launch.inputandoutputrows of tokentstart att * input_token_stride, and gate rows att * gate_token_stride, both in BF16 elements. - gated_
rms_ norm_ strided - 2026-09-25: Gated RMS norm of every
(head, sequence)row of a multi-sequence decode in one launch:heads_per_seqrows per sequence,num_seqssequences. Sequence strides count elements of each buffer’s own type:input_seq_stridein f32,gate_seq_strideandoutput_seq_stridein BF16. - gdn_
carry_ conv - 2026-09-26: Carried-state conv verify (
gdn_carry_conv): the twin ofgdn_verify_fused_conv_kn_batchedthat first shifts each sequence’s pending input rows into its window (writing it back when there were any), writes no snapshot and no final window, and stashes the position inputs atconv_stash + slot * stash_seq_elems.lazymust match the verify kernel of the same run (gdn_carry_wy{K}_lazy): the window is then written back only when the stash is full, else on every launch. - gdn_
carry_ conv_ f32 - 2026-10-01: Carried-state FP32 conv verify (
gdn_carry_conv_f32): the twin ofcausal_conv1d_update_l2norm_f32_stridedfor allnum_tokenspositions ofn_seqsequences, withgdn_carry_conv’s pending-row fold and stash. Sequence b’s window is atconv_state + b * dim * d_convfloats; rowb * num_tokens + treadsnew_inputatinput_strideand writes the FP32outputatoutput_stride.lazymust match the verify kernel of the same run. - gdn_
carry_ conv_ flush - 2026-09-26: Standalone conv fold (
gdn_carry_conv_flush) overlayersGDN layers, laid out as ingdn_carry_flushwith conv-state pointers and a BF16 stash. - gdn_
carry_ conv_ seq_ elems - 2026-09-26: Per-(layer, slot) conv stash length in BF16 elements:
GDN_CARRY_CAPinput rows. - gdn_
carry_ flush - 2026-09-26: Standalone fold (
gdn_carry_flush) overlayersGDN layers: layerlreads its h pointers at entryl * table_layer_entriesofh_table, its stash atcarry_base + l * carry_layer_floatsfloats and its counts atpend + l * pend_layer_entries. A count of 0 leaves H alone;pendis not cleared. - gdn_
carry_ seq_ floats - 2026-09-26: Per-(layer, slot) stash width in floats:
vn[CAP][nv][vd] | g[CAP][nv] | sk[CAP][nv][kd], the layout of the kernel’sCARRY_VN/CARRY_G/CARRY_SKmacros. - gdn_
carry_ wy - 2026-09-26: Carried-state verify (
gdn_carry_wy{2,3,4}or its_lazyform, chosen by the caller’skernel). It applies each sequence’s pending rows (pend[slot_tab[b]]) to its copy of H and writes H back (the lazy form only when this verify’s rows might not fit behind them in the stash,pending + K > GDN_CARRY_CAP), writes the output, and stashes the rows it verified atcarry_base + slot * seq_floats. Engaged word b becomes 2 after a write-back, else 1. - gdn_
conv_ chain_ f32 - 2026-10-01: The single-sequence exact verify’s FP32 conv (
gdn_conv_chain_f32):num_tokenspositions ofcausal_conv1d_update_l2norm_f32_stridedfor one sequence in one launch, the window after position t (t < num_tokens - 1) atconv_inter[t], the final window atconv_state. The unusedconv_interentries must be valid pointers; they are not written. - gdn_
conv_ chain_ f32_ batched - 2026-10-01:
super::gdn_conv_chain_f32forbatchsequences on consecutive conv slots (dim * d_convfloats apart): rowb * num_tokens + treadsnew_input + row * input_strideand writesoutput + row * output_stride; the window after position t < num_tokens - 1 goes toconv_inter + b * inter_strides[1] + t * inter_strides[0]floats. - gdn_
decode - 2026-09-25: Single-token GDN decode (
gated_delta_rule_decode). Thebatch_sizeh-states are contiguous:[batch, num_v_heads, k_dim, v_dim]FP32. - gdn_
decode_ chunk2 - 2026-09-25: Two tokens through the GDN recurrence in one launch
(
gated_delta_rule_chunk2). The state after the first token is written toh_state_intermediate, for rollback when the draft is rejected. The strides are in elements, not bytes. - gdn_
decode_ chunk3 - 2026-09-25: Three tokens through the GDN recurrence in one launch
(
gated_delta_rule_chunk3). The states after the first and second tokens go toh_state_inter0andh_state_inter1, for rollback when drafts are rejected. - gdn_
decode_ f16_ strided_ norm - 2026-09-25: FP16 h-state twin of
gdn_decode_f32_strided_norm, used whenssm_h_fp16_enabled()is set. It adds one argument,h_seq_stride: the per-sequence slot pitch of the h-state pool in__halfelements. The pitch depends on how the pool was sized, not on the head dims, so the caller passes it. - gdn_
decode_ f32_ conv_ norm - 2026-09-25: Conv1d update + L2 norm, the GDN recurrence and the gated RMS
norm in one decode launch (
gated_delta_rule_decode_f32_conv_norm). - gdn_
decode_ f32_ norm - 2026-09-25: FP32 GDN decode fused with the gated RMS norm: the kernel normalises each v-head’s output in the same CTA and writes BF16, with no FP32 output buffer in global memory.
- gdn_
decode_ f32_ norm_ snap - 2026-09-25:
super::gdn_decode_f32_normplus an inline h-state snapshot. - gdn_
decode_ f32_ strided - 2026-09-25: Strided FP32 GDN decode for several sequences in one launch:
Q/K/V, gate/beta and the output are rows
qk_stride,v_stride,gb_strideandout_strideapart per sequence. - gdn_
decode_ f32_ strided_ norm - 2026-09-25:
gdn_decode_f32_stridedfused with the gated RMS norm: it writes the BF16 post-norm output directly,out_strideapart per sequence. - gdn_
decode_ f32_ strided_ norm_ snap - 2026-09-25:
super::gdn_decode_f32_strided_normplus an inline h-state snapshot, for the batched-verify arm overbatch_sizesequences. - gdn_
decode_ strided_ smem - 2026-09-29: The dynamic shared memory
gdn_decode_f32_stridedreserves forbatch_size. - gdn_
decode_ wy2 - 2026-09-25: WY-chunkwise 2-token verify decode (
gated_delta_rule_wy2). One pass over H computes both tokens’H^T kproducts, the WY correction is applied, and a second pass updates H and writes the intermediate state. - gdn_
decode_ wy3 - 2026-09-25: WY-chunkwise 3-token verify decode (
gated_delta_rule_wy3): thegdn_decode_wy2scheme for three tokens, with two intermediate states. - gdn_
decode_ wy4 - 2026-09-25: WY-chunkwise 4-token verify decode (
gated_delta_rule_wy4): thegdn_decode_wy2scheme for four tokens, with three intermediate states. - gdn_
decode_ wy4_ woa - 2026-09-25: Write-on-accept K=4 verify (
gated_delta_rule_wy4_woa). It writes the output but no state, and stashes the per-row update terms forgdn_wy4_fold. The state arguments are pointer tables. - gdn_
decode_ wyn - 2026-09-25: WY-chunkwise verify decode for K tokens, contiguous form: the
launch for
gated_delta_rule_wy5..wy16(and their_f16twins) fromgated_delta_rule_wyn.cu, and forgated_delta_rule_wy17. K is compile-time in the kernel, so thekernelhandle selects it. The kernel writes Hi_0..Hi_{K-2} and the final H. - gdn_
decode_ wyn_ table - 2026-09-25: Cross-sequence batched-verify launch of the wyN pointer-table
twins (
gated_delta_rule_wy{5..16}_tableand their_f16_tableforms).state_is_tableis compiled into the symbol, so the argument list is the same asgdn_decode_wyn, but the state arguments are tables: - gdn_
exact_ carry - 2026-10-01: Carried-state exact verify (
gdn_exact_carry{2,3,4}or its_lazyform, chosen by the caller’skernel;gdn_exact_carry.cuin the model directory): the stash protocol ofgdn_carry_wyaround the strided FP32 decode’s per-token chain. Rows are sequence-major,b * K + t: FP32 q and k atqk_stride, v atv_stride, gate and beta atgb_stride, the FP32 output atout_stride, all in floats. - gdn_
exact_ chain - 2026-10-01: The single-sequence exact verify (
gdn_exact_chain{2,3,4}, chosen by the caller’skernel): K rows of one sequence’s strided-decode chain in one launch.h_stateis updated to the state after the last row,h_inter[t]receives the state after row t (t < K - 1; the other entries must still be valid pointers and are not written). Rows arestrides = [qk, v, gate|beta, out]floats apart. - gdn_
exact_ chain_ f16 - 2026-10-01: The FP16 h-state exact verify, K = 2..4 rows per sequence (
kernelis thegdn_exact_chain_f16_{K}entry): the decode’s FP16 fused-norm chain per row with the state in registers, the FP16 intermediates of rows 0..K-2 and the final state written, and the BF16 normed rows. Rows areb * K + t;stridesis[qk, v, gb, z, out]per row. - gdn_
init_ spine_ line - 2026-09-25:
GDN state spine: …, the lineqwen3_ssm::initprints for each layer as it binds the handles, before any prefill has run. - gdn_
prefill - 2026-09-25: Token-sequential GDN prefill (
gated_delta_rule_prefill): one block per (v-head, sequence) walks allseq_lentokens. Q/K/V and gate/beta are read at their own per-token strides, so the packed conv output needs no repacking. - gdn_
prefill_ fla - 2026-09-25: Chunked GDN prefill in three launches, ordered by
stream: - gdn_
prefill_ persistent - 2026-09-25: Persistent GDN prefill (
gated_delta_rule_prefill_persistent): each block loads its v-head’s H into shared memory once, runs every token against it, and writes it back to global memory once at the end. - gdn_
prefill_ persistent_ batched - 2026-09-25: Batched persistent prefill with H plus double-buffered k and q
in shared memory (
gated_delta_rule_prefill_persistent_batched). - gdn_
prefill_ persistent_ smem - 2026-09-25: Persistent GDN prefill whose shared-memory size the caller computes, for kernels with a larger layout (the WY4-persistent and WY64 prefill kernels).
- gdn_
prefill_ persistent_ smem_ batched - 2026-09-25: Batched persistent prefill whose shared memory the caller
computes (
gated_delta_rule_prefill_wy64_batchedorgated_delta_rule_prefill_persistent_wy4_batched). - gdn_
prefill_ regresident - 2026-09-25: Token-sequential prefill recurrence with H in registers
(
gated_delta_rule_prefill_regresident). One warp owns one v-column and holds its 128 k-rows (4 per lane); there is no shared-memory H and no block barrier. Requiresk_dim == 128andv_dim % 4 == 0(4 warps per block). - gdn_
prefill_ split - 2026-09-25:
gdn_prefillwith v_dim split across 2 blocks per v-head (gated_delta_rule_prefill_split). - gdn_
prefill_ split4 - 2026-09-25:
gdn_prefillwith v_dim split across 4 blocks of 32 threads per v-head (gated_delta_rule_prefill_split4). - gdn_
prefill_ split4_ batched - 2026-09-25: Batched split4 prefill
(
gated_delta_rule_prefill_split4_batched). - gdn_
scalar_ spine - 2026-09-28:
gdn_scalar_spine_fromof this process’s environment, read once. - gdn_
scalar_ spine_ from - 2026-09-28: From the values of
METRALE_GDN_PIPEandMETRALE_GDN_VTILE:PIPE=1picks the pipe spine (as before), elseVTILE=1the vtile spine, elsePIPE=0the vfused spine, else the pipe spine. - gdn_
tc_ spine_ route_ line - 2026-09-25:
GDN state spine: …, the line the prefill logs when the tensor-core spine runs, built fromGDN_TC_SPINE_ENTRY. Pure and returning aString, so the tests below can check it. - gdn_
verify_ fused_ conv_ k2 - 2026-09-25: K=2 MTP-verify conv1d + SiLU + L2 norm: both draft positions in one launch, with the position-0 conv-state snapshot written inline.
- gdn_
verify_ fused_ conv_ kn - 2026-09-25: K-position verify conv1d + SiLU + L2 norm: all
num_tokensdraft positions in one launch. Positiont’s conv-state snapshot is written toconv_state_inter + t * inter_stride. - gdn_
verify_ fused_ conv_ kn_ batched - 2026-09-25:
gdn_verify_fused_conv_knforn_seqsequences in one launch, one grid row (blockIdx.y) per sequence. - gdn_
verify_ fused_ conv_ kn_ f32 - 2026-09-25: FP32-output twin of
super::gdn_verify_fused_conv_kn: one launch runs conv1d + SiLU + L2 norm for all K verify positions, writes FP32 conv rows, and writes each per-token conv-state snapshot inline.output_strideis in FP32 elements. - gdn_
verify_ fused_ norm_ k2 - 2026-09-25: K=2 MTP-verify gated RMS norm: both draft positions in one
launch. The Z gate is read from the deinterleaved [Q|K|V|Z] buffer at
z_offsetwithin each position. Thegdn_verify_fused_microtestexample checks it against the per-tokengated_rms_normat cos >= 0.99999. - gdn_
wy4_ flag_ clear - 2026-09-25: Clear a layer’s write-on-accept engaged word. The caller issues it at the start of a batched verify that requested write-on-accept, on the stream of the launches that follow.
- gdn_
wy4_ fold - 2026-09-25: Post-verdict fold (
gated_delta_rule_wy4_fold). When the engaged word is set, it applies stashed rows0..na_tab[b]to H, reading and writing H once. Otherwise the parent kernel ran, and a partial accept (na < k_rows) restoresHi(na - 1)fromhi_tables. - gemv_
sw_ from - 2026-09-25: Polarity of the
METRALE_NO_GEMV_SWkill switch, given the variable’s value: the single-warp GEMV is on unless the value is exactly"1", so=0and an empty value leave it on. - grouped_
gemm_ mla - 2026-09-25:
gindependent GEMMsC_g[m, n_g] = A_g[m, k_g] @ B_g[n_g, k_g]^Tin one launch.A_gsits at columng * k_gof A,B_gat rowg * n_gof B, andC_gat columng * n_gof C; one block per(row, group)computes 4 outputs. - hc_
expand - 2026-09-25: Broadcast the BF16 hidden state into
hc_multidentical FP32 streams:streams[t, i, d] = hidden[t, d]. - hc_head
- 2026-09-25: Final collapse before the LM head: one learned sigmoid-weighted sum over the
hc_multstreams, written as BF16[T, H]. - hc_
head_ lowrank - 2026-09-25: The model-level mixer (
use_combine=Falsein the reference bench/qwen4_exp/ref/modeling_qwen4_exp.py): the same collapse with no injection vector, on the same path choice ashc_pre_lowrank. It is also the model’s final normalization: the config parser setsfinal_norm_identity(config/src/parsers/qwen4_exp.rs). - hc_
head_ site - 2026-09-25: The model-level final collapse before the LM head. In the low-rank family this is
also the model’s final normalization: the Qwen3.8-Flash-Next config parser sets
final_norm_identity(config/src/parsers/qwen4_exp.rs), and the mixer’shc_normnormalizes. - hc_post
- 2026-09-25: Expand the sublayer output back into
hc_multstreams:out[t,j,d] = post[t,j] * block_out[t,d] + sum_i comb[t,i,j] * residual[t,i,d].outmay aliasresidual: each element’s residual values are read before its outputs are written. - hc_
post_ lowrank - 2026-09-25: Inject the block output back into every stream:
out[t, s*H + d] = residual[t, s*H + d] + block_out[t, d] * inj[t, s]. There is nocombargument: this family scales each stream by one scalar. - hc_
post_ site - 2026-09-25: Inject the block output back into every stream.
outmay aliasresidual. - hc_pre
- 2026-09-25: Collapse the
hc_multstreams to one BF16 row (an RMS-rescaled mix gives sigmoidpreweights for the weighted sum), and writepost_out [T, hc]and the Sinkhorn-normalizedcomb_out [T, hc, hc]for the matchinghc_post. - hc_
pre_ lowrank - 2026-09-25: Collapse the
hc_multstreams to one, and emit the per-stream injection weights the matchinghc_post_lowrankneeds:streams [T, hc, H] -> y_out [T, H]BF16,inj_out [T, hc]FP32. Fails whenw.inject_wis null (a site without an injection weight is the model-level mixer, which useshc_head_lowrank). - hc_
pre_ site - 2026-09-25: Collapse the streams to one and emit what the matching
hc_postneeds:postandcombfor Sinkhorn, the injection vector inpost_outfor low-rank. - int8_
gemm_ faith2_ prefill - 2026-09-25: int8 prefill GEMM: requantize the BF16 activations to int8
with one F32 scale per 32 elements (
requant_a_kernel), then multiply them with the int8 weight fromrequant_w_nvfp4_int8(faith2_kernel). Both launches go onstream. - kquant_
mmq_ act_ bytes - 2026-09-25: Bytes of the MMQ-layout q8_1 buffer for
[m, k]activations: 144 B per 128 values, withmrounded up to the 128-row tile andkto 256. - kquant_
mmq_ gemm - 2026-09-25: Prefill GEMM on raw blocks through the vendored MMQ engine:
out[m][n](bf16) =A_q8[m][k]xW[n][k].a_q8must be in the type’s MMQ q8_1 layout (D2S6 for Q2_K, D4 for Q3_K), andsmemis the matching*_MMQ_SMEM.kernel_ncservesn % 128 == 0, andkernel_wc(bounds-checked) any othern. The kernel’s arguments are(x = weights, y = activations, dst, nrows_x = n, ncols_dst = m, ncols_x = k, stride_row_x = k / 256, ncols_y = m, stride_col_dst = n). - kquant_
mmvq - 2026-09-25: Decode GEMV on raw blocks:
out[m][n] = sum_k xq8[m][k] * W[n][k](kquant_mmvq_q2_k/kquant_mmvq_q3_k), one 4-warp block per output row.w_blocksis[n][k/256]raw super-blocks;y_q8is theblock_q8_1 [m][k/32]buffer;out_bf16is[m][n]. - kquant_
mmvq_ experts - 2026-09-25:
kquant_mmvq_*_experts: one launch overn_expertsexperts whose block pointers sit in the device tablevxs. The activation for experteisy_q8 + e * y_stride_bytes(0 = shared), its outputout_bf16 + e * m * n. Each expert’s rows go through the same device function askquant_mmvq. - kquant_
mmvq_ experts_ w - 2026-09-25:
kquant_mmvq_*_experts_w: the warp-per-row expert batch, with the same arguments askquant_mmvq_experts. - kquant_
mmvq_ experts_ wn - 2026-09-25:
kquant_mmvq_experts_wwithnwarpsrows a block (the_w2/_w8entries for 2 / 8; the plain_wentry is 4). One warp computes each row in the same way for anynwarps. Fails unlessnwarpsis 2, 4 or 8. - kquant_
mmvq_ groups_ w - 2026-09-25:
kquant_mmvq_q2_k_groups_w:n_groupsindependent[n, k]GEMVs in one launch. Groupgtakes weight rows[g*n, (g+1)*n)(w_blocksis[n_groups * n][k/256]) against activation columns[g*k, (g+1)*k)of theblock_q8_1 [m][n_groups * k / 32]buffery_q8, and writes columns[g*n, (g+1)*n)ofout_bf16([m][n_groups * n]). Each group runs the per-row code ofkquant_mmvq_wwith offsets. - kquant_
mmvq_ pair_ w - 2026-09-25:
kquant_mmvq_q2_k_pair_w: two[n_i, k]Q2_K projections of one activation (y_q8,block_q8_1 [m][k/32]) in one launch,out_i=[m][n_i]bf16. Grid y picks the projection, and each runs the same device function askquant_mmvq_w. - kquant_
mmvq_ w - 2026-09-25:
kquant_mmvq_*_w: the warp-per-row GEMV (four rows a block, reduced by warp shuffle), with the same arguments askquant_mmvq. - kquant_
q8_ 1_ rows - 2026-09-25: bf16
[m, k]->block_q8_1 [m, k/32](kquant_q8_1_rows_bf16), one warp per block. Fails unlessk % 32 == 0. - kquant_
q8_ 1_ rows_ bytes - 2026-09-25: Bytes of the plain
block_q8_1buffer for[m, k]activations. - kquant_
swiglu_ q8_ 1_ rows - 2026-09-25:
moe_v41_swigluandkquant_q8_1_rowsin one launch (kquant_swiglu_q8_1_rows_bf16):h[rows, inter] = bf16(swiglu(gate, up) * w[row]), then the q8_1 blocks of those bf16 rows.kquant_fold_testscompares both outputs byte for byte with the two launches.wmay be null. Fails unlessinter % 32 == 0. - kquant_
weight_ bytes - 2026-09-25: Raw bytes of an
[n, k]K-quant weight. - l2_norm
- 2026-09-25: In-place L2 normalization of each head,
x / sqrt(sum(x^2) + eps)(kernell2_norm_bf16).datais[num_tokens, stride]BF16 withnum_heads * head_dimused per token; one block per (head, token). - log_
cutlass_ nvfp4_ route - log_
gemm_ shape - 2026-09-25: With
METRALE_GEMM_SHAPE_LOG=1, log each (kernel, M, N, K) GEMM shape once per backend at warn level, with its FLOP count. - mamba2_
ssd_ bmm - 2026-09-25: K2:
CB[c][g][t][s] = C_t . B_s(raw, FP32). - mamba2_
ssd_ cumsum - 2026-09-25: K1: per-chunk dt (softplus and clamp) and the inclusive cumsum of the log-decay.
- mamba2_
ssd_ scan - 2026-09-25: K3: chunk_state, state_passing and chunk_scan fused in one kernel. The running state h0 stays in shared memory, so no per-chunk state tensor is written to global memory.
- mamba2_
ssm_ prefill - 2026-09-25: Mamba-2 SSM prefill (
mamba2_ssm_prefill): the token-sequential recurrence overseq_lentokens in one launch.x_stride,bc_stride,dt_strideandy_strideare BF16 elements between consecutive tokens. - mamba2_
ssm_ prefill_ persistent - 2026-09-25: Mamba-2 SSM prefill with each block’s H slice in shared memory
for the whole token loop (
mamba2_ssm_prefill_persistent). Same arguments asmamba2_ssm_prefill, but launched withhead_dim * SUBthreads and dynamic shared memory. - mla_
batched_ gemv - 2026-09-25: MLA batched GEMV over all heads in one launch:
output[head, n] = sum_k(weight[head, n, k] * input[head, k]), BF16, with the per-head input and output atinput_stride/output_strideand the weight contiguous per head. - mla_
cache_ assemble - 2026-09-25: Assemble one token’s cache entries: K =
[kv_latent | k_rope]and V =[kv_latent | zeros], eachmla_cache_dimwide. The block has one thread per element (max(mla_cache_dim, 256)threads). - mla_
cache_ assemble_ batched - 2026-09-26: Per token, write the compressed MLA cache rows: K =
[kv_latent | k_rope], and V =[kv_latent | zeros]in the mistral-small-4 kernel or[kv_latent | k_rope]in the deepseek-v4-flash kernel. - mla_
fused_ prefill - 2026-09-25: MLA prefill in one kernel: Q absorption through
w_uk, attention over the latent cache, and V extraction throughw_uv. One block per(head, query token). - mla_
kv_ assemble_ batched - 2026-09-25: Per token, build K as
[k_nope | k_rope]for each KV head (k_rope shared by all heads) and extract V fromkv_expanded.blockIdx.y0 builds K, 1 extracts V. - mla_
paged_ decode_ fp8 - 2026-09-25: MLA paged decode for DeepSeek-V4-Flash over an FP8 cache (kernel
mla_paged_decode_fp8), with scalar dequant scalesk_scale/v_scaleandcache_stridein bytes.sinks(per-head attention sinks, FP32) may be null. The compressed-KV pool is attended only whencomp_poolis non-null andcomp_block_count > 0. - mla_
paged_ decode_ nvfp4 - 2026-09-25: MLA paged decode for DeepSeek-V4-Flash over an NVFP4 cache (kernel
mla_paged_decode_nvfp4). A cache token iskv_lora_rank + qk_rope_head_dim= 512 + 64 = 576 values (MLA_CACHE_DIMin the kernel); each block holds packed E2M1 data (data_section_bytes) followed by one FP8 E4M3 scale per 16 values. - mla_
prefill_ attention_ 320 - 2026-09-25: Absorbed MLA prefill attention with scalar BF16 dot products and a
single KV head. The head dim is the kernel’s
MLA_HDIM: 320 in the mistral-small-4 fork, 576 in the deepseek-v4-flash one; both keep the entry namemla_prefill_attn_320. - mla_
q_ final_ assemble_ batched - 2026-09-25: Build Q as
[q_absorbed (kv_lora) | q_rope (rope)]per head and token,mla_cache_dim = kv_lora + ropewide. - mla_
q_ rope_ extract_ batched - 2026-09-25: Copy each head’s rope slice (offset
nopein the head’shd) out of Q, rowsq_dimapart, into contiguous[num_tokens, nq, rope]. - mla_
q_ rope_ scatter - 2026-09-25: Copy each head’s rope part of
q_full([nq, hd], at offsetnope) intoq_absorbed_buf([nq, mla_cache_dim], at offsetkv_lora) and into the contiguousq_rope_contiguous([nq, rope]) in one pass. - mla_
q_ rope_ writeback - 2026-09-25: Write the rotated
[nq, rope]Q rope parts back intoq_absorbed_bufat offsetkv_loraof each head’smla_cache_dimrow. - mla_
q_ rope_ writeback_ batched - 2026-09-25: Inverse of
mla_q_rope_extract_batched: write[num_tokens, nq, rope]back into each head’s rope slice of Q. - moe_
act_ quant_ e4m3 - 2026-09-28: E4M3 per (row, 128-K group) of
x[rows, k]BF16 intoq/s. - moe_
batched_ blend - 2026-09-25:
output[t] += sigmoid(dot(normed[t], gate_weight)) * shared_out[t], one block per token. A nullgate_weightblends at weight 1. - moe_
bf16_ grouped_ gemm - 2026-09-25: BF16 grouped GEMM for sorted MoE prefill, without scales:
input[total_tokens, K]BF16,weight_ptrs[e]→[N, K]BF16,output[total_expanded, N]BF16,sorted_token_ids[total_expanded]or NULL. The MoE layer’s long-prefill path uses it when its experts are BF16, which the loader sets up whenMETRALE_FP8_DEQUANT_MOE_TO_BF16=1dequantizes FP8 experts at load (qwen35/load_layers.rs). - moe_
build_ tile_ worklist - 2026-09-25: Build the compacted work-list for the grouped-GEMM grid: one
item per (expert, m-tile, n-tile) of every expert that has rows and a
non-NULL weight pointer, experts in ascending order. One CTA; thread 0
writes
worklist[2w] = expert,worklist[2w + 1] = (m-tile index << 6) | n-tile index, andtotal_tiles[0] = w. - moe_
decode_ atomic_ c4_ finalize - moe_
decode_ atomic_ c4_ silu_ down_ accum - moe_
expert_ down_ act_ bf16_ grouped - 2026-10-02: Grouped BF16 down over the hi + lo SiLU rows.
kis the intermediate width; rows ofactandoutputare sorted positions, rows ofsh_actandsh_down_outtokens. - moe_
expert_ down_ act_ fp8_ grouped - 2026-09-26: Grouped FP8 down over the SiLU product, launched with
geometry(FP8_GROUPED_DOWN_SCALARreads FP32 products,FP8_GROUPED_DOWN_TCBF16).kis the intermediate width; rows ofactandoutputare sorted positions, rows ofsh_actandsh_down_outtokens. - moe_
expert_ down_ act_ fp8_ grouped_ tc_ w8a8 - 2026-09-28: W8A8 down over the quantized SiLU products: routed rows into
outputby sorted position, the shared rows intosh_down_outby token, both BF16. - moe_
expert_ down_ act_ nvfp4_ grouped - moe_
expert_ gate_ up_ act_ bf16_ grouped - 2026-10-02: Grouped BF16 gate+up and SiLU.
gate_ptrs/up_ptrsare device tables of each routed expert’s[n, k]BF16 weight;sh_gate/sh_upthe shared expert’s. Writes the SiLU product as BF16 hi + lo rows ([positions, 2n]intoact,[num_tokens, 2n]intosh_act). - moe_
expert_ gate_ up_ act_ fp8_ grouped - 2026-09-26: Grouped FP8 gate+up and SiLU.
capisfp8_grouped_active_cap; the firstceil(num_tokens / geometry.rows_per_pass)block rows are the shared expert. Writes the productsilu(bf16(gate)) * bf16(up),[positions, n]for the routed experts intoactand[num_tokens, n]for the shared expert intosh_act: FP32 from the scalar kernel (FP8_GROUPED_GATE_UP_SCALAR), BF16 from the tensor-core one (FP8_GROUPED_GATE_UP_TC, 2026-09-28). - moe_
expert_ gate_ up_ act_ fp8_ grouped_ tc_ w8a8 - 2026-09-28: W8A8 gate+up and SiLU:
(xq, xs)the quantized layer input; writes the quantized products(act_q, act_s)by sorted position and(sh_q, sh_s)by token. - moe_
expert_ gate_ up_ act_ nvfp4_ grouped - 2026-09-27: Grouped NVFP4 gate+up and SiLU over
k-wide input rows.capisfp8_grouped_active_cap; the firstceil(num_tokens / geometry.rows_per_pass)block rows are the shared expert. Writes the FP32 productsilu(bf16(gate)) * bf16(up),[positions, n]for the routed experts intoactand[num_tokens, n]for the shared expert intosh_act(2026-10-02: the tensor-core kernel writes it as BF16 hi + lo in the same bytes, which only its down kernel reads). - moe_
expert_ gate_ up_ shared - 2026-09-25: NVFP4 gate and up GEMVs of the routed experts and the shared expert in one launch.
- moe_
expert_ gate_ up_ shared_ batch2 - 2026-09-25: Gate and up GEMVs of the routed and shared experts for two tokens in one launch
(row layout in the module doc). The shared expert uses direct weight pointers, the routed
experts the pointer tables. A
block_sizeof 256 selects the kernel’s wide decomposition (blockDim.x == 256); any other width runs the 128-thread one. - moe_
expert_ gate_ up_ shared_ batch3 - 2026-09-25:
moe_expert_gate_up_shared_batch2for three tokens. - moe_
expert_ gate_ up_ shared_ batch2_ t - 2026-09-25: NVFP4 fused gate+up GEMV over transposed weights, for two tokens.
- moe_
expert_ gate_ up_ shared_ batch3_ t - 2026-09-25: NVFP4 fused gate+up GEMV over transposed weights, for three tokens.
- moe_
expert_ gate_ up_ shared_ bf16 - 2026-09-25: BF16 variant of
moe_expert_gate_up_shared_fp8, with no scale tables, for experts installed byMoeLayer::set_bf16_experts. - moe_
expert_ gate_ up_ shared_ bf16_ batch2 - 2026-09-25:
moe_expert_gate_up_shared_bf16for two tokens in one launch (called fromMoeLayer::forward_k2).blockIdx.yin[0, 2*top_k)is a routed expert (tokeny / top_k, sloty % top_k, output rowtoken * top_k + slot);blockIdx.y == 2*top_kis the shared expert, computed for both tokens into rows 0 and 1. - moe_
expert_ gate_ up_ shared_ fp8 - 2026-09-25: FP8 variant of
moe_expert_gate_up_shared: two pointer tables per projection (weights, scales) and the shared expert as directFp8Weightpointers. - moe_
expert_ gate_ up_ shared_ fp8_ batch2 - 2026-09-25: FP8 fused gate+up GEMV over the routed experts and the shared
expert, for two tokens (
moe/forward_k2.rs). - moe_
expert_ gate_ up_ shared_ fp8_ batch3 - 2026-09-25: FP8 fused gate+up GEMV over the routed experts and the shared
expert, for three tokens (
moe/forward_k3.rs). - moe_
expert_ gate_ up_ shared_ fp8_ batch2_ t - 2026-09-25: FP8 fused gate+up GEMV over transposed weights, for two tokens.
- moe_
expert_ gate_ up_ shared_ fp8_ batch3_ t - 2026-09-25: FP8 fused gate+up GEMV over transposed weights, for three tokens.
- moe_
expert_ gate_ up_ shared_ fp8_ t - 2026-09-25: FP8 fused gate+up GEMV over transposed weights, for one token.
- moe_
expert_ gate_ up_ shared_ prefill - 2026-09-25: Gate and up GEMVs for
num_tokenstokens, routed and shared experts in one launch. Rowy < num_tokens * top_kis routed (tokeny / top_k, expertexpert_indices[y]) and writesgate_out/up_out([num_tokens * top_k, n]BF16); the remainingnum_tokensrows run the shared expert and writesh_gate_out/sh_up_out([num_tokens, n]BF16).blockIdx.zpicks gate (0) or up (1).inputis[num_tokens, k]BF16. - moe_
expert_ gate_ up_ shared_ t - 2026-09-25: NVFP4 fused gate+up GEMV over transposed weights, for one token.
- moe_
expert_ gemv - 2026-09-25: All top_k expert W4A16 GEMVs in one launch, output
[top_k, N].input_strideis 0 when every expert reads the same input row (gate/up) and K when slot e reads row e (down). A null weight pointer (a remote expert under EP) writes zeros. - moe_
expert_ gemv_ gate_ up - 2026-09-25: Gate and up expert GEMVs in one launch;
blockIdx.z0 is gate, 1 is up. - moe_
expert_ gemv_ gate_ up_ 2x - 2026-09-25:
moe_expert_gemv_gate_upwith two adjacent output rows per 32-thread group, 8 outputs per block. - moe_
expert_ gemv_ silu_ down - 2026-09-25: Down expert GEMV whose activation
silu(gate) * upis computed inline fromgate_outandup_out. - moe_
expert_ gemv_ silu_ down_ 2x - 2026-09-25:
moe_expert_gemv_silu_downwith two adjacent output rows per 32-thread group, 8 outputs per block. - moe_
expert_ silu_ down_ shared - 2026-09-25: NVFP4 SiLU+down GEMVs in one launch. Routed experts read
gate_out/up_out; the shared expert readssh_gate_in/sh_up_in. The kernel’ss_actis dynamic shared memory of K floats. - moe_
expert_ silu_ down_ shared_ batch2 - 2026-09-25: SiLU+down GEMVs of the routed and shared experts for two tokens in one launch.
block_sizeas inmoe_expert_gate_up_shared_batch2. - moe_
expert_ silu_ down_ shared_ batch3 - 2026-09-25:
moe_expert_silu_down_shared_batch2for three tokens. - moe_
expert_ silu_ down_ shared_ batch2_ t - 2026-09-25: NVFP4 fused SiLU+down GEMV over transposed weights, for two tokens.
- moe_
expert_ silu_ down_ shared_ batch3_ t - 2026-09-25: NVFP4 fused SiLU+down GEMV over transposed weights, for three tokens.
- moe_
expert_ silu_ down_ shared_ bf16 - 2026-09-25: BF16 variant of
moe_expert_silu_down_shared_fp8, with no scale tables. - moe_
expert_ silu_ down_ shared_ bf16_ batch2 - 2026-09-25:
moe_expert_silu_down_shared_bf16for two tokens, with themoe_expert_gate_up_shared_bf16_batch2row layout. - moe_
expert_ silu_ down_ shared_ fp8 - 2026-09-25: FP8 variant of
moe_expert_silu_down_shared: two pointer tables (weights, scales) and the shared down weight as a directFp8Weightpointer. - moe_
expert_ silu_ down_ shared_ fp8_ batch2 - 2026-09-25: FP8 fused SiLU+down GEMV over the routed experts and the shared expert, for two tokens.
- moe_
expert_ silu_ down_ shared_ fp8_ batch3 - 2026-09-25: FP8 fused SiLU+down GEMV over the routed experts and the shared expert, for three tokens.
- moe_
expert_ silu_ down_ shared_ fp8_ batch2_ t - 2026-09-25: FP8 fused SiLU+down GEMV over transposed weights, for two tokens.
- moe_
expert_ silu_ down_ shared_ fp8_ batch3_ t - 2026-09-25: FP8 fused SiLU+down GEMV over transposed weights, for three tokens.
- moe_
expert_ silu_ down_ shared_ fp8_ t - 2026-09-25: FP8 fused SiLU+down GEMV over transposed weights, for one token.
- moe_
expert_ silu_ down_ shared_ prefill - 2026-09-25: SiLU(gate) * up, then the down GEMV, for the routed and shared
rows of
moe_expert_gate_up_shared_prefill, with the same row split. Routed rows readgate_out/up_outand writeoutput([num_tokens * top_k, n]BF16); shared rows readsh_gate_in/sh_up_inand writesh_down_out([num_tokens, n]BF16). - moe_
expert_ silu_ down_ shared_ t - 2026-09-25: NVFP4 fused SiLU+down GEMV over transposed weights, for one token.
- moe_
fp8_ grouped_ gemm - 2026-09-25: FP8 grouped GEMM for sorted MoE prefill over the work-list from
moe_build_tile_worklist, which must run first on the samestream. - moe_
fp8_ grouped_ gemm_ ptrtable_ n128 - 2026-09-25: Pointer-table grouped GEMM with FP8 E4M3 activations and transposed NVFP4
weights;
a_fp8must already be FP8. Same launch shape asmoe_w4a16_grouped_gemm_ptrtable_n128. - moe_
fp8_ grouped_ sort - 2026-09-27: Sorts the
total_expandedslots oftopk_idsby expert, asmoe_sort_by_expertdoes, and writesactive_experts[0..count]in ascending order withactive_count[0] = count, in one launch onstream(the grouped kernels that read them must follow on it). - moe_
gate_ topk_ fused - 2026-09-25: Fused gate GEMV and top-k for one token (kernel
moe_gate_topk_fused):gate[num_experts] = A[K] @ B_gate[num_experts, K]^Twith an NVFP4 gate weight, then the top-k expert indices and weightsexp(logit - max)over those k, divided by their sum whennormalizeis nonzero. One 256-thread CTA;KBF16 values of dynamic shared memory hold the input. - moe_
grouped_ down_ cutlass - 2026-09-25: Single-launch CUTLASS grouped NVFP4 down GEMM through
metrale_gpu_runtime::cutlass::nvfp4_grouped_down.ais the expert-sorted post-SiLU intermediate[total_expanded, inter];expert_offsetsis the device prefix sum. - moe_
grouped_ gate_ up_ cutlass - 2026-09-25: Single-launch CUTLASS grouped NVFP4 gate_up GEMM through
metrale_gpu_runtime::cutlass::nvfp4_grouped_gate_up_fused, with the weights fromhost.expert_offsetsis the device i32[num_experts + 1]prefix sum; the host entry needs it on the host, so it is copied and the stream synchronised first. Returns that host copy, whichmoe_grouped_down_cutlassaccepts to skip its own copy and synchronise. - moe_
hash_ route - 2026-09-25: Hash router, one token: the experts are the static
tid2eid[token_id]row, and the gate’s sqrt-softplus scores weight them. The token id is read on the device fromtoken_id_ptr. - moe_
hash_ route_ batched - 2026-09-25:
moe_hash_routeforntokens, one block per token, readingtoken_ids[n]. - moe_
permute_ tokens - 2026-09-25: Gather token rows into expert-sorted order:
permuted[i] = hidden[sorted_token_ids[i]],permutedbeing[total_expanded, hidden]. One block per output row. No code calls it. - moe_
router_ gemm - 2026-09-26: The MoE router gate GEMM,
C = A @ B^Twith the operands ofdense_gemmand its bits (kernelmoe_router_gemm_bf16): each output keeps one FP32 accumulator over k = 0..K-1 in order, but a block stages a 512-wide K slice of 4 weight rows and up to 16 activation rows in shared memory at once instead of waiting on every 16-wide tile.kmust be a multiple of 16 (below thatdense_gemmadds zero padding terms). - moe_
router_ gemm_ rt - 2026-09-28:
dense_gemm_routeron 64x128 tiles with a 4x8 register tile per thread (kernelmoe_router_gemm_rt,kernels/gb10/common/moe_router_gemm_prefill.cu): the same per-output FP32 accumulation in ascending k, so the same bits. Needsk % 16 == 0. - moe_
silu_ mul - 2026-09-25:
output[i] = silu(gate[i]) * up[i]overtotal_elementsBF16 values. - moe_
sort_ by_ expert - 2026-09-25: Counting sort of the
total_expanded(token, slot) routes by expert, in one block: writessorted_token_idsandsorted_expert_idsin expert order,expert_offsets(the[num_experts + 1]prefix sum) andtoken_to_perm(each route’s sorted position). - moe_
topk_ sigmoid - 2026-09-25: Sigmoid router, one token. The bias is added to the scores for selection only;
the weights come from the pre-bias sigmoid scores.
top_kandnum_expertsare bounded byMOE_TOPK_SIGMOID_MAX_TOP_KandMOE_TOPK_SIGMOID_MAX_EXPERTS. - moe_
topk_ sigmoid_ batched - 2026-09-25: The sigmoid router with a selection-only bias for
num_tokenstokens. - moe_
topk_ softmax - 2026-09-25: Top-k experts of one token’s gate logits, with softmax weights, in one block.
The kernel handle decides the logit type (
moe_topk_softmaxBF16,moe_topk_softmax_f32). - moe_
topk_ softmax_ batched - 2026-09-25: The top-k softmax router for
num_tokenstokens. The handle picks the tie-break:moe_topk_softmax_batchedkeeps the lower lane on an equal logit,moe_topk_softmax_rows(2026-09-26) the lower expert index, asmoe_topk_softmaxdoes. - moe_
topk_ softmax_ bias - 2026-09-25: Softmax router with a correction bias and the zero-expert fold, one token. Logits
cover
num_logitsexperts, of which ids>= num_routedare identity experts: a selected one adds its weight tozero_accumand its slot becomes expert 0 with weight 0. - moe_
topk_ softmax_ bias_ batched - 2026-09-25:
moe_topk_softmax_biasforntokens, one block per token. - moe_
topk_ sqrtsoftplus - 2026-09-25: Sqrt-softplus router (
sqrt(log(1 + exp(logit)))), one token. As inmoe_topk_sigmoid, the bias steers selection only and the weights come from the pre-bias scores. - moe_
topk_ sqrtsoftplus_ batched - 2026-09-25: Same arguments as
moe_topk_sigmoid_batched, scoring experts withsqrt(log(1 + exp(logit))), the score of the single-tokenmoe_topk_sqrtsoftplus. - moe_
transpose_ u8_ batched - 2026-09-25: Per-expert uint8 transpose for the MoE down_proj relayout:
reads expert
e’s[rows, cols]matrix throughsrc_ptrs[e]and writes it as[cols, rows]throughdst_ptrs[e]. A NULL entry in either table skips that expert. - moe_
unpermute_ blend - 2026-09-28:
moe_unpermute_reduce_indexedthenmoe_batched_blendin one launch (kernelmoe_unpermute_blend,kernels/gb10/common/moe_unpermute_blend.cu), with the same output bits; one 256-thread block per token. Needshidden_size % 8 == 0. - moe_
unpermute_ reduce_ indexed - 2026-09-25: For each token,
output[t] = sum_k topk_weights[t, k] * expert_output[token_to_perm[t, k]], one block per token. - moe_
w4a4_ grouped_ gemm_ relu2 - 2026-09-25: Grouped W4A4 expert up GEMM on the FP4 block-scale MMA, with
relu^2 applied to the accumulator before the BF16 store. A is NVFP4 (packed
E2M1 + per-16 E4M3 scales) in token order, gathered through
sorted_token_ids; B is read from the per-expert NVFP4 pointer tables.blockIdx.zis the expert, andexpert_offsetsbounds its rows. The kernel ships only inkernels/gb10/nemotron-labs-3-puzzle-75b-a9b/nvfp4/moe_w4a4_grouped.cu. - moe_
w4a16_ fused_ gate_ up_ k64_ m128 - 2026-09-25:
moe_w4a16_fused_gate_up_k64_n128with a 128-row M tile and a 256-thread block.max_m_tiles_m128counts 128-row tiles: the call site halves the 64-row count (forward_prefill_routed.rs). - moe_
w4a16_ fused_ gate_ up_ k64_ n128 - 2026-09-25:
moe_w4a16_fused_gate_up_n128for the kernels with a 64-wide K step. - moe_
w4a16_ fused_ gate_ up_ n128 - 2026-09-25: Gate and up grouped GEMMs in one launch: the grid spans
2 * n_outcolumns, the firstn_outfor gate and the rest for up. - moe_
w4a16_ grouped_ gemm - 2026-09-25: Launcher for
moe_w4a16_grouped_gemm, whose weights are contiguous per expert rather than in pointer tables. No production code calls it (@human-review: its grid(num_experts, 1, 1)does not match the kernel, which takes the expert fromblockIdx.z). - moe_
w4a16_ grouped_ gemm_ ptrtable - 2026-09-29: Pointer-table grouped W4A16 GEMM, 128 threads; one launch covers all experts.
- moe_
w4a16_ grouped_ gemm_ ptrtable_ k64_ n128 - 2026-09-25: Same launch shape as
moe_w4a16_grouped_gemm_ptrtable_n128, for the kernels with a 64-wide K step. - moe_
w4a16_ grouped_ gemm_ ptrtable_ m256 - 2026-09-25:
moe_w4a16_grouped_gemm_ptrtablewith a 256-row M tile and a 512-thread block.max_m_tilescounts 256-row tiles:MoeLayer::launch_grouped_gemmdivides the 64-row count by 4. Loaded only underMETRALE_MOE_GROUPED_M256=1(moe/init.rs); the measurement behind that is onlaunch_grouped_gemm. - moe_
w4a16_ grouped_ gemm_ ptrtable_ n128 - 2026-09-29: Pointer-table grouped W4A16 GEMM, 128 threads. The name is historical: the grid follows the kernel’s published N tile, 64 or 128.
- moe_
w8a8_ gateup_ silu_ e4m3 - 2026-09-28:
moe_w8a8_gateup_silu_e4m3_w1/_w2: the gate and up grouped GEMMs of one work-list item (the_gushape,MOE_E4M3_GU) followed by SiLU(gate) * up quantized to E4M3 per 128-column group, bit-identical to the two_gulaunches plussilu_mul_quant_fp8. Writesout_fp8[total_expanded, n]andout_scale[total_expanded, n / 128]. The work-list is built withMOE_E4M3_GU’s shape. - moe_
w8a8_ grouped_ gemm - 2026-09-25: W8A8 grouped MoE GEMM on a dense grid
(ceil(N/64), max_m_tiles, num_experts).a_fp8comes fromper_token_group_quant_fp8;a_scale([total_tokens, K/128]FP32) and the per-blockb_scale(scale_ptrs[e]→[N/128, K/128]FP32) are applied in an FP32 epilogue per 128-element K-group.weight_ptrs[e]points at[N, K]FP8;outputis[total_expanded, N]BF16;sorted_token_idsis[total_expanded]or NULL. - moe_
w8a8_ grouped_ gemm_ e4m3 - 2026-09-27:
moe_w8a8_grouped_gemm_pm4on the native e4m3 tensor-core MMA (the_guor_dnentry, described bytile): same operands and output, bit-identical, over a work-list thatmoe_build_tile_worklistbuilt on the samestreamwithtile.m_tileandn / tile.n_tile.grid_ctas(clamped to1..=16384) CTAs stride over the items. - moe_
w8a8_ grouped_ gemm_ pm4 - 2026-09-25:
moe_w8a8_grouped_gemmover the work-list frommoe_build_tile_worklist(kernelmoe_w8a8_grouped_gemm_pm4, same module), which must run first on the samestream. The grid follows the rule ofmoe_fp8_grouped_gemm:max_tilesclamped to1..=16384. - moe_
weighted_ sum_ blend - 2026-09-25: The MoE combine for one token:
output[j] = sum_e weights[e] * expert_out[e, j] + sigmoid(dot(input, gate_weight)) * shared_out[j]. Every block computes the gate dot product itself. A nullgate_weightmeans an ungated shared expert, blended at weight 1. - moe_
weighted_ sum_ blend_ batch2 - 2026-09-25:
moe_weighted_sum_blendfor two tokens;blockIdx.yis the token. - moe_
weighted_ sum_ blend_ batch3 - 2026-09-25:
moe_weighted_sum_blendfor three tokens. - moe_
weighted_ sum_ blend_ fp8_ grouped - 2026-09-25: Grouped blend, one
blockIdx.yper token.expert_outrows are sorted positions;token_to_perm[token * top_k + k]maps a slot to its row.gate_weightmay be NULL (ungated shared expert). - moe_
weighted_ sum_ blend_ prefill - 2026-09-25: Per token
t:output[t] = sum_e expert_weights[t*top_k+e] * expert_out[t*top_k+e] + sigmoid(dot(input[t], gate_weight)) * shared_out[t].expert_outis[num_tokens * top_k, hidden]BF16,expert_weights[num_tokens * top_k]f32,input[num_tokens, k]BF16 andgate_weightthe shared-expert gate[1, k]BF16. - moe_
zero_ expert_ add - 2026-09-25:
out[t, :] += zero_accum[t] * x[t, :], the identity-expert blend. - n_
tile_ blocks - 2026-09-29:
ceil(n / t)blocks,tbeingkernel’s published N tile. An error when the kernel publishes none. - native_
q2_ mmq_ enabled - 2026-09-25: True only when
METRALE_GGUF_NATIVE_Q2_MMQis exactly1. With it, and with the kernels resolved and group 128 on gate, up and down, the dense FFN prefill runs packed Q2 weights throughq2_0_mmq_gemminstead of dequantizing them to BF16. Whether weights stay packed at all isMETRALE_GGUF_NATIVE_Q2’s decision. - nvfp4_
grouped_ tc_ shape_ ok - 2026-10-02: Whether the tensor-core kernels take an
n-column,k-deep projection:kin whole load groups of two 128-wide chunks,nin whole CTAs ofgeometry. - nvfp4_
lean_ repack_ shape_ ok - 2026-10-04:
nvfp4_tc_lean_repackadmits whole 16-row tiles, whole 128-K chunks, and a tile that fits the default 48 KiB of shared memory. - nvfp4_
mmq_ gemm - 2026-09-25:
C[m, n] = A[m, k] x W[n, k]in BF16, withoutweight_scale_2, on the 128-wide M tile.a_fp4isblock_fp4_mmq,w_nvfp4thenvfp4_mmq_repackoutput.kernel_wcis used whennis not a multiple of 128. - nvfp4_
mmq_ gemm_ tiled - 2026-09-25:
nvfp4_mmq_gemmwith the M tilemmq_xchosen by the caller. 2026-09-28: Without_scale, the pipelined 128-row tile applies it in its store and the call returnstrue; otherwise the caller still owesnvfp4_scale_bf16. The tile choice: the kernels must be that tile’s entries.nvfp4_mmq.cuinstantiates 16, 32, 64 and 128. A 128-wide tile issues MMAs for all 128 columns whatevermis, so a smallmwants a small tile.grid.y = ceil(m / mmq_x), and each M tile streams the whole weight again, sommust not exceedmmq_x(debug-asserted). - nvfp4_
mmq_ quantize_ act - 2026-09-25: Quantize BF16 activations
[m, k]toblock_fp4_mmqinout_y: E2M1 values with one UE4M3 scale per 16,kpadded to 256, one thread per 16-value group. - nvfp4_
mmq_ repack - 2026-09-25: Repack a checkpoint NVFP4 weight (E2M1
[n, k/2], low nibble = even k, and E4M3[n, k/16]scales) for the MMQ kernel. Each row holdsk/64blocks as all nibble bytes (32 per block) followed by all scale bytes (4 per block). Codes and scale bytes are copied, not requantized. - nvfp4_
mmq_ smem - 2026-09-25: Dynamic shared memory for M tile
mmq_x, in bytes:mmq_xids, a y tile ofmmq_x * 36ints padded to 256 ints, and an x tile of128 * 76ints. This ismmq_get_nbytes_sharedinq4k_vendor/mmq.cuhwithmmq_y = 128,MMQ_MMA_TILE_X_K_FP4 = 76and 8 warps of 32. - nvfp4_
mmq_ weight_ bytes - 2026-09-25: Bytes of the repacked form of an
[n, k]weight;kmust be a multiple of 64. - nvfp4_
pipe_ gemm - 2026-09-28:
C[m, n] = A[m, k] x W[n, k]in BF16, withoutweight_scale_2, throughmetrale_nvfp4_gemm_pipe(same operands and output asnvfp4_mmq_gemm, bit-identical).kmust be a multiple of 256. Grid of 128-channel x 192-token tiles, 256 threads. Without_scale, each output is multiplied by it asnvfp4_scale_bf16does in place, bit for bit. - nvfp4_
scale_ bf16 - 2026-09-25:
data[i] *= scalein place overtotalBF16 values; the caller passes the down projection’sweight_scale_2. - nvfp4_
silu_ mul_ quant - 2026-09-25:
silu(gate * gate_scale) * (up * up_scale)quantized straight toblock_fp4_mmqinout_yfor the down GEMM, without writing a BF16 intermediate.kis the intermediate width, padded to 256. The kernel applies no clamp. - nvfp4_
silu_ mul_ scaled - 2026-09-25:
out[i] = silu(gate[i] * gate_scale) * (up[i] * up_scale)overtotalBF16 values. The kernel applies no clamp. - nvfp4_
tc_ lean_ repack - 2026-09-27: Grouped NVFP4 down over the SiLU product.
kis the intermediate width; rows ofactandoutputare sorted positions, rows ofsh_actandsh_down_outtokens. 2026-10-04: Repacks one row-major NVFP4 matrix[n, k](packed E2M1[n, k / 2]atpacked, E4M3 block scales[n, k / 16]atscale) in place into the lean layout the_leantensor-core expert kernels read (nvfp4_tc_lean_repack, moe_nvfp4_grouped_tc.cu): same bytes and size, outputs byte-identical to the row-major point. Sets the device u32 atbad(zeroed by the caller) on a negative or NaN scale, after which the matrix is unusable. Needsnvfp4_lean_repack_shape_ok. - paged_
decode_ attn_ bf16 - 2026-09-25: Paged BF16-KV decode attention, one block per
(q_head, seq).sliding_window == 0attends to the whole sequence; otherwise only the lastsliding_windowpositions. - paged_
decode_ attn_ bf16_ gqa - 2026-09-25: GQA-packed BF16-KV paged decode, one block per
(kv_head, seq). Same arguments, argument order and block aspaged_decode_attn_bf16; only the grid’s x extent changes, tonum_kv_heads, because the kernel (kernels/gb10/common/paged_decode_attn_bf16_gqa.cu) keeps a KV head’s whole query group in registers. - paged_
decode_ attn_ bf16k_ turbo2v - 2026-09-25: Paged decode attention over the BF16-K / Turbo2V cache (kernel
paged_decode_attn_bf16k_turbo2v), with the same sparse-V skip as the Turbo3V kernel. - paged_
decode_ attn_ bf16k_ turbo3v - 2026-09-25: Paged decode attention over the BF16-K / Turbo3V cache (kernel
paged_decode_attn_bf16k_turbo3v). The kernel skips a position’s V load and dequant when its attention weight is at mostTQ_PLUS_SPARSE_V_THRESHOLD(1e-3 by default). - paged_
decode_ attn_ bf16k_ turbo4v - 2026-09-25: Paged decode attention over the BF16-K / Turbo4V cache (kernel
paged_decode_attn_bf16k_turbo4v), with the same sparse-V skip as the Turbo3V kernel. - paged_
decode_ attn_ fp8 - paged_
decode_ attn_ fp8_ gqa - 2026-09-25: GQA-packed FP8-KV paged decode, one block per
(kv_head, seq): the arguments and order ofpaged_decode_attn_fp8, grid x extentnum_kv_heads, and the preconditions ofpaged_decode_attn_bf16_gqa. - paged_
decode_ attn_ fp8k_ turbo2v - 2026-09-25: Paged decode attention over the FP8-K / Turbo2V cache (kernel
paged_decode_attn_fp8k_turbo2v). - paged_
decode_ attn_ fp8k_ turbo3v - 2026-09-25: Paged decode attention over the FP8-K / Turbo3V cache (kernel
paged_decode_attn_fp8k_turbo3v), one 256-thread block per (query head, sequence). The kernel skips a position’s V load and dequant when its attention weight is at mostTQ_PLUS_SPARSE_V_THRESHOLD. - paged_
decode_ attn_ fp8k_ turbo4v - 2026-09-25: Paged decode attention over the FP8-K / Turbo4V cache (kernel
paged_decode_attn_fp8k_turbo4v). - paged_
decode_ attn_ nvfp4 - 2026-09-25: Paged decode attention over an NVFP4 KV cache, one block per
(q_head, seq). - paged_
decode_ attn_ reduce_ fp8 - 2026-09-25: Combine split-K partials into the BF16 output. The workspace is F32
[head_dim values, m, l]per split whatever the cache type, so the BF16 split-K’s reduce handle is launched through this function too (qwen3_attention/decode/splitk_dispatch.rs). - paged_
decode_ attn_ reduce_ nvfp4 - 2026-09-25: Combine the split-K partials in
workspaceinto the BF16 output. - paged_
decode_ attn_ splitk_ bf16 - 2026-09-25: The BF16-KV counterpart of
paged_decode_attn_splitk_nvfp4(kernels/hopper/common/paged_decode_bf16_splitk_hopper.cu). It takes nocache_stride: the cache is[blocks, block_size, kv_heads, head_dim]and the kernel computes the page stride, aspaged_decode_attn_bf16does. - paged_
decode_ attn_ splitk_ fp8 - 2026-09-25: The FP8-KV counterpart of
paged_decode_attn_splitk_nvfp4. - paged_
decode_ attn_ splitk_ nvfp4 - 2026-09-25: Split-K paged decode attention over an NVFP4 KV cache: each
(q_head, seq)sequence is cut intonum_splitsparts, and each block writes its partial output and softmax state toworkspace. - paged_
decode_ attn_ turbo3k_ turbo8v - 2026-09-25: Paged decode attention over the Turbo3K / Turbo8V cache (kernel
paged_decode_attn_turbo3k_turbo8v). - paged_
decode_ attn_ turbo4k_ turbo3v - 2026-09-25: Paged decode attention over the Turbo4K / Turbo3V cache (kernel
paged_decode_attn_turbo4k_turbo3v). - paged_
decode_ attn_ turbo4k_ turbo8v - 2026-09-25: Paged decode attention over the Turbo4K / Turbo8V cache (kernel
paged_decode_attn_turbo4k_turbo8v). - parse_
cublas_ scope - 2026-09-25: Parse the
CublasScopegrammar. Returns the resolved set and the lowercased tokens that matched nothing. Pure: the environment read and the logging are inGemmDispatch::from_env. - per_
token_ group_ quant_ fp8 - 2026-09-25: Per-token FP8 activation quantization over 128-element
K-groups: A_fp8
[M, K]FP8 E4M3 and a_scale[M, K/128]FP32. - ple_
add_ highway - 2026-09-25:
highway += ple_out, in FP32. The reference model (bench/qwen4_exp/ref/modeling_qwen4_exp.py) adds PLE’s output to the hidden state before that layer’s attention hyper-connection. - ple_
conv - 2026-09-25: Depthwise causal conv with kernel
k_sizeand dilationdilation, thenout = gated + silu(conv). All buffers butweight(BF16) are FP32.stateis[(k_size - 1) * dilation, channels]and is rolled in place, so prefill and decode use the same launch. - ple_
gate - 2026-09-25: Gate the n-gram value by the highway, and write both the gated
value and its
norm_convoutput.hiddenis the FP32 highway[T, hc*H];keyandvalueare BF16 projection outputs. Both outputs are FP32, because the chain ends on the FP32 highway (the precision note inple.cu). One block per token. - predequant_
nvfp4_ to_ fp8 - 2026-09-25: Dequantize an NVFP4 weight to FP8 E4M3: reads
B_packed[N, K/2],B_scale[N, K/16]andscale2, writesB_fp8[N, K].QuantizedWeight::predequant_to_fp8calls it. - prefill_
attention - 2026-09-25: Flash-attention prefill on contiguous BF16 tensors: Q and O
[batch, seq_len, num_q_heads, head_dim], K and V[batch, seq_len, num_kv_heads, head_dim].sliding_window == 0disables the window; otherwise keys withq - k >= sliding_windoware masked. - prefill_
attention_ 64 - 2026-09-25:
prefill_attentionwith 64 query rows per block (32 on the SCALE and HIP targets). - prefill_
attention_ 512_ sink - 2026-09-25:
prefill_attentionfor the deepseek-v4-flashattn_prefill_512kernel (HDIM 512, 16 query rows per block) with a per-head sink logit:sinksis FP32[num_q_heads], added to the softmax denominator only.DevicePtr::NULLmeans no sink. - prefill_
attention_ fp8kv - 2026-09-25: Contiguous prefill with BF16 Q and FP8 E4M3 K and V, which the kernel dequantizes to BF16 in shared memory; 64 query rows per block.
- prefill_
attention_ paged - 2026-09-25: Causal flash-attention prefill of a contiguous Q chunk against
K and V in the paged BF16 cache, found through
block_table. Query rowiis at absolute positionq_offset + i; 32 query rows per block. - prefill_
attention_ paged_ 64 - 2026-09-25:
prefill_attention_pagedwith 64 query rows per block (32 on the SCALE and HIP targets). - prefill_
attention_ paged_ 512 - 2026-09-25: Causal paged prefill for
head_dim == 512over a BF16 KV cache: 32 query rows and 8 warps per block, with the 101,120 bytes of dynamic shared memoryattn_prefill_paged_512.curequires. - prefill_
attention_ paged_ batched - 2026-09-25: Batched BF16-KV paged prefill attention, 32 query rows per block.
- prefill_
attention_ paged_ batched_ 64 - 2026-09-25: Batched BF16-KV paged prefill attention, 64 query rows per block.
- prefill_
attention_ paged_ bf16k_ turbo2v_ 64 - 2026-09-25: BF16 K with 2-bit V; the arguments of
prefill_attention_paged_bf16k_turbo3v_64. - prefill_
attention_ paged_ bf16k_ turbo3v_ 64 - 2026-09-25: BF16 K (
[block_size, num_kv_heads, head_dim]per block) with 3-bit V. - prefill_
attention_ paged_ bf16k_ turbo4v_ 64 - 2026-09-25: BF16 K with 4-bit V; the arguments of
prefill_attention_paged_bf16k_turbo3v_64. - prefill_
attention_ paged_ dflash - 2026-09-25:
prefill_attention_pagedlaunched withcausal_mask_enabled = 0, the BF16-cache counterpart ofprefill_attention_paged_fp8_dflash. - prefill_
attention_ paged_ dflash_ bf16_ indirect - 2026-09-25:
prefill_attention_paged_dflashwithkv_len,q_offsetandq_rope_posread on the device fromkv_len_q_offset_dev(three u32 at byte offsets 0, 4 and 8) instead of passed as scalars, so a captured CUDA graph can replay the launch with values the host writes before each replay.q_offsetaddresses the cache;q_rope_posis the absolute query position the causal and sliding-window masks compare against. The kernel applies no RoPE. Kernel:attn_prefill_paged_indirect. - prefill_
attention_ paged_ fp8 - 2026-09-25:
prefill_attention_pagedover an FP8 KV cache. - prefill_
attention_ paged_ fp8_ 64 - 2026-09-25:
prefill_attention_paged_fp8with 64 query rows per block (32 on the SCALE and HIP targets). - prefill_
attention_ paged_ fp8_ batched - 2026-09-25: Batched FP8-KV paged prefill attention, 32 query rows per block.
- prefill_
attention_ paged_ fp8_ batched_ 64 - 2026-09-25: Batched FP8-KV paged prefill attention, 64 query rows per block.
- prefill_
attention_ paged_ fp8_ dflash - 2026-09-25:
prefill_attention_paged_fp8launched withcausal_mask_enabled = 0: the causal mask is skipped, so a query of the DFlash draft block also attends to the block’s later positions. - prefill_
attention_ paged_ fp8k_ turbo2v_ 64 - 2026-09-25: FP8 K with 2-bit V.
- prefill_
attention_ paged_ fp8k_ turbo3v_ 64 - 2026-09-25: FP8 K with 3-bit V.
- prefill_
attention_ paged_ fp8k_ turbo4v_ 64 - 2026-09-25: FP8 K with 4-bit V.
- prefill_
attention_ paged_ nvfp4 - 2026-09-25: Causal paged prefill over an NVFP4 KV cache, 32 query rows per block.
- prefill_
attention_ paged_ nvfp4_ 64 - 2026-09-25:
prefill_attention_paged_nvfp4with 64 query rows per block (32 on the SCALE and HIP targets). - prefill_
attention_ paged_ nvfp4_ batched - 2026-09-25: Batched NVFP4-KV paged prefill attention, 32 query rows per block.
- prefill_
attention_ paged_ nvfp4_ batched_ 64 - 2026-09-25: Batched NVFP4-KV paged prefill attention, 64 query rows per block,
with the arguments of
prefill_attention_paged_nvfp4_batched. The caller (qwen3_attention/prefill/paged_attn_batched.rs) picks the 64-row kernels for every KV type whenchunk_len >= 256. - prefill_
attention_ paged_ turbo2_ 64 - 2026-09-25: The turbo2 counterpart of
prefill_attention_paged_turbo_64. - prefill_
attention_ paged_ turbo3k_ turbo8v_ 64 - 2026-09-25: 3-bit K with FP8 V.
- prefill_
attention_ paged_ turbo4k_ turbo3v_ 64 - 2026-09-25: 4-bit K with 3-bit V.
- prefill_
attention_ paged_ turbo4k_ turbo8v_ 64 - 2026-09-25: 4-bit K with FP8 V.
- prefill_
attention_ paged_ turbo_ 64 - 2026-09-25: Causal paged prefill over a TurboQuant KV cache (same format for K
and V), 64 query rows per block (32 on the SCALE and HIP targets). The
turbo8, turbo4 and turbo3
_64entries share this argument list; the caller picks one throughkerneland passes that cache’s block stride and data-section size. - prefill_
batched_ chunk_ zero_ admitted - 2026-09-28: Whether a batched prefill wave may carry chunk-zero streams: the
first-chunk lever (
prefill_batched_first_chunk_enabled) or varlen batching (prefill_varlen_enabled). The single rule for the model engine’s admission (kernel_batched_eligible), its paged metadata upload, and the attention layer’s routing; before 2026-09-28 the layer read the lever alone and refused a varlen-admitted chunk-zero wave after admission, which failed every stream in it. - prefill_
batched_ first_ chunk_ enabled - 2026-09-25: Whether chunk-zero streams may use the paged batched-prefill
path: codispatch on, or
METRALE_Q12_BATCHED_FIRST_CHUNKset to1ortrue. The scheduler reads codispatch alone. - prefill_
codispatch_ enabled - 2026-09-25: Whether cross-request co-dispatch of fresh prompts is on:
--prefill-codispatch, elseMETRALE_PREFILL_CODISPATCH(1ortrue, any case); off when neither is set. The scheduler’s levers andprefill_batched_first_chunk_enabledboth read it. - prefill_
varlen_ enabled - 2026-09-25: Whether varlen (ragged) batched prefill is on:
--prefill-varlen-batch, elseMETRALE_PREFILL_VARLEN(1ortrue, any case); off when neither is set. The admission predicate (check_kernel_batched_eligible), the batched attention layer and the scheduler’s levers all read this one value. - q2_
0_ gemv - 2026-09-25: Q2_0 GEMV for M=1 decode:
C[1,N] = A[1,K] @ dequant(B)^T.AandCare BF16;Bis the rawblock_q2_0buffer, and each weight is dequantized as(code-1)*dinside the dot product. - q2_
0_ gemv_ batchm - 2026-09-25: Batched Q2_0 GEMV:
C[M,N] = A[M,K] @ dequant(B)^T,AandCrow-major BF16. Each weight block is read once and applied to allmrows. - q2_
0_ gemv_ vec - 2026-09-25: Q2_0 GEMV for M=1 decode:
C[1,N] = A[1,K] @ dequant(B)^T. Each lane reads oneuint32of 16 codes, and the CTA stages the activation tile in shared memory.AandCare BF16;Bis the rawblock_q2_0buffer; each weight is(code-1)*d. - q2_
0_ gemv_ vec_ batchm - 2026-09-25: Batched Q2_0 GEMV for any
m:C[M,N] = A[M,K] @ dequant(B)^T,AandCrow-major BF16. Each weight word is read once per launch and applied to every staged row. - q2_
0_ mmq_ gemm - 2026-09-25:
C[m, n] = A[m, k] x W[n, k]in BF16.a_q8is the DS4 q8_1 activation fromsuper::quantize_act_q8_1;w_q2_0is the packed weight as loaded. The tile is 128 x 128 like the Q4_K GEMM, and Q2_0’s x tile row (MMQ_MMA_TILE_X_K_Q8_0) is the same 76 ints as Q4_K’s, so it reusesQ4K_MMQ_SMEM.kernel_wcis used whennis not a multiple of 128. - q2_
0_ mmq_ gemm_ packed - 2026-09-25:
q2_0_mmq_gemmon aPackedQ2Weight. Returns an error unlessw.group == 128, the group size ofblock_q2_0. - q2_
0_ weight_ bytes - 2026-09-25: Bytes of the packed
block_q2_0form of an[n, k]weight;kmust be a multiple of 128. - q4k_
mmq_ gemm - 2026-09-25:
C[m, n] = A[m, k] x W[n, k]in BF16, witha_q8in q8_1 andw_q4kinblock_q4_K, on a 128 x 128 tile.kernel_wcis used whennis not a multiple of 128. - q4k_
weight_ bytes - 2026-09-25: Bytes of the Q4_K form of an
[nrows, n_per_row]weight;n_per_rowmust be a multiple of 256. - q8_
1_ scratch_ bytes - 2026-09-25: q8_1 activation scratch bytes for
[m, k]: 4 bytes per value withkrounded up to 256, plus 1 MiB.ffn_act_q8ingpu-runtime/src/buffers/sizes.rsuses the same expression withkthe larger of the hidden and intermediate sizes. - qsa_
block_ pool - 2026-09-25: Pool
n_newnewly complete blocks starting atfirst_block: the mean ofratioraw keys, then RMSNorm scaled by1 + w, then rope at the block’s first token position. Returns without launching whenn_new == 0. - qsa_
gather - 2026-09-25: Copy the selected tokens’ K/V rows into contiguous NHD scratch:
slot
iholds positionsel[i]. - qsa_
prefill_ attn - 2026-09-25: Per (row, q head), attention over exactly the selected blocks in
listsplus the incomplete tail, read from the paged cache; the result overwrites that row’s context inattn_out. - qsa_
qprep - 2026-09-25: One decode query: per head, RMSNorm scaled by
1 + w, then partial rope atpos; FP32 output. - qsa_
qprep_ rows - 2026-09-25:
qsa_qprepforrowsprefill rows at positionsfirst_pos + row, reading q from rows of the indexer projectionqk. - qsa_
score - 2026-09-25:
scores[b] = sum_h relu(q_h . k_b) / sqrt(hd)forn_blocksblocks. - qsa_
score_ rows - 2026-09-25: Per-row block scores for prefill rows; blocks at or past a row’s
complete-block count score
-inf. - qsa_
score_ rows_ tc - 2026-09-25: Tensor-core
qsa_score_rows: one block of 8 warps covers 16 rows by 64 blocks instead of one block per (row, block). q is split into BF16 high and low halves for the MMA, so the scores are not bit-identical toqsa_score_rows; they feed a top-k. - quant_
gemm - 2026-09-25: GEMM (
mrows) through the kernel for the weight’s format: NVFP4, FP8 or dense BF16.PackedQ2weights return an error. - quant_
gemv - 2026-09-25: GEMV through the kernel for the weight’s format: NVFP4, FP8 or
dense BF16.
PackedQ2weights return an error. - quantize_
act_ q8_ 1 - 2026-09-25: Quantize BF16 activations
[m, k]to q8_1 inout_q8, withkpadded to 256. The scale layout (DS4, D4 or D2S6) is the kernel’s. - quantize_
bf16_ to_ fp8 - 2026-09-25: Quantize a BF16 weight
[N, K]to FP8 E4M3[N, K]with one f32 scale per row[N], one CTA per row (kernelquantize_bf16_to_fp8inkernels/gb10/common/dense_gemv_fp8w.cu).DenseWeight::quantize_to_fp8calls it; the resultingFp8DenseWeightfeeds the row-scaled FP8 kernels such asfp8_gemm_n128_row_scaled. - quantize_
bf16_ to_ nvfp4 - 2026-09-25: Quantize a BF16
[M, K]matrix to NVFP4 withscale2 = 1.0: packed E2M1[M, K/2]and one E4M3 scale per 16 elements[M, K/16]. One block per row; the kernel’sNparameter is the row count. Produces the W4A4 prefill activations. - quantize_
weight_ q4k - 2026-09-25: Quantize BF16 weights
[nrows, n_per_row]toblock_q4_K, one thread per 256-value block. - read_
expert_ ptrs_ u64 - 2026-09-25: One blocking device-to-host copy of an
[n]u64 pointer table. - read_
expert_ scales_ f32 - 2026-09-25: One blocking device-to-host copy of an
[n]f32 scale table. - requant_
w_ nvfp4_ int8 - 2026-09-25: Requantize an NVFP4 weight (packed E2M1, per-16 E4M3 block
scales, per-tensor
scale2) to int8 with one F32 scale per 32 elements, forint8_gemm_faith2. ReadsW_packed[N, K/2]andW_e4m3[N, K/16]; writesW_i8[N, K](signed int8) andW_scale[N, K/32](F32). The dense FFN’sensure_int8_weightruns it on a weight’s first int8 prefill and keeps the result. - reshape_
and_ cache - 2026-09-25: Copy BF16 K and V rows into the paged BF16 cache at
slot_mapping(kernelreshape_and_cache_flash), one block per token.key_stride/value_strideare the row strides in elements._cache_strideis not passed to the kernel, which derives the block stride fromblock_size. - reshape_
and_ cache_ bf16k_ turbo2v - 2026-09-25: Write K and V to the BF16-K / Turbo2V cache (kernel
reshape_and_cache_flash_bf16k_turbo2v): K as raw BF16, V as 2-bit Lloyd-Max codes plus one FP8 scale per 16 elements, 2.5 bits per V element. - reshape_
and_ cache_ bf16k_ turbo3v - 2026-09-25: Write K and V to the BF16-K / Turbo3V cache (kernel
reshape_and_cache_flash_bf16k_turbo3v): K as raw BF16, V as 3-bit Lloyd-Max codes (3/8 byte per element) plus one FP8 scale per 16 elements.v_data_section_bytesis the size of a V block’s code section, after which its scales start. - reshape_
and_ cache_ bf16k_ turbo4v - 2026-09-25: Write K and V to the BF16-K / Turbo4V cache (kernel
reshape_and_cache_flash_bf16k_turbo4v): K as raw BF16, V as 4-bit Lloyd-Max codes plus one FP8 scale per 16 elements. - reshape_
and_ cache_ flash_ v_ only - 2026-09-25: Copy only V into the paged BF16 cache (kernel
reshape_and_cache_flash_v_only), for callers whose K is written by afused_k_norm_rope_cache_write_*launch; areshape_and_cachethere would overwrite that K. - reshape_
and_ cache_ fp8 - 2026-09-25: Quantize BF16 K and V rows into the paged FP8 cache (kernel
reshape_and_cache_flash_fp8):fp8 = sat(bf16 / scale)with the dequant scalesk_scale/v_scale.k_cache/v_cacheare the pool base pointers, andcache_strideis the stride between cache blocks in elements (normallyblock_size * num_kv_heads * head_dim). - reshape_
and_ cache_ fp8k_ turbo2v - 2026-09-25: Write K and V to the FP8-K / Turbo2V cache (kernel
reshape_and_cache_flash_fp8k_turbo2v). - reshape_
and_ cache_ fp8k_ turbo3v - 2026-09-25: Write K and V to the FP8-K / Turbo3V cache (kernel
reshape_and_cache_flash_fp8k_turbo3v): K as FP8 E4M3, V as 3-bit Lloyd-Max codes plus one FP8 scale per 16 elements. One 256-thread block per token. - reshape_
and_ cache_ fp8k_ turbo4v - 2026-09-25: Write K and V to the FP8-K / Turbo4V cache (kernel
reshape_and_cache_flash_fp8k_turbo4v). - reshape_
and_ cache_ nvfp4 - 2026-09-25: Write each token’s K and V into the paged NVFP4 cache at its
slot_mappingslot: E2M1 values with one E4M3 scale per 16. One block per token. - reshape_
and_ cache_ turbo3k_ turbo8v - 2026-09-25: Write K and V to the Turbo3K / Turbo8V cache (kernel
reshape_and_cache_flash_turbo3k_turbo8v). - reshape_
and_ cache_ turbo4k_ turbo3v - 2026-09-25: Write K and V to the Turbo4K / Turbo3V cache (kernel
reshape_and_cache_flash_turbo4k_turbo3v). - reshape_
and_ cache_ turbo4k_ turbo8v - 2026-09-25: Write K and V to the Turbo4K / Turbo8V cache (kernel
reshape_and_cache_flash_turbo4k_turbo8v). - residual_
add - 2026-09-25: In-place BF16
residual[i] += src[i](kernelbf16_residual_add). - residual_
add_ rms_ norm - 2026-09-25:
hidden += src, thenoutput = rms_norm(hidden)andresidual = hidden, in one kernel, one block per token row. - residual_
add_ rms_ norm_ exact - 2026-09-28:
residual_add_rms_norm_exact(residual_add_rms_norm_exact.cu): the arguments and launch ofresidual_add_rms_norm, with the bytes ofbf16_residual_addfollowed byrms_norm_residual: the sum of squares reads the BF16-rounded sums. The circuit executor launches it across a layer boundary, with the next layer’s input-norm weight. - residual_
add_ rms_ norm_ gatef32 - 2026-09-25:
residual_add_rms_normthat also writes the normed row in FP32 tooutput_f32, the MoE router input, so routing does not see the BF16 rounding of the norm output. Callers use it whenMETRALE_FP32_ROUTINGis active for the layer’s FFN. - rms_
norm - 2026-09-25: RMS norm of
num_tokenspacked rows ofhidden_size, one block per row. Howweightscales the result is the kernel’s:rms_norminkernels/gb10/common/rms_norm.cumultiplies by1 + weight, and therms_norm_vanillakernels byweight. - rms_
norm_ residual - 2026-09-25:
output = rms_norm(input)andresidual = inputin one pass, one block per token row. - rms_
norm_ short_ row_ eligible - 2026-09-25: Gate for
rms_norm_warp_row:hidden_size <= 256and even, andnum_rows >= 1024.METRALE_RMS_NORM_WARP_ROW=0turns it off; the variable is read once per process. - rms_
norm_ strided - 2026-09-25: RMS norm of
num_groupsgroups ofrows_per_grouprows in one launch. Groups startrow_strideelements apart, and rows inside a group are packed athidden_size. The multi-sequence q/k head norms use it because each sequence’s heads sit inside that sequence’s own interleaved block. - rms_
norm_ warp_ row - 2026-09-25: RMS norm with one warp per row and 8 rows per block, so the
reduction needs no shared memory or block barrier. The prefill per-head
q_norm/k_normuses it whenrms_norm_short_row_eligibleholds (qwen3_attention/prefill/cache_skip.rs). - rope
- 2026-09-25: Apply rotary position embeddings to Q and K in place, rows packed
(
num_q_heads * head_dimandnum_kv_heads * head_dimelements apart).positionsis a deviceu32[seq_len]. - rope_
mrope_ interleaved - 2026-09-25: Interleaved multimodal RoPE (MRoPE) with three position streams
(
pos_t,pos_h,pos_w); rotary pairitakes its position from streami % 3. With the same pointer for all three, the math is that ofrope. - rope_
mrope_ interleaved_ k_ only - 2026-09-25:
rope_mrope_interleavedfor K only, for when Q was already rotated by a fused prefill kernel. - rope_
proportional - 2026-09-25: Proportional RoPE (Gemma-4 full-attention layers).
- rope_
strided - 2026-09-25:
ropefor rows that are not packed: Q rowsq_row_strideand K rowsk_row_strideelements apart, allnum_tokensrows in one launch.rope_forward_strideddiffers fromrope_forwardonly in the row address, so the packed strides give the same result asrope. - rope_
yarn - 2026-09-25: RoPE with frequencies from a precomputed
inv_freqtable ([rotary_dim/2]FP32);rope_forward_yarnignorestheta. - rope_
yarn_ scaled - 2026-09-25: RoPE from an
inv_freqtable with cosine and sine scaled byattention_factor. - scaled_
add - 2026-09-25: In-place BF16
output[i] += scale * src[i](kernelbf16_scaled_add). - set_
prefill_ codispatch_ from_ cli - 2026-09-25: Publish the command line’s
--prefill-codispatchdecision. Returns the value in force, which differs fromenabledwhen the cell was already resolved; the command line then did not take effect. The serve calls this only when the flag is given, so without it theMETRALE_PREFILL_CODISPATCHfallback applies. - set_
prefill_ varlen_ from_ cli - 2026-09-25: Publish the command line’s
--prefill-varlen-batchdecision. Returns the value in force, which differs fromenabledwhen the cell was already resolved; the command line then did not take effect. The serve calls this only when the flag is given, so without it theMETRALE_PREFILL_VARLENfallback applies. - sigmoid_
blend - 2026-09-25: In-place BF16
output[i] += sigmoid_gate * src[i], wheresigmoid_gateis a host value the caller has already passed through the sigmoid. The arguments are those of kernelbf16_sigmoid_blend; nothing in the tree calls this function. - sigmoid_
blend_ device - 2026-09-25:
output[i] += sigmoid(*gate_ptr) * src[i], wheregate_ptris one BF16 scalar in device memory (bf16_sigmoid_blend_deviceinkernels/gb10/common/residual_add.cu). - sigmoid_
gate_ mul - 2026-09-25:
output[i] = input[i] * sigmoid(gate[i])(kernelsigmoid_gate_mul). - sigmoid_
gate_ mul_ batched - 2026-09-25:
sigmoid_gate_mulovernum_tokensrows in one launch:output[t, d] = input[t, d] * sigmoid(gate[t * gate_stride + d]).inputandoutputare contiguous[num_tokens, dim]. - sigmoid_
gate_ mul_ head_ broadcast - 2026-09-25:
output[t, h, d] = input[t, h, d] * sigmoid(gate[t, h]): one BF16 gate value per head,[num_tokens, nq], broadcast over the head’shdelements (kernelsigmoid_gate_mul_head_broadcast). - silu_
mul - 2026-09-25:
output = act(gate) * upovernum_elementsBF16 values, wherekernelfixes the activation: callers passmoe_silu_mul(SiLU) or, for a GeLU FFN,gelu_mul. Themoe_silu_mul.cucopies ingb10/deepseek-v4-flash(also compiled forlongcat-flash-lite) andgb10/step3p7-flashfirst clampgateto at most 10 andupto [-10, 10]. - silu_
mul_ quant_ fp8 - 2026-09-25:
SiLU(gate) * upquantized to FP8 E4M3 with one scale per 128-element group of each row, in one kernel (silu_mul_quant_fp8); the FP8 MoE prefill uses it before the down projection (moe/forward_prefill_fp8.rs). - silu_
mul_ strided - 2026-09-25:
SiLU(gate) * upover row-strided BF16 operands (kernelsilu_mul_strided): rowrreadsgateandupatr * in_stride + cforc < colsand writesoutputatr * out_stride + c. The fused dense-FFN gate+up projection (layers/dense_ffn_gateup_fused.rs) passes the two column halves of one[rows, 2 * cols]matrix (up = gate.offset(cols * 2)) and a contiguous output. One grid row per matrix row. - softplus_
gate_ mul_ head_ broadcast - 2026-09-25: Like
sigmoid_gate_mul_head_broadcastwith softplus in place of sigmoid (kernelsoftplus_gate_mul_head_broadcast). - ssd_
scan_ fits - 2026-09-25: Whether the SSD chunked scan fits in shared memory for this
state_size. - ssd_
scan_ smem - 2026-09-25: Dynamic shared memory
mamba2_ssd_scanrequests for a given SSM state size. It grows linearly instate_size, so a large SSM state can exceedMAX_DYNAMIC_SMEM. The launch calls this function, so the two cannot drift. - ssm_
ba_ gates_ hopper_ enabled - 2026-09-25: The lever: the target’s
[defaults] ssm_ba_gates_hopper, whichMETRALE_SSM_BA_GATES_HOPPERoverrides (0,false,offornoturn it off, any other value on;super::target_defaults). There is noMETRALE_NO_*spelling for it. - ssm_
ba_ gates_ hopper_ reject - 2026-09-25: Why the twin does not run, as one of
BA_GATES_REJECTS;Nonemeans it runs. Pure, so tests cover it without a GPU. The shape guards: - ssm_
h_ state_ f16_ to_ f32 - 2026-09-25: FP16 -> FP32 widening of
nh-state elements (ssm_h_state_f16_to_f32). Grid-stride;srcanddstmust not alias. - ssm_
h_ state_ f32_ to_ f16 - 2026-09-25: FP32 -> FP16 conversion of
nh-state elements (ssm_h_state_f32_to_f16, round-to-nearest-even). The kernel is grid-stride, so the clamped grid still covers every element.srcanddstmust not alias: an in-place narrowing conversion is a data race. - strided_
out_ extent_ elems - 2026-09-25: Elements from the start of the output to one past the last
element a cuBLASLt GEMM writes when its
m_padoutput rows ofnelements areldcelements apart:(m_pad - 1) * ldc + n. Pass the padded row count, because the pad rows are written too. The strided call sites bound their buffers with it. - transpose_
block_ scale - 2026-09-25: Transpose FP32 block scales:
[N/128, K/128]to[K/128, N/128]. - transpose_
fp8 - 2026-09-25: Transpose an FP8 weight on the GPU:
B[N, K]toB_t[K, N]. - transpose_
u8 - 2026-09-25: Single-matrix uint8 transpose
[rows, cols] -> [cols, rows]on the GPU (transpose_u8.cu, 32x32 shared-memory tiles). The quantized weight transposes inweight_map/quantized/transpose.rscall it. - use_
gemv_ sw - 2026-09-25: Use the single-warp kernel only when the lever is on and its handle resolved
(a missing kernel is
KernelHandle(0)). - w4a4_
gemm - 2026-09-25: W4A4 GEMM on FP4 tensor cores (kernel
w4a4_gemm). The activation comes fromquantize_bf16_to_nvfp4and is launched withscaleA2 = 1.0; the weight is an NVFP4QuantizedWeight; the output is BF16[M, N]. - w4a4_
gemm_ mfast - 2026-09-25:
w4a4_gemmthrough thew4a4_gemm_mfastkernel, with M on the fast grid axis (blockIdx.x= M block), so consecutive CTAs share a B panel. - w4a16_
decode_ gemv - 2026-09-25: Decode GEMV: the single-warp kernel when
use_gemv_swallows it, otherwise the basew4a16_gemv, each with its own grid. - w4a16_
gemm - 2026-09-29: W4A16 GEMM,
C = A @ dequant(B): A[M, K]BF16, B NVFP4 (packed E2M1, FP8 block scales, FP32 per-tensor scale), C[M, N]BF16. Every launcher here sizes grid.x from the kernel’s published N tile (n_tile_blocks). - w4a16_
gemm_ n128 - 2026-09-29: W4A16 GEMM over a packed transposed B, N tiled by the kernel’s published
tile: it launches through
w4a16_gemm_n128_ldbwithldb = n. - w4a16_
gemm_ n128_ ldb - 2026-09-25:
w4a16_gemm_n128with an explicit row strideldbfor the transposed B, so rowrstarts atr * ldb. - w4a16_
gemm_ n128_ m128 - 2026-09-25: W4A16 GEMM with a 128-row CTA (two 64-row chunks): each CTA loads a B tile once for both chunks.
- w4a16_
gemm_ n128_ m128_ bf16 - 2026-09-25: W4A16 GEMM launching
w4a16_gemm_t_m128_bf16, which runs BF16 m16n8k16 MMAs, on the grid, block and transposed NVFP4 weight layout ofw4a16_gemm_n128_m128. It passes 8 arguments, so it fits only the 8-parameter v1 kernel;w4a16_gemm_t_m128_bf16_v2takes a 9th (ldb) and goes throughw4a16_gemm_n128_m128_bf16_ldb(ldb = Nfor an unpadded twin). - w4a16_
gemm_ n128_ m128_ bf16_ ldb - 2026-09-25:
w4a16_gemm_n128_m128_bf16with an explicit transposed-B row stride, for the same reason asw4a16_gemm_n128_ldb. This is the launcher for the 9-parameterw4a16_gemm_t_m128_bf16_v2. - w4a16_
gemm_ n128_ m128_ v2 - 2026-09-25: W4A16 GEMM v2 (
w4a16_gemm_t_m128_v2, in the minimax-m2-229b and qwen3.6-27b kernel dirs): the CTA tile ofw4a16_gemm_n128_m128(M=128, N=128, K step 32) on 256 threads instead of 128. Warps 0-3 compute the first 64 rows and warps 4-7 the second, so the two chunks’ MMAs run in parallel. - w4a16_
gemm_ n128_ m128_ v3 - 2026-09-25: W4A16 GEMM v3 (
w4a16_gemm_t_m128_v3, only inkernels/gb10/minimax-m2-229b/nvfp4/w4a16_gemm_v3.cu): a 128x128 CTA tile on 256 threads with a K step of 64. - w4a16_
gemv - 2026-09-25:
C[1, N] = A[1, K] @ dequant(B)with BF16 A and C and an NVFP4 weight. - w4a16_
gemv_ batch2 - 2026-09-25:
w4a16_gemvfor 2 contiguous rows in one pass over the weight.gemv_tc::tc_fixed_mtakes the launch to the tensor-core kernel when it routes it (METRALE_W4A16_TC_WIDE); otherwisekernelruns. - w4a16_
gemv_ batch3 - 2026-09-25:
w4a16_gemv_batch2for 3 rows. - w4a16_
gemv_ batchm - 2026-09-25:
w4a16_gemvformcontiguous rows in one pass over the weight.kernelis the CUDA-corew4a16_gemv_batch{M}tier the caller picked (W4a16BatchmTiers::kernel);gemv_tc::tc_kernelreplaces it with the tensor-corew4a16_gemv_tc8/tc16when it routes the shape. - w4a16_
gemv_ dual - 2026-09-25: Two W4A16 GEMVs over the same BF16 input in one launch;
blockIdx.zpicksweight1orweight2. Both projections havenoutputs. - w4a16_
gemv_ dual_ batch2 - 2026-09-25:
w4a16_gemv_dual_batch3for 2 rows. - w4a16_
gemv_ dual_ batch3 - 2026-09-25: Two NVFP4 GEMVs over the same 3-row input
[3, K];blockIdx.zpicksweight0orweight1, and each writes[3, N]. - w4a16_
gemv_ dual_ sw - 2026-09-25: One warp per output variant of
w4a16_gemv_dual, 8 outputs per block. It shares the per-lane partialw4a16_dual_partialwith the base kernel (w4a16_gemv_fused.cu). Callers pick it throughuse_gemv_swwithModelLevers::gemv_sw, which is on unlessMETRALE_NO_GEMV_SW=1. - w4a16_
gemv_ grid_ x - w4a16_
gemv_ qg - 2026-09-25:
w4a16_gemvover a weight whose rows interleave Q and Gate per head; the output is stored deinterleaved,[Q of all heads | Gate of all heads], withn = num_heads * head_dim * 2. - w4a16_
gemv_ qg_ batch2 - 2026-09-25:
w4a16_gemv_qgfor 2 rows: A is[2, K], C is[2, N], each row deinterleaved. - w4a16_
gemv_ qg_ batch3 - 2026-09-25:
w4a16_gemv_qgfor 3 rows: A is[3, K], C is[3, N], each row deinterleaved. - w4a16_
gemv_ qkvz - 2026-09-25:
w4a16_gemvover a weight whose rows interleave Q, K, V and Z per group; the output is stored deinterleaved as[Q | K | V | Z]. - w4a16_
gemv_ silu_ input - 2026-09-25: W4A16 GEMV whose activation is
silu(gate_out) * up_out, computed per element from the two[k]BF16 vectors inside the kernel. - w4a16_
gemv_ silu_ input_ sw - 2026-09-25: One warp per output variant of
w4a16_gemv_silu_input, 8 outputs per block, picked the same way asw4a16_gemv_dual_sw. - w4a16_
gemv_ sw - 2026-09-25: Single-warp-per-output W4A16 GEMV for M=1, grid
ceil(N/8). - w4a16_
gemv_ sw_ grid_ x - w4a16_
gemv_ sw_ raw - 2026-09-25: The launch of
w4a16_gemv_swfor callers that hold the NVFP4 packed weight, scale and global scale as separate values rather than aQuantizedWeight(the GLM-5.3 MLP inmodel-arch/src/glm5next_mlp/forward.rs). It keeps the grid onw4a16_gemv_sw_grid_x. - w4a16_
t_ via_ fp8_ ldmab - 2026-09-28:
w4a16_gemm_t_m128’s product on the multistage FP8 GEMM: the transposed NVFP4 weight ([K/2, N]codes,[K/16, N]E4M3 scales, scalarweight_scale_2) is dequantized to E4M3[N, K]with that kernel’s arithmetic (fp8_predequant_nvfp4_t), thenfp8_act_ldmab_gemmruns. Bit-identical tow4a16_gemm_t_m128(kbenchw4a16_bench.cu, nine shapes).kmust be a multiple of 32. - w4a16_
tc_ rows - 2026-10-02:
output [m, ldc] = input [m, lda] x W^Tfor the row-major NVFP4weight[n, k](packed E2M1, E4M3 scales of 16,weight_scale_2). Refuses a shapew4a16_tc_rows_shape_okrefuses. - w4a16_
tc_ rows_ shape_ ok - 2026-10-02: The kernel’s shape contract, without a GPU: 1..=64 rows, any positive N (the entry points are ragged: a partial last CTA loads zero weight rows and stores nothing past N), K a positive multiple of 256 (whole load groups of every entry point), and an A pitch that keeps rows 16-byte aligned and covers K; the C pitch covers N.
- w8a8_
act_ quant - 2026-09-28: Quantize
rowsrows of the BF16 activationx([rows, ldx], the firstkcolumns) intoscratchforscale’s layout. - w8a8_
act_ quant_ silu - 2026-09-28:
w8a8_act_quantofbf16(silu(gate) * up), computed in the same launch with the arithmetic ofmoe_silu_mul: gate and up are[rows, ld]BF16, the firstkcolumns read. - w8a8_
decode_ available - 2026-09-28: The “W8A8 available for this layer and shape” hook: the kernels
of
w’s layout resolved,rowsis in1..=W8A8_MAX_ROWS, and the scratch holds the quantized activation. The declared-precision policy decides whether W8A8 is wanted; this says whether it can run. - w8a8_
decode_ proj_ disabled - 2026-09-25: Kill switch:
METRALE_NO_W8A8_DECODE_PROJset to any value, empty and0included, turns this route off. Read once, so it is constant for the process and safe to branch on under CUDA-graph capture. - w8a8_
gemv - 2026-09-28: The GEMV over the activation
w8a8_act_quantleft inscratch:out[m, 0..n](row pitchldcBF16 elements) form < rows. - w8a8_
proj - 2026-09-28: One W8A8 projection: quantize
x([rows, ldx]BF16) and multiply, writingout([rows, ldc]BF16, the firstw.n()columns). - w8a16_
gemm - 2026-09-25: W8A16 GEMM for M>1:
C[M,N] = A[M,K] @ dequant(B[N,K])^T, with the 2D block scale[ceil(N/128), ceil(K/128)]FP32. - w8a16_
gemm_ m16 - 2026-09-25: Contiguous
input[m, k]BF16 andoutput[m, n]BF16;weight/block_scaleare the raww8a16_gemvpointers ([N, K]FP8 E4M3 and[N/128, K/128]FP32). - w8a16_
gemm_ m16_ n64 - 2026-09-25: The
N_TILE=64instantiation ofw8a16_gemm_m16: the same arguments and guards,ceil(N/64)CTAs instead ofceil(N/32). - w8a16_
gemm_ m16_ strided - 2026-09-25: Strided
w8a16_gemm_m16:a_row_stride/c_row_strideare the A and C row pitches in elements, for callers whose rows are not contiguous. The multi-seq decode QKV buffer (qkv_fp8_batch.rs) is[n, per_seq_qkv]with Q at offset 0, K after Q and V after K in every row, so one launch per projection writes allmrows into their slots. Same argument order asw8a16_gemv_batch16_strided. - w8a16_
gemm_ n128_ m128 - 2026-09-25: Transposed W8A16 GEMM with a 128x128 MxN tile (kernel
w8a16_gemm_t_m128): two 64-row chunks, 8 warps,m16n8k16BF16 MMA, and the block scale folded into an FP32 accumulator once per 128-K block (kernels/gb10/common/w8a16_gemm_t_m128.cu). Same arguments and layout asw8a16_gemm_t, so it takes the output of thetranspose_fp8/transpose_block_scalekernels unchanged. - w8a16_
gemm_ pipelined - 2026-09-25: Pipelined W8A16 GEMM (kernel
w8a16_gemm_pipelined), with the same arguments and block-scale layout asw8a16_gemm. A 128x32 MxN tile with 256 threads and a cp.async prefetch (PM_M_TILE,PM_N_TILE,PM_THREADSin kernels/gb10/common/w8a16_gemm_pipelined.cu). - w8a16_
gemm_ pipelined_ by_ m - 2026-09-25: Contiguous block-scaled W8A16 GEMM, tile chosen by
w8a16_pipelined_prefers_m32: the 32-tile twin onm32_kernel, else (2026-09-26)w8a16_pipelined_prefers_m64’s 64-tile twin onm64_kernel, else the 128-tilew8a16_gemm_pipelinedonfull_kernel. The GDNin_proj_qkvz/out_projbatched-verify arms (trait_decode_batched.rs) call it. - w8a16_
gemm_ pipelined_ m32 - 2026-09-25: Contiguous
[M, K]->[M, N]launch of the same kernel: the pitches arekandn. Same signature assuper::w8a16_gemm_pipelined. - w8a16_
gemm_ pipelined_ m64 - 2026-09-26: Contiguous launch of
w8a16_gemm_pipelined_m64(pitcheskandn). Same signature assuper::w8a16_gemm_pipelined. - w8a16_
gemm_ pipelined_ m32_ strided - 2026-09-25: Strided launch of
w8a16_gemm_pipelined_m32. - w8a16_
gemm_ pipelined_ m64_ strided - 2026-09-26: Strided launch of
w8a16_gemm_pipelined_m64: the arguments and checks ofw8a16_gemm_pipelined_m32_strided, grid (ceil(N/32), ceil(M/64), 1), block 256. The multi-seq attention Q/K/V and O arms take it above 32 rows underModelLevers::fp8_attn_m32. - w8a16_
gemm_ t - 2026-09-25: Transposed W8A16 GEMM:
C[M,N] = A[M,K] @ dequant(B_t[K,N]), with the transposed FP32 block scaleblock_scale_t[K/128, N/128], so weight reads are contiguous along N. Each CTA covers 64 rows and 64 columns with 128 threads (kernels/gb10/common/w8a16_gemm_t.cu, kernels/strix-hip/common/w8a16_gemm_t.cu). - w8a16_
gemm_ t_ pipelined - 2026-09-25: Pipelined transposed W8A16 GEMM (kernel
w8a16_gemm_t_pipelined), with the same arguments asw8a16_gemm_t: a 128x32 MxN tile with 256 threads (PT_M_TILE,PT_N_TILE,PT_THREADSin kernels/gb10/common/w8a16_gemm_t.cu). - w8a16_
gemv - 2026-09-25: W8A16 GEMV for M=1 decode:
C[1,N] = A[1,K] @ dequant(B[N,K])^T. - w8a16_
gemv_ batch2 - 2026-09-25: Launches a batch-2 block-scaled FP8 GEMV. No kernel under
kernels/defines aw8a16_gemv_batch2entry point. - w8a16_
gemv_ batch4 - 2026-09-25: Block-scaled FP8 GEMV for up to 4 rows
(
w8a16_gemv_batchm_impl<4>); one pass over the weight serves every row.input[M, K]BF16,output[M, N]BF16;weight[N, K]FP8 E4M3 andblock_scale[N/128, K/128]FP32, as forw8a16_gemv. - w8a16_
gemv_ batch4_ strided - 2026-09-25: Strided variant of
w8a16_gemv_batch4(up to 4 rows). It reads and writes rows at caller-given pitches, so one projection of the multi-sequence decode QKV buffer[n, per_seq_qkv]is written for every row in one launch. - w8a16_
gemv_ batch16 - 2026-09-25: The 16-row instantiation of the same template (kernel
w8a16_gemv_batch16, modulew8a16_gemv_batch4), with the launch geometry and per-row numerics ofw8a16_gemv_batch4. - w8a16_
gemv_ batch16_ ncol2 - 2026-09-25:
N_COLS=2, contiguous A[M, K]and C[M, N]. - w8a16_
gemv_ batch16_ ncol4 - 2026-09-25:
N_COLS=4, contiguous A and C. Grid: (ceil(N/16), 1, 1) - w8a16_
gemv_ batch16_ ncol2_ strided - 2026-09-25:
N_COLS=2, explicit A and C row pitches in elements, for the multi-seq[n, per_seq_qkv]decode buffer, asw8a16_gemv_batch16_strided. - w8a16_
gemv_ batch16_ ncol4_ strided - 2026-09-25:
N_COLS=4, explicit row pitches. - w8a16_
gemv_ batch16_ strided - 2026-09-25: The 16-row variant of
w8a16_gemv_batch4_strided(kernelw8a16_gemv_batch16_strided, modulew8a16_gemv_batch4), with the same launch geometry. - w8a16_
gemv_ dual - 2026-09-25: Two FP8 E4M3 GEMVs over the same BF16 input in one launch;
blockIdx.zpicks projection 1 or 2. Both havenoutputs. Each weight is[n, k]bytes with an FP32[n/128, k/128]block-scale buffer. - w8a16_
gemv_ row_ tiered - 2026-09-27: One row’s block-scaled W8A16 projection
[1, k] x [n, k]^Tfor a single-row decode site: underRowTiers::Canonical, whenm32_kernelis linked andkis whole 128-wide scale blocks, the 32-row tile (the order every other row count takes under that policy); otherwise the scalarw8a16_gemv. - w8a16_
gemv_ silu_ input - 2026-09-25: FP8 E4M3 GEMV whose activation is
silu(gate_out) * up_out, computed per element from the two[k]BF16 vectors inside the kernel.block_scaleis FP32[n/128, k/128]. - w8a16_
m16_ smem_ bytes - 2026-09-27: Dynamic shared memory of a skinny block for
k:PM16_SMEM_BYTES(K), the block’s 8 weight rowsk + 16bytes apart. - w8a16_
pipelined_ prefers_ m32 - 2026-09-25: The selection rule between the 128-tile
w8a16_gemm_pipelinedand its 32-tile twin at a contiguous call site: the twin takes1..=32rows when its handle is nonzero andKis a positive multiple of 128. Above 32 rows the twin would needgrid.y > 1, streaming the weight once per 32-row tile.w8a16_gemm_pipelined_by_mapplies it. - w8a16_
pipelined_ prefers_ m64 - 2026-09-26: 33..=64 rows take the 64-row twin
w8a16_gemm_pipelined_m64when its handle is nonzero andKis a positive multiple of 128: one weight pass for a whole k = 2 or 3 batched verify at C = 16, where the 32-row twin would stream the weight per tile and the 128-row tile is three-quarters empty. The three kernels give every output the same sub-MMAs in the same order (native_fp8_gdn_proj_m32_microtestcompares them byte for byte). - w8a16_
tc_ rows - 2026-09-28: The launch itself, with no policy check:
input[m, a_row_stride]BF16,weight[n, k]E4M3,block_scale[n / 128, k / 128]FP32,output[m, c_row_stride]BF16. Refuses a shapew8a16_tc_rows_shape_okrefuses. - w8a16_
tc_ rows_ launch - 2026-09-28: Launches
[m, k] x [n, k]^Tthroughw8a16_tc_rows_{16,32,64}and returns true when the lever is on, the process runsRowTiers::Canonical, the shape passesw8a16_tc_rows_shape_okand the target ships the module; otherwise returns false and launches nothing. - w8a16_
tc_ rows_ shape_ ok - 2026-09-28: The kernel’s shape contract, without a GPU: at least one row, N a positive multiple of 128 (whole scale blocks, whole CTAs), K a positive multiple of 128, and an A pitch that keeps rows 16-byte aligned and covers K; the C pitch covers N.
- wide_
prefill_ kernel - 2026-09-25: The head_dim > 256 prefill kernel and the BR its grid must be
built for.
qwen3_attention::inittakes the handle from here andprefill_attentiontakes the BR from here, so the two cannot disagree; a grid built for the wrong BR would not fail, it would cover the wrong q-tiles. - widen_
block_ scale_ f32 - 2026-09-25: Widen an FP8 block-scale tensor to FP32 on the GPU, so the
block-scale kernels read
const float*.srcis[total]BF16 (dtype 0), FP32 (1) or E8M0 (2);dstis[total]FP32. An E8M0 byteebecomes2^(e - 127)(the bit patterne << 23),e = 0becomes2^-127ande = 255becomes 0.0.
Type Aliases§
- Contiguous
Batch Gemv - 2026-09-25: The signature of the contiguous batched GEMV launchers, such as
w8a16_gemv_batch4andw8a16_gemv_batch16, so a caller that picks a tier by row count can hold the launcher and its handle as one pair. - Contiguous
M16Gemm - 2026-09-25: The shared signature of
w8a16_gemm_m16andw8a16_gemm_m16_n64, som16_tc_kernel(dense_ffn_m16_tc.rs) can return either as one function pointer. - Dense
M16Bf16 Gemm - 2026-09-25: The signature both instantiations share, so a caller can pick one and hold a single function pointer.