round 30 track b: no shippable improvement #
decision #
keep the existing kernels. nine isolated source variants were screened; none established a repeatable 2% improvement. all valid a/b runs were bitwise identical. /tmp/sol_r30_prompt/sol_r30_prompt.patch is deliberately empty; git -C vendor/strata apply --allow-empty --check /tmp/sol_r30_prompt/sol_r30_prompt.patch exits 0. plain apply --check rejects an empty patch, so there is nothing to apply. no tracked vendor files were edited, and no test changes are proposed.
experiment contract and provenance #
question: can redundant accumulator state, smaller reduction storage, gate-load/unroll changes, or hc epilogue address simplification reduce gpu time without changing a bit?
acceptance set before runs: bitwise equality and repeatable >2% target-kernel improvement without material regression across 512/1024/2048. no candidate cleared screening, so the planned two-repeat confirmation of a winner was unnecessary. the accumulator/gate candidates were nevertheless checked at all three sizes, and up-hoist at 2048 too.
- device: apple m5; macos version 27.0 (build 26a428).
- vendor head:
296b59d2f73c8f04a805df29c2fa97655adace78; working source snapshot, not assumed clean. - immutable baseline:
/tmp/sol_r30_prompt/base_prompt.metal, sha25686adff9cfdbdf1af34ecfbdab0bef8b9e0668b3884a577469ac7bc58140f13a3. - executable: existing
vendor/strata/build-metal/comb_fold_parity; sha256ba877816cf682d912ebdcd5fcd30e83dfcdcb9ff024b06ff58c8ad3d9547bf30. no rebuild needed: tests compile the selected msl at runtime. - scratch tree:
/tmp/sol_r30_prompt/strata, withSTRATA_METAL_KERNELS=/tmp/sol_r30_prompt/strata/metal/kernels. - evaluator: existing ab_parity, 12 alternating paired samples of 8 dispatches, rotated output buffers; medians of paired ratios. safe metal math, explicit fma order retained.
- source selection independently verified by injecting an invalid type into scratch gr_norm_h4: compilation failed as expected (exit 3), then source was restored. no silent fallback to live kernels.
- gpu invocations serialized; existing live server left alone. no port access or full-model benchmark. every measured invocation completed in <5s (20s cold-compile timeout cap).
- metadata and immutable candidate
.metalsources alongside each.logunder/tmp/sol_r30_prompt/.
screens #
ratios are candidate/baseline; lower is faster. each row is one source variant, not an additive stack.
| variant | t | moec | h4 apply 1 | h4 apply 0 | result |
|---|---|---|---|---|---|
| self/self baseline | 1024 | 0.9996 | 0.9998 | 0.9985 | control |
| direct bv accumulation, no s array | 512 | 1.0000 | 1.0066 | 0.9861 | no target improvement |
| direct bv accumulation | 1024 | 0.9960 | 0.9999 | 1.0032 | noise-scale |
| direct bv accumulation | 2048 | 0.9999 | 1.0043 | 0.9997 | no improvement |
| float4 gates, exact quarter when hc=4 | 512 | 0.9995 | 0.9983 | 0.9936 | noise-scale |
| float4 gates | 1024 | 1.0014 | 0.9989 | 0.9955 | noise-scale |
| float4 gates | 2048 | 0.9996 | 1.0006 | 0.9975 | no improvement |
| ping-pong part[2][8], scoped to owned kernels | 1024 | 0.9975 | 0.9976 | 0.9960 | noise-scale |
| fully unrolled four-stream loop, hc guard | 1024 | 0.9988 | 0.9989 | 0.9978 | noise-scale |
| first simdgroup returns register slot count | 1024 | 0.9988 | 1.0013 | 1.0040 | no improvement |
| all residual streams live, one reduction barrier | 1024 | 1.0021 | 1.0011 | 0.9929 | no target improvement |
all bitwise pass. the earlier pingpong exploratory snapshot accidentally also replaced an unowned helper declaration in scratch only; it is excluded from the decision and superseded by pingpong_fixed, whose prefix is unchanged. nothing from either is shipped.
| epilogue variant | t | hc-down | hc-up reg 32/128/4 | result |
|---|---|---|---|---|
| self/self | 1024 | 1.0014 | 0.9935 | control; up noisier in early run |
| hc-up tile-base address hoist | 1024 | 1.0104 (unchanged source) | 1.0004 | no improvement |
| hc-up tile-base address hoist | 2048 | 1.0006 (unchanged source) | 1.0039 | slight loss |
| hc-down hardcode documented hc=4 precondition | 1024 | 0.9973 | 1.0010 (unchanged source) | noise-scale |
no measured register-occupancy evidence supports the task's proposed “saves ten vgprs” claim: compiler lifetime/coalescing may already remove the distinction. similarly, source-level arithmetic simplification alone did not improve measured throughput. near-linear scaling of gr latency is consistent with bandwidth pressure, but this is not a hardware-counter diagnosis.
final baseline controls #
scratch restored byte-for-byte to the original baseline. independent ab ... gr and ab ... gemm modes exercise the same cases as unfiltered ab, while keeping each invocation short. all cases pass at all requested sizes.
| t | moec ms | h4 apply 1 ms | h4 apply 0 ms | hc-down ms | hc-up ms |
|---|---|---|---|---|---|
| 512 | 0.8743 | 0.4548 | 0.2247 | 0.2899 | 0.2945 |
| 1024 | 1.7317 | 0.9049 | 0.4691 | 0.6718 | 0.5732 |
| 2048 | 3.4438 | 1.8054 | 0.9586 | 1.2101 | 1.1294 |
hc-down tiles follow the evaluator's production-size selection: 32/128/4, 64/128/4, 32/128/2 respectively. these are standalone latencies, not promised full-model savings.
additional requested regressions, all exit 0:
comb_fold_parity 1024: all 20 bitwise checks pass at t=1,7,64,1024; 4.32s.comb_fold_parity 0 epi: all tested tiles/sizes through 2048 bitwise pass; 0.60s.comb_fold_parity 256 hcup: all enumerated tiles, mixed bound and unbound, bitwise pass; 0.05s. this mode's existing tile list does not include reg 32/128/4; the a/b evaluator explicitly covers that production tile instead.
logs: /tmp/sol_r30_prompt/{variant}_{t}_{gr|gemm}.log, parity1024.log, epi.log, hcup.log. final control logs use final_control_....
stop reason #
valid negative result: all high-leverage suggestions tested, no qualifying performance winner. do not ship cosmetic kernel rewrites on this evidence. a larger gain would need a different memory-traffic or dispatch decomposition, not the source-level state/address rewrites tested here.