gqa-decode-composite: measure primitive hand-tiled (16×16×16) latency
Switch primitive hand-tiled Q·Kᵀ / P·V from a deferred-K-sum tl.dot chain to per-block GemmCmd writes into a shared (M, N) out handle (implicit MAC-side accumulation). Full-shape coarse Q / K_T / V loads carry data-mode correctness; per-block DMAs remain for the streaming architecture dispatch story. The kernel now runs in engine mode end-to-end, so its 128K latency is measured instead of derived as primitive + Δdispatch. Drop the coarse-primitive baseline from the sweep and plots; keep the kernel file for reference. At S_kv=128K: primitive hand-tiled = 959.5 µs vs composite = 460.7 µs (2.08× from 5 235 vs 94 PE_CPU commands). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,12 +64,11 @@ def test_tiled_gemm_count_matches_block_formula():
|
||||
|
||||
def test_tiled_dma_count_matches_streamed_formula():
|
||||
"""Streamed operand DMAs — Q·Kᵀ blocks pay 2 DMAs (A+B slice), P·V
|
||||
blocks pay 1 DMA (V slice only; the P side is TCM-resident). Each
|
||||
_blocked_dot_* call also emits one small prime DMA at the top so the
|
||||
DataExecutor's read of the shared M×N output succeeds — 2 primes per
|
||||
outer S_kv tile (one QK + one PV)."""
|
||||
blocks pay 1 DMA (V slice only; the P side is TCM-resident post-softmax).
|
||||
Each matmul also carries full-shape coarse loads for the GemmCmd
|
||||
operand handles (2 for Q·Kᵀ: Q + K_T, 1 for P·V: V only)."""
|
||||
n_tiles, qk, pv = _block_counts()
|
||||
expected = n_tiles * (2 * qk + 1 * pv + 2)
|
||||
expected = n_tiles * (2 * qk + 1 * pv + 3)
|
||||
|
||||
cmds = _run(_tiled, _S_KV)
|
||||
got = sum(1 for c in cmds if isinstance(c, DmaReadCmd))
|
||||
@@ -77,12 +76,12 @@ def test_tiled_dma_count_matches_streamed_formula():
|
||||
|
||||
|
||||
def test_tiled_amplifies_dispatch_vs_primitive():
|
||||
"""The streamed tiled kernel emits ≫50× more PE_CPU dispatches than
|
||||
"""The streamed tiled kernel emits ≫40× more PE_CPU dispatches than
|
||||
the coarse primitive — the whole point of adding this variant."""
|
||||
n_tiled = sum(1 for c in _run(_tiled, _S_KV)
|
||||
if isinstance(c, PeCpuOverheadCmd))
|
||||
n_prim = sum(1 for c in _run(_primitive, _S_KV)
|
||||
if isinstance(c, PeCpuOverheadCmd))
|
||||
assert n_tiled > 50 * n_prim, (
|
||||
f"expected >50× dispatch amplification, got {n_tiled} vs {n_prim}"
|
||||
assert n_tiled > 40 * n_prim, (
|
||||
f"expected >40× dispatch amplification, got {n_tiled} vs {n_prim}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user