Expand description
2026-09-25: Paged-decode attention launch geometry: the split-K count, the split-K workspace size and the GQA-packed kernel gate, as pure functions of configuration.
The online-softmax split merge is not associative, so a split count that moved with the co-batched sequence count would change a sequence’s output bytes depending on what it is batched with.
Owner: kernels crate (paged-decode attention policy). Invariants:
- Under
SplitkPolicy::AutoandSplitkPolicy::Pinnedthe split count depends only on(sm_count, num_q_heads)and the pin; onlySplitkPolicy::Legacyreads the reference batch. resolve_policyis the one resolution of the target declaration andMETRALE_ATTN_DECODE_SPLITK; the metrale-model-layers dispatch and the metrale-gpu-runtime workspace sizing both call it.gqa_pack_shape_okadmits onlynum_q_heads == num_kv_heads * DECODE_GQA_PACK_WIDTHathead_dim == DECODE_GQA_PACK_HEAD_DIM.
SplitkPolicy::Legacy computes, with NUM_SMS standing for the target’s
sm_count:
current_ctas = num_q_heads * split_ref_seqs(num_seqs, max_decode_seqs);
num_splits = if current_ctas >= NUM_SMS { 1 } else { NUM_SMS / current_ctas };Short contexts are handled inside the Hopper split-K kernel, which floors
each sequence’s split size at PD_MIN_KV_PER_SPLIT from that sequence’s own
seq_len (kernels/hopper/common/paged_decode_splitk_hopper.cuh).
Enums§
- Splitk
Policy - 2026-09-25: How a target picks its paged-decode split count.
Constants§
- DECODE_
GQA_ PACK_ DECLARED - 2026-09-25: The packed kernels’ declared state: off, for every target.
METRALE_ATTN_DECODE_GQA_PACKoverrides it (resolve_gqa_pack). - DECODE_
GQA_ PACK_ HEAD_ DIM - 2026-09-25: The head dim the packed kernels are compiled for: both sources
#define PD_HDIM 256, andgqa_pack_shape_okrefuses any other head dim. - DECODE_
GQA_ PACK_ WIDTH - 2026-09-25: Query heads one packed CTA carries: the Rust copy of the
kernels’
#define PD_GQA, which sizes theirq_reg/o_regregister arrays at compile time.cuda_sources_declare_the_pack_width_rust_dispatches_onfails if the two differ. - MAX_
DECODE_ SPLITS - 2026-09-25: Ceiling on the split count under every policy but
Legacy, and so on the split-K workspace, which isrows * num_q_heads * num_splits * (head_dim + 2)F32 values. Without it a model with few q heads would ask for2 * sm_count / num_q_headssplits (264 for one head on 132 SMs). At 24 q heads on the 148-SM targets (kernels/b200,kernels/b300)autoasks for 13. A pinned count is clamped to it. - SPLITK_
TARGET_ WAVES - 2026-09-25: Waves of CTAs
SplitkPolicy::Autoaims to put on the device with one sequence in flight (seeauto_splits).
Functions§
- auto_
splits - 2026-09-25:
clamp(ceil(WAVES * sm_count / num_q_heads), 1, MAX_DECODE_SPLITS). - gqa_
pack_ ctas - 2026-09-25: CTAs a packed launch puts on the device:
num_kv_heads * num_seqs, aDECODE_GQA_PACK_WIDTH-fold cut from the unpackednum_q_heads * num_seqs. With 4 KV heads on gb10’s 48 SMs the packed grid covers the SMs only fromnum_seqs = 12. - gqa_
pack_ enabled - 2026-09-25: Whether the packed kernels are armed in this process, resolved once. The dispatch reads it on every non-split BF16 and FP8 paged-decode launch, and a fixed answer keeps a captured CUDA graph consistent with later launches.
- gqa_
pack_ shape_ ok - 2026-09-25: Whether this launch’s shape is one the packed kernels can serve. Each condition is a precondition of the kernel:
- legacy_
splits - 2026-09-25: The
SplitkPolicy::Legacyrule. The dispatch passesref_seqs = split_ref_seqs(num_seqs, max_decode_seqs), which ismax(max_decode_seqs, num_seqs). - num_
splits - 2026-09-25: The split count for a launch.
- parse
- 2026-09-25:
legacy|auto|0/off/false/no| a decimal count (clamped to1..=MAX_DECODE_SPLITS), trimmed and case-insensitive. - parse_
gqa_ pack - 2026-09-25:
1/on/true/yes|0/off/false/no, trimmed and case-insensitive. - policy_
from_ env - 2026-09-25:
resolve_policyagainst the process environment and this binary’s baked declaration. Used by the split-K workspace sizing in metrale-gpu-runtime (sizes.rs), which metrale-model-layers depends on and so cannot call the model-layers resolver. - resolve_
gqa_ pack - 2026-09-25:
declared, overridden by a parseableMETRALE_ATTN_DECODE_GQA_PACKvalue. Pure;gqa_pack_enabledsupplies the environment. - resolve_
policy - 2026-09-25: The target’s declaration, overridden by a parseable
METRALE_ATTN_DECODE_SPLITK. An unparseable declaration isLegacy. - workspace_
slots - 2026-09-25:
[o[head_dim], m, l]slots the split-K workspace must hold.