Repository navigation
dsv41 metal: bf16 and fp32 matvecs and the phase-1 glue - #1710
Conversation
0e0f75c to
f509b77
Compare
f509b77 to
01b15e4
Compare
|
Thanks @ashhart. #1710 now has a float64 case and live controls for all seven of
|
01b15e4 to
7a2a318
Compare
|
Thanks @gilby, and sorry for the long wait on this stack. We're reviewing it from the bottom, starting here. #1710 reads well: the matvec bits don't depend on the launch, since every tier uses the same lane chain order, a fixed butterfly, and contraction off. The 12 glue kernels match their stated formulas (E8M0, E4M3 and E2M1 rounding ties to even, checked). Each is gated against float64 with 2 to 4 planted controls, and the glue's own matvec is held byte-equal to the gated one. The records match the source, only family files change, every file is at or under 592 lines, and lean adds nothing. One small change before we run it, on bounds in the glue:
Please bound each (refuse a token id or position past the table, and refuse a zero shape by name). Then we'll run |
7a2a318 to
9d6513e
Compare
|
Thanks @ashhart. Done, and the stack is rebased onto main |
mv.metal runs the router, indexer, compressor and head matvecs as lane chains over K with one butterfly, so the bits never depend on the row count. glue_tmp.metal is the layer's phase-1 glue (norms, act_quant, RoPE, FP4, pools, candidates, hc and MoE glue), the reference bits the registered glue kernels are checked against.
9d6513e to
4733fdd
Compare
|
Thank you @gilby. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes. |
|
Thanks @gilby! This is in TensorFold 1.2.2, out now: https://github.com/ashhart/TensorFold/releases/tag/v1.2.2 |
What this changes
The router, indexer, compressor and head matvecs (
mv.metal, bits independent of the row count) and the layer's phase-1 glue (glue_tmp.metal: norms, act_quant, RoPE, FP4, pools, candidates, hc and MoE glue). Both are registered with the kernel contract: the phase-1 glue has 14 launch records (dsv41_glue_tmp_records.zig), planted controls in every kernel (a non-finite read as 0, a lost or swapped term, an fp16 total, a write past the end; they compile away atTF_CTL 0) and gate suites against float64:metal_dsv41_glue_tmp.zig(rmsnorm, RoPE, scatter, embed, hc mean; references indsv41_glue_ref.zig) andmetal_dsv41_glue_tmp2.zig(the FP4 pack and round trip, the compressor pool, the candidate blocks and the hc mix, pre and post; references indsv41_glue_tmp_ref.zig, which models each kernel's own arithmetic so non-finite inputs match bit for bit). Each of these seven kernels has its two planted controls (a lost term or wrong value, and a stray write) going red through data, and gives every row the same bits at 1, 7 and rows/3 rows a launch.Out-of-range inputs are bounded:
embedtakes the table's row count, and a token id past it gives zero rows and reads nothing; RoPE takes the position table's length, and a position past it leaves the row untouched; both refuse a zero size by name (RoPE also a head under 64 or odd, beforehead - 64is computed); the matvec wrapper returns an error for a zero shape instead of asserting, and every call site up the stack takes thetry. Host tests cover the refusals, and the contract has atable boundscheck (embed ids past the vocabulary, RoPE positions past the table) that goes red with the bounds removed.Main's shared files change only by one-line hooks; this part's records, suites and limits go into the family's own files (
dsv41_metal_records.zig,metal_dsv41_main.zig,metal_dsv41_limits.zig).Part 6 of 18 of the stack for #1676; stacks on main, with parts 1 to 5 (#1705 to #1709) merged.
Receipt
tools/bench_concurrent.py --alone --serialortoken_shaagainst"draft": false: n/a: kernels only; the kernel contract checks each launch geometry's bits against the others and against float64.tools/bench_openai.py: measured on the PR that turns serving on.ttft_sfromtools/bench_cache.py --require-coldon a long prompt, or "n/a" with the reason when the change cannot reach prompt processing: measured on the PR that turns serving on.zig build test tf-kernel-contract -Dcpu=apple_m1: exit 0, 621/621 steps succeeded; kernel contract,tf-kernel-contract --only dsv41(Metal):SUMMARY 38 kernels: 38 pass gates 1-4, 0 fail, 0 known findings; 66 controls: 66 red as planted, 0 missed; 0 limit problems; gates 98147 ms, limits 173 ms;python3 tools/zig/lean_check.py: 5040 files, 424 problems, the same count as main (5027 files, 424). Zig's summary counts only the test binaries it ran in that invocation, so the step count is the comparable figure.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo.SUMMARYline is in the receipt.