A container the suite can reach at index_bits 6, and a VQ4P arm in run.sh - #48
A container the suite can reach at index_bits 6, and a VQ4P arm in run.sh#48mfethe1 wants to merge 1 commit into
Conversation
…--index-bits 6 and a VQ4P arm in run.sh The VQ4P apply — and the AVX-512 kernel PR sqliteai#41 adds to it — was unreachable from make check: the synthetic container is always index_bits 8, and a real --index-bits 6 conversion needs the source weights and hours. So a green run asserted nothing about it, on any platform. --index-bits 6 writes the one combination the engine accepts at 6 (4 stages, 64 entries, packed 4x6 into 3 bytes, same packing as convert.py's block_indices_packed). The default path emits byte-identical containers: manifest.json gains no key (the engine reads absence as 8), and the rotary fixture's container_sha256 gate still passes. The VQ4P arm in run.sh runs the same four self-comparisons the engine block runs on VQ3R: records through the C structs (test_container now accepts the WQ_VQ4P fmt byte), chunked == token-at-a-time, SIMD vs CPU baseline, expert cache bit-identity. It builds in milliseconds, so it runs everywhere CI does — ARM takes the NEON vq_rows_p6 path, x86-64 without VBMI takes the scalar one, and PR sqliteai#41's kernel gets the same checks for free once it lands.
2fa0796 to
dee1a48
Compare
|
Following up on the #41 measurement (dispatched vs That makes the arm weaker than it looks on real containers, and I'd rather say so on the PR than let a green run carry it. The check that would actually pin it is the one you named in #41 — bit-identity of the int8 table (or of the routes) against the scalar path — since a broken kernel and a single entry rounding the other way are indistinguishable at logits level on 6-bit indices. The LUT is a pure function of the codebook, so it can be checked exhaustively in milliseconds with no container at all: build the table scalar, build it through the kernel's lane path, If that sounds right I'll send it as a follow-up — |
|
Traced this further after PR #41 merged — the dispatch table now has three real That rules out the LUT-building step as the source: given the same float activations, That confirms the fix precisely: the test needs to hold the int8 table fixed (not derived from a live, backend-dependent forward pass) and compare only the integer-accumulation step across backends. Scoped the harness assuming a
I don't have AVX-512 VBMI or ARM hardware here to build and run the SIMD arm myself, so I stopped short of writing it rather than ship an untested harness — happy to build the portable-reference half now if useful, or defer entirely if this is already in progress on your end. |
Requested by @Ultron09 in #41: teach
make_test_container.py--index-bits 6and wire the VQ4P engine check intorun.sh. This is that PR; the kernel it covers isvq_rows_p6, which #41's AVX-512 work joins.Why
CLAUDE.md names the trap this closes:
Until now
vq_rows_p6had no containermake checkcould reach: the synthetic one is alwaysindex_bits 8, and a real--index-bits 6conversion needs the source weights and hours. My own review on #41 said I had tried to close this and could not — this is the closing half, and #41's kernel gets the same checks for free once it lands.What
--index-bits 6writes the one combination the engine accepts at 6 (src/model.crefuses anything but 4 stages × 64 entries): records carry theWQ_VQ4Pfmt byte, indices packed 4×6 bits into 3 bytes with the same little-endian bit order and[M/B][pos][row]blocking asconvert.py'sblock_indices_packed, and the manifest'sexpert_quantcarriesindex_bits/fmt/bits_per_weightexactly as convert.py writes them.The default path emits byte-identical containers:
manifest.jsongains no key (the engine reads absence as 8), so the rotary fixture'scontainer_sha256gate is untouched. Verified per-file by sha256 at seed 0, plain and--rope, before and after.run.shgains aVQ4P engine (index_bits 6)section running the same four self-comparisons the engine block runs on VQ3R: records through the C structs (test_containernow accepts theWQ_VQ4Pfmt byte — same size and layout as VQ3R, only the payload packing differs), chunked == token-at-a-time, SIMD vs the CPU baseline, and expert-cache bit-identity. A few MB, milliseconds to build, so it runs on every host CI does.Evidence
Same tree (
2fa0796onmainat6430585), two platforms:vq_rows_p6vq_rows_p6Both boards are exactly baseline + 4: no prior PASS moved. The SIMD-vs-baseline check lands in the suite's existing "within fp noise" branch on both hosts, same as the VQ3R arm; the cache check is bit-identical on both. Also: the same-seed VQ4P container is byte-identical across Windows and macOS (6/6 file sha256s equal — the
newline="\n"discipline #47 landed, working), and the 4×6 packing round-trips against the engine'sP6_J0..P6_J3macros on 1,000,000 random rows with 0 mismatches.What this does not claim: quality of the noise codebooks (there is none — it is noise), and nothing about the AVX-512 kernel itself, which stays #41's to land; when it does, this arm covers it on Cascade Lake / Skylake-SP CI runners without further work.