nx_f32_mha_multi.nx
buildroot/runtime/nx_f32_mha_multi.nx
about
nx_f32_mha_multi.nx -- bits-up f32 multi-head + multi-token attention.
L7 / L8 composition brick. Combines the head-decomposition pattern
from nx_f32_mha.nx (multi-head + GQA) with the multi-token causal
kernel from nx_f32_attn_multi.nx into the full attention forward.
This is the actual attention kernel for:
- Prefill (n_tokens = prompt length, causal mask)
- KV-cache decode (n_tokens = 1 new + cache; future Task #13)
- Non-causal encoder attention (causal = 0)
Algorithm:
Q_all = matmul(x, W_q) [n_tokens, n_heads*head_dim]
K_all = matmul(x, W_k) [n_tokens, n_kv_heads*head_dim]
V_all = matmul(x, W_v) [n_tokens, n_kv_heads*head_dim]
For each query head h in 0..n_heads:
kv_head = h / group_size
Slice Q_h, K_h, V_h from the column range [h*head_dim,
(h+1)*head_dim] for queries (or kv_head*head_dim for K,V).
attn_h = nx_f32_attn_multi(Q_h, K_h, V_h, n_tokens, n_tokens,
head_dim, causal, attn_scale)
Scatter attn_h back into attn_out_all at columns [h*head_dim,
(h+1)*head_dim].
out = matmul(attn_out_all, W_o) [n_tokens, hidden_dim]
Slicing is via copy in v1. v2 will use stride-aware kernels to
avoid the copy (perf lift queued).
genealogy_id: vaswani_2017_mha + ainslie_2023_gqa + causal_mask_canon
lineage_id: substrate_f32_mha_multi_v1
dependencies 5 imports · 1 importers
imports: nx_syscalls.nxnx_tier.nxnx_f32.nxnx_f32_matmul.nxnx_f32_attn_multi.nx
imported by: nx_f32_mha_multi_test.nx
structs
| none |
consts
| 41 | const NX_F32_MHAM_OK: nx_int = 0 |
| 42 | const NX_F32_MHAM_ERR_BAD_DIM: nx_int = 1 |
| 43 | const NX_F32_MHAM_ERR_BAD_GQA: nx_int = 2 |
| 44 | const NX_F32_MHAM_N_VERDICTS: nx_int = 3 |
functions
| 46 | func nx_f32_mham_verdict_is_valid(v: nx_int) -> nx_int called by 1: main |
| 54 | func nx_f32_mha_multi_token( |