round 11 track b: qsa attention and score #

decision #

keep the qsa_attn_mm cooperative k/v hoist only. full partial-buffer memcmp passes all 16 requested cases. two nine-pair confirmations at T=1984, pos0=30000 give 70.488 → 39.162 ms and 70.649 → 39.163 ms, about 44.5% less kernel time / 1.80x throughput on apple m5.

reject the score changes: 8192-byte threadgroup storage and bitwise equality are demonstrated, but a repeatable speedup is not. the retained patch leaves qsa_score_mm, qsa_flash, dispatch interfaces, and the non-coop_k4 path's arithmetic unchanged. the test gains --mm-compare attn|score T pos0 baseline.metal pairs.

boundaries and provenance #

  • scratch tree: /tmp/sol_r11_qsa/strata; no tracked vendor files edited, no server requests, no full-model runs, no child agents.
  • clean patch: /tmp/sol_r11_qsa/sol_r11_qsa.patch; git -C vendor/strata apply --check passes.
  • base submodule head: 296b59d2f73c8f04a805df29c2fa97655adace78, plus the existing dirty workspace, not head alone. kernel baseline sha256: 2cdfe150dc1b97c8502299bd34fb06a9f2253d12525ab3dca7f990988ac825a5.
  • exact copied baseline: /tmp/sol_r11_qsa/baseline.metal; baseline tester: /tmp/sol_r11_qsa/baseline_qsa_prompt_parity.cpp.
  • snapshots, binary hashes, runtime-source hash: /tmp/sol_r11_qsa/manifest.json. plan fixed before candidate runs: /tmp/sol_r11_qsa/plan.md.
  • machine: apple m5, coop_k4=1, macos 27.0 build 26A428. safe metal math; no fast-math override. deterministic seed 5; random signed int8 caches, finite positive fp16 scales, fp16 queries. explicit selected ids are evenly spaced unique causal cells; implicit rows poison ids with -1. score inputs use deterministic random fp32 values.

implementation and evaluator #

k row pointers and all four scale groups are resolved once before the eight k steps. the cooperative layout repeats its eight cell identities 16 k later, so the pointer index must be (i >> 2) & 7. v pointers/scales are resolved once per 32-cell run and dimension slice. empty cells read valid row-zero addresses with zero scales; parity includes incomplete 64-cell chunks and the final three-cell selection chunk.

the comparator compiles baseline and candidate in the same process, dispatches them to separate identically sentinel-filled outputs, and compares the entire byte buffer, including inactive/unwritten regions. attention compares part before merge, not a tolerance or rounded output. score compares all scores including the scalar dead-key tail and untouched beyond-causal cells. each side receives one untimed correctness dispatch before measurements. timings alternate baseline/candidate order, one dispatch per sample; final tester prints every pair.

all requested attention cases passed: T={96,512,1024,1984} × pos0={0,1984,2050,30000}. logs: /tmp/sol_r11_qsa/attn-T-pos0.log. static threadgroup memory stays 6912 → 6912 bytes. no m4 hardware test; its fallback arithmetic is retained.

confirmation case baseline median ms candidate median ms result
1984 / 30000, nine pairs, repeat 1 70.487958 39.162417 pass, -44.44%
1984 / 30000, nine pairs, repeat 2 70.648958 39.162750 pass, -44.57%
96 / 1984, nine pairs, repeat 1 2.845500 1.518750 pass, -46.63%
96 / 1984, nine pairs, repeat 2 2.854875 1.517750 pass, -46.84%
1984 / 0, nine pairs 29.593292 15.733958 pass, -46.83%

confirmation logs: /tmp/sol_r11_qsa/attn-confirm-{0..4}.log (also copied into audits/sol_r11_qsa_evidence/ alongside the matrix logs and manifest). all 18 long-context confirmation pairs favor the candidate; repeat-1 baseline samples span 70.160–70.800 ms and candidate samples 39.132–39.196 ms. these stable confirmations support retention under the predeclared >3% improvement rule.

score: valid negative result #

three variants were tested against the original 64×64 score gemm:

  1. two 32×64 gemms into an 8192-byte buffer, float4 head reduction, packed-float4 device output for arbitrary row-stride alignment. parity passes, no consistent speed gain.
  2. one 64×64 gemm into a cooperative accumulator, manual two-window scatter into an 8192-byte buffer. parity passes, roughly 1–2% slower on the large case.
  3. same full gemm, native accumulator stores through tO.slice(0, -row * IH) into the clipped 32-row view, barriers between reuse, float4 reduction. this avoids the manual scatter and passes all 20 requested cases: T={96,512,1024,1984} × pos0={0,1984,2050,2052,30000}.

variant 3 confirms actual pipeline static allocation 16384 → 8192 bytes, but long-context 15-pair medians were 4.532750 → 4.540500 ms and 4.542000 → 4.546917 ms; another three-pair sweep gave 4.529333 → 4.624542 ms. low-position cases often regressed too. reduced allocation does not establish an occupancy or performance win. not included in the patch.

rejected snapshots: /tmp/sol_r11_qsa/score-two-gemm.metal, score-window.metal; logs score-staged-*.log, score-window-*.log, and score-matrix-T-pos0.log. the score-mode evaluator remains useful for later work.

run quality, repairs, and limits #

  • first attention candidate failed parity because the repeated k-layout pointer index omitted & 7; repaired before the matrix/confirmations. the failed snapshot is preserved as candidate-a.metal. no failing kernel code is retained.
  • score baseline-vs-baseline evaluator control passed before modification. final same-source attention control passes; nine-pair medians 2.038333 → 2.048625 ms (~0.5% difference), with early warm-up/load outliers visible in the raw pairs.
  • this is a shared live-server machine, not an isolated performance environment. exploratory samples varied heavily; one early T96/1984 median regressed and was explicitly retested twice. no speed claim relies on that noisy sample or on a single run.
  • all completed invocations were below five seconds. each was launched with a five-second deadline. one redundant final large-case check hit that deadline and was terminated (5.026 seconds including termination overhead); it produced no measurement and is an execution failure, not a parity failure. /tmp/sol_r11_qsa/final-attn-1984-30000-9.log preserves it.
  • the smaller post-review baseline comparison passes (final-attn-small.log); its heavily contended 124.001 → 82.592 ms medians are not used for the primary claim. final score-mode smoke passes with the unchanged retained score kernel; invalid target returns status 2. final build exits 0.
  • the largest attention test allocates about 3.24 gb for its two partial buffers; it is a test-only cost. no model benchmark or end-to-end server speedup was measured.

reproduction #

from the project root, build the standalone evaluator (the existing runtime library is read, not rebuilt):

clang++ -std=c++20 -O2 -I/tmp/sol_r11_qsa/strata/metal/src /tmp/sol_r11_qsa/strata/metal/tests/qsa_prompt_parity.cpp vendor/strata/build-metal/libmtl_rt.a -framework Metal -framework Foundation -o /tmp/sol_r11_qsa/qsa_prompt_parity

set STRATA_METAL_KERNELS=/tmp/sol_r11_qsa/strata/metal/kernels, then run with an external five-second deadline:

/tmp/sol_r11_qsa/qsa_prompt_parity --mm-compare attn 1984 30000 /tmp/sol_r11_qsa/baseline.metal 9

for the rejected score candidate, copy the archived score-window.metal into the scratch kernel path only, and use --mm-compare score ...; restore the retained kernel afterward. do not run these concurrently with other gpu benchmarks. source review completed via full patch images and surrounding definitions; patch touches only the owned attention kernel and test file.