round 16 track b — decode wave zip and table barrier guards #
experiment contract #
- owner:
Window::layerdispatch scheduling and gemv kernel table initialization. only the assigned decode block andgemv.metalchange, in/tmp/sol_r16_dec/strata. - hypothesis: zip independent resident moe and shared expert work into three waves rather than four, preserving all data dependencies and fallback dispatch order; remove table-init barriers only where the compile-time table has one dummy element.
- constraints: no live server interaction or full-model runs; each standalone test invocation has a 4.9s deadline. no new tracked vendor edits. gemv_x retains its activation-staging barrier.
- evaluator: baseline/current scratch kernels on identical seeded inputs, memcmp of output bytes, plus short interleaved gpu timings. six non-table formats × ntok 1..4, gemv and cat. table formats and pair covered where existing tests permit. require exact output equality; speed differences below 3% treated as noise without replication.
- scheduling proof: first wave moe_gu + shared gate/up/gate-inp; second moe_down + swiglu_prep; third shared down. fallback sequence/barriers must remain identical. kernel unit tests cannot establish full-model scheduling parity; report this limitation.
- budget: local short unit invocations only, serial gpu measurements, up to three repeated comparison passes. build cpu work may run alongside inspection. stop or narrow tests that exceed 4.9s; do not silently describe timed-out tests as passing.
implementation #
patch: /tmp/sol_r16_dec/sol_r16_dec.patch (sha256 602c139238113e75e1ac528109215f040645d617b8590051b2610fc3cdbae09d). it applies with git -C vendor/strata apply --check. no tracked vendor file was edited. base checkout HEAD: 296b59d2f73c8f04a805df29c2fa97655adace78; the checkout was already dirty, so exact before/after file hashes are recorded in /tmp/sol_r16_dec/metadata.json. baseline is the copied working tree, not pristine HEAD.
- two shared-work lambdas let the split path emit resident gu beside shared gate/up/gate-inp, resident down beside shared prep, then shared down. phase 2 remains after the host wait. this is one fewer internal buffer barrier per layer, hence 48 fewer for a 48-layer decode window, by schedule construction, not an end-to-end timing result.
!sigs_/!esplitretain the original dispatch/barrier order. signal and cut positions retain their dispatch indices (same number of dispatches).- gemv/cat only initialize and synchronize real tables. pair synchronizes if either format needs a table. gemv_x only guards the no-op table load: its activation staging barrier stays unconditional. the KS>1 reduction barrier is untouched.
- no extra buffers, allocations, public interfaces, persistent state, or new feature flags.
build and correctness #
machine: apple m5, macos 27.0 build 26a428, safe metal math (default). every standalone execution had timeout=4.9; cpu builds were not subject to the test deadline.
build succeeded:
cmake -S /tmp/sol_r16_dec/strata/metal -B /tmp/sol_r16_dec/strata/build-metal -G Ninja -DCMAKE_BUILD_TYPE=Release -DMETAL_CPP_DIR=/tmp/sol_r16_dec/strata/third_party/metal-cpp -DSTRATA_GGML_DIR=/Users/dawn/proj/swift1.5-qwen3.8-next-flash-ps-scr-qat-persona/vendor/llama.cpp
cmake --build /tmp/sol_r16_dec/strata/build-metal --target strata_window_cli gemv_parity route_parity fuse_parity expert_parity pair_parity -j 4
route_parity: pass, k=512 and k=256+moce, 200 windows each, zero mismatches; 2.406s.expert_parity: pass, default q2_0/q2_0, ntok=1; h relative l2 1.81e-7, y 6.13e-8; 0.477s.pair_parity: all pass, including table/non-table pairs and raw q2_0 down; 3.338s.- unmodified
gemv_parityandfuse_parity: deadline exceeded at 4.9s, not passes. logs retained. nomoe_paritytarget/source exists; an explicit build request reports unknown target. expert parity and the zip test below supply relevant coverage, but are not a fictitious pass of that missing target. - gemv suite sharded outside the strata tree, changing only its format/token iteration lists: 39/39 invocations pass (13 formats × ntok 1,3,8); original shapes, tile list, double reference, and token-wise bitwise comparisons remain. maximum invocation 2.828s. source:
/tmp/sol_r16_dec/gemv_shard.cpp; logsgemv_shard_*.log. - fuse suite sharded outside strata only by token count: ntok 2..8 pass, including cat, bf16/f32 fused router, and combined norm variants. ntok=1 still hits the 4.9s deadline, including a line-buffered diagnostic attempt; no diagnostic device/result line was emitted before termination. do not treat the full fuse suite as passing. logs
fuse_shard_*.logandfuse_nt1_diagnostic.log. - actual owned scheduling block extracted unchanged from baseline and candidate into an external mock fixture: 32/32 configurations pass (split flag off/on × signal off/on × router fusion off/on × streaming off/on × predictor off/on). fallback pipeline order/barrier flags and signal/cut indices match. split path explicitly asserts the seven dispatches and
[true,false,false,false,true,false,true]flags, with 3→2 internal barriers. fixture mocks payloads; this is not numerical full-model validation. source/tmp/sol_r16_dec/schedule_probe.cpp, logsschedule_0.log,schedule_1.log. - real metal zip parity: ntok 1..4 × zero/mixed/all resident sets, 8 repetitions each, comparing 8 full intermediate/output buffers (
h,ye, shared g/u/gate-inp, prepared shared h, shared down, final combine). 768/768 buffer comparisons equal byte-for-byte. uses arena addressing, phase-1 cached slots, phase-2 missing experts, indirect plans, concurrent encoders, and real q2_0 kernels at 2560/640 dimensions. both schedules use identical guarded kernels, isolating scheduling. max invocation 3.557s. source/tmp/sol_r16_dec/zip_probe.cpp, logszip_probe_1.logthrough_4.log.
guard-only benchmark and exact parity #
external harness /tmp/sol_r16_dec/guard_probe.cpp compiles baseline and candidate kernel function bodies unchanged, with reduced template instantiations to fit the short invocation budget. same seeded weights/inputs, safe math, prepared activations, and paired processes. gemv/cat/x use tile 16,1,4,1 (cat/x have no KS); pair uses 32,4. shape 2560→640; cat is 640+640 rows, not the production 48+48 alpha/beta shape. six requested formats × ntok 1..4 × 3 independent invocations = 72/72 successful invocations, maximum wall time 0.785s. each compares gemv, cat (both outputs), x, and same-format pair to the baseline with memcmp: 100% exact.
each kernel warms both variants together for 50ms, then runs five paired batches of 64 dispatches, alternating baseline/candidate order; gpu time per dispatch is the metric. table below reports median base and candidate times across the three invocations. raw logs retain the paired ratios; medians of times and ratios need not divide identically.
| format | ntok | gemv base → guard (µs) | cat base → guard (µs) |
|---|---|---|---|
| Q6_K | 1 | 7.027 → 6.981 | 18.323 → 18.270 |
| Q6_K | 2 | 9.395 → 9.395 | 19.953 → 20.047 |
| Q6_K | 3 | 13.047 → 13.023 | 25.964 → 26.168 |
| Q6_K | 4 | 15.890 → 15.896 | 30.842 → 31.098 |
| Q8_0 | 1 | 6.771 → 6.738 | 22.783 → 22.660 |
| Q8_0 | 2 | 9.251 → 9.216 | 23.932 → 23.532 |
| Q8_0 | 3 | 12.055 → 12.013 | 26.114 → 26.232 |
| Q8_0 | 4 | 14.654 → 14.684 | 29.785 → 30.182 |
| Q2_0 | 1 | 5.027 → 4.956 | 8.148 → 8.139 |
| Q2_0 | 2 | 6.869 → 6.835 | 11.895 → 11.855 |
| Q2_0 | 3 | 9.073 → 9.010 | 15.979 → 15.977 |
| Q2_0 | 4 | 11.242 → 11.211 | 20.301 → 20.246 |
| BF16 | 1 | 21.738 → 21.574 | 42.350 → 42.387 |
| BF16 | 2 | 21.796 → 21.764 | 43.016 → 43.252 |
| BF16 | 3 | 21.828 → 21.744 | 43.326 → 43.423 |
| BF16 | 4 | 21.953 → 21.965 | 44.823 → 45.260 |
| Q4_K | 1 | 6.943 → 7.012 | 11.160 → 11.105 |
| Q4_K | 2 | 8.878 → 8.891 | 14.748 → 14.701 |
| Q4_K | 3 | 13.403 → 13.368 | 23.375 → 23.287 |
| Q4_K | 4 | 16.223 → 16.186 | 29.035 → 28.949 |
| Q5_K | 1 | 7.529 → 7.443 | 12.816 → 12.797 |
| Q5_K | 2 | 9.283 → 9.304 | 16.802 → 16.758 |
| Q5_K | 3 | 13.953 → 13.938 | 25.884 → 25.851 |
| Q5_K | 4 | 16.850 → 16.785 | 31.630 → 31.506 |
no credible guard-only speedup established. geometric mean of per-case median paired base/candidate ratios: gemv 1.0026×, cat 0.9998×, x 0.9988×, pair 0.9985×. gemv case ratios range 0.9838–1.0156; cat 0.9843–1.0117. all lie inside the predeclared 3% noise threshold after replication. this is a correctness-validated barrier cleanup, not evidence for a throughput claim. compiler elimination of redundant barriers is plausible, but not proven by these measurements.
artifacts and limits #
all large artifacts are under /tmp/sol_r16_dec/: build.log, metadata.json, probe_runs.json, probe_summary.json, probe_*.log, harness sources/binaries, and baseline/candidate reduced msl. exact full baseline files can be recovered from the scratch git index (git -C /tmp/sol_r16_dec/strata show :metal/kernels/gemv.metal, likewise window.cpp).
reproduce probes using guard_probe <format-id> <ntok> (14,8,42,30,12,13), zip_probe <ntok>, schedule_probe with STRATA_METAL_EXPERT_SPLIT=0/1, gemv_shard with TEST_TYPE/TEST_NTOK, and fuse_shard with TEST_NTOK; always enforce the 4.9s deadline. harnesses link scratch build-metal/libmtl_rt.a, include scratch metal/src, and use -std=c++20 -O2 -framework Metal -framework Foundation.
reviewed the complete production diff and surrounding code with view_diff/view_code; existing moe table guards provide the matching idiom. checked patch application and file/line scope. no live server request, port 8080 operation, full-model run, or full-model performance claim. synthetic parity does not establish real-model answer parity or host-overlap wall-time benefit. the uncompleted fuse ntok=1 check remains a validation limitation.