round 6 track b — qsa flash #
experiment contract #
owner: prompt qsa kernels and the prompt_chunk dispatch block. preserve output bytes, selected-index semantics above budget, scalar fallback, and existing runtime interfaces. scratch only: /tmp/sol_r6_qsa/strata.
hypothesis: cached half scales plus eight-lane-per-head softmax lowers standalone flash time without changing any fp16 output bit. identity selection avoids topk below budget. scalar qsa_attn still needs ids, so retain its topk dispatch.
evaluator: same deterministic random int8/scales/query/gate input against frozen baseline kernel in /tmp/sol_r6_qsa/baseline; bitwise memcmp is mandatory. boundary cases include 2051/2052 and mixed chunks. standalone flash pairs at t=512,1024,1984; three paired samples per process, no warm duration loop; each process capped below 5 seconds. no full-model execution or port 8080. reject on byte mismatch; performance improvement must recur across sizes, otherwise report inconclusive. maximum three implementation repairs.
delivered change #
qsa_flash/qsa_attn_mmderive identity ids per token whenn_kv <= 2051; longer tokens retain explicit selection, including chunks that cross the threshold.- flash stages both half4 scales once per selected cell. removes the dead
vsstore. static threadgroup storage rises from 18,880 to 19,904 bytes; max threads remains 1024 on m5. - eight lanes per head compute max and exp; shuffle reduction stays inside each eight-lane partition. reuse dead
sp[0]for float exponentials; lane zero sums them in the original order. padding heads stay zero. - host dispatch skips
qsa_topkfor under-budget flash prompts. deliberate safety deviation: keeps it for!p.flash, because this branch dispatches scalarqsa_attn, which unconditionally reads ids and is outside this track's ownership. unconditional under-budget skipping would break that fallback. only original window.cpp line 3454 changes. - test adds
--flash-compare T pos0 baseline_qsa_prompt.metaland poisons implicit ids. ordinary parity now also exercises mixed-budget windows at pos0=1984 and 2050.
actual runs #
machine: apple m5, safe metal math (runtime default), rng seed 5. baseline is the frozen working tree, not clean upstream: repository head 296b59d2f73c8f04a805df29c2fa97655adace78; exact owned-file hashes in /tmp/sol_r6_qsa/sha256.json, initial status in baseline-status.txt. no tracked vendor file was edited. source snapshots and test executable are under /tmp/sol_r6_qsa/.
compiled test with:
clang++ -std=c++20 -O2 /tmp/sol_r6_qsa/strata/metal/tests/qsa_prompt_parity.cpp -I/tmp/sol_r6_qsa/strata/metal/src -I/tmp/sol_r6_qsa/strata/metal/tests vendor/strata/build-metal/libmtl_rt.a -framework Metal -framework Foundation -o /tmp/sol_r6_qsa/qsa_prompt_parity
the existing runtime static library was reused; candidate msl is runtime-compiled from scratch, selected with STRATA_METAL_KERNELS=/tmp/sol_r6_qsa/strata/metal/kernels. exact invocation per pair:
/tmp/sol_r6_qsa/qsa_prompt_parity --flash-compare T POS /tmp/sol_r6_qsa/baseline/metal/kernels/qsa_prompt.metal
three interleaved paired gpu timings per process after one correctness dispatch each; no sustained warmup. all processes exit 0, all under 1.5 seconds wall, each launch timeout=4.9s.
| t | pos0 | initial baseline → candidate ms | confirmation baseline → candidate ms | confirmation reduction |
|---|---|---|---|---|
| 512 | 0 | 2.538 → 2.032 | 2.537 → 2.036 | 19.7% |
| 1024 | 0 | 9.437 → 7.574 | 9.426 → 7.572 | 19.7% |
| 1984 | 0 | 34.353 → 27.461 | 34.361 → 27.503 | 20.0% |
| 96 | 1984 | 3.801 → 2.540 | — | — |
| 32 | 2050 | 1.819 → 1.165 | — | — |
| 96 | 30000 | 4.543 → 3.336 | — | — |
every listed comparison passed full-output memcmp == 0 against frozen flash baseline, with implicit ids poisoned to -1 in candidate correctness dispatch. timing-only candidate ids were restored for fair baseline pairing.
ordinary parity command (same environment, no args): exit 0, ALL PASS, 0.208 seconds final run. qsa_attn_mm relative l2 vs scalar reference ranged 3.09e-4–3.62e-4; flash ranged 3.72e-4–4.28e-4 across pos0 0/1984/2050/30000. score worst relative difference 2.76e-6. existing fused prep qcurh and flash memcmp both pass. logs: /tmp/sol_r6_qsa/parity-final.log, flash-*.log, confirm-flash-*.log.
decision / limitations #
recommend applying the combined patch: reproducible ~20% standalone under-budget flash reduction, tested byte parity, topk dispatch removed on the flash short-prompt path. topk host savings are not timed here. no end-to-end prefill speed claim; full model and :8080 were not run/touched. m4 / non-k4 execution not available (the branch compiles on m5); scalar fallback host behavior is preserved by retaining topk. no full engine rebuild was run; host edit is a single conditional guard.
patch: /tmp/sol_r6_qsa/sol_r6_qsa.patch; git -C vendor/strata apply --check passes. reviewed complete scratch diff with view_diff and kernel/test context with view_code. host edit verified restricted to original line 3454, inside authorized 3440–3475.