test: cover fp8 block-scale dequantization - #40
Conversation
|
Reviewed. The test is good and I checked it by trying to break it rather than
Two things before this comes out of draft. 1. It never runs, on any machine that tests this project
It skips in CI too, and that is the part that decides it: the Linux Confirmed the fix, with the if ! command -v uv >/dev/null 2>&1; then
sk "fp8 block-scale mapping" "uv not installed"
else
out=$(run_uv run --quiet --with torch --no-project \
python tests/test_fp8_blocks.py 2>&1); rc=$?
2. One reader's guard is uncovered
Smaller
Nothing here is structural, and the mutation results say the core is right. |
Two things on top of tomatotomata's checks, which are unchanged and were right: the mutants I planted in unblock_scale — returning q untouched, transposing the block dims, dropping the [:M, :N] crop, removing the shape guard — were all caught, and expected_dequant being an independent index-array implementation rather than a second call to the code under test is what gives it that. It never ran. run.sh invoked it as bare `python3`, and torch is not a system package on the machines that test this: CLAUDE.md says it is never a repo dependency and every other torch checker goes through uv. So the whole thing reported "torch not installed" and skipped everywhere, CI included — where the Linux job is the one that installs uv, which is to say the one place it does get to run. Through run_uv now, with the guard on uv rather than python3, since without uv run_uv exits 127 and the catch-all would report FAIL where a SKIP is meant. 56 passed / 0 failed / 2 skipped becomes 57 / 0 / 2. And the missing-companion check exercised ST only. Deleting ShardReader's own `raise` in convert.py, so it returns the tensor unscaled instead, kept the suite green — a silent wrong answer in the reader sqliteai#26's description called out as "a second reader and was easy to miss". Both readers now, and that mutant is killed. The same mutation against ST survives, and should: without its guard, raw() still raises KeyError naming weight_scale_inv, so the contract the test asserts — refuses, and says which tensor — holds either way. That guard buys a better message, not a different decision, and asserting its exact prose would test the wording rather than the behaviour. Also wrote down the case nothing here can catch, which is the reason the tile size is read from config rather than inferred: 300 rows against 3 scale rows admits both 128 and 100, both pass every shape check, and the wrong one applies each scale to the wrong rows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Both points fixed and pushed to this branch — 1. It now runs. Through That line did not exist before. Under bare 2. Both readers. One thing I checked and deliberately did not change: the same mutation I also wrote down the case nothing here can catch, since #26 described it and CI is 9/9 on the branch. I approved the workflow run — it needed a maintainer Over to you to take it out of draft; I did not want to flip that on your For the record, your checks were the right ones and they were right on the |
|
Merged, and #39 closed with it. CI 9/9 on the merge commit, and the check runs rather than skips on the Linux job — which was the whole difference between this being coverage and being a file. Thanks. Filed in the morning, correct checks by the afternoon, and the mutation results were the part that made it easy to take: four planted bugs in |
Almost none of this is the engine. It is Windows, real containers, and the four feasibility gates that were still open, and most of it was found by people running hardware this project does not own. GATES.md has no open gate for the first time, and two of the three that closed this cycle closed against the change they were proposing. No ABI move: src/waste.h changed only in a comment this cycle, unlike 0.6.8. waste_kernels gained vq_rows_p6 but that lives in src/waste_backend.h and is not public. Added: the VQ4P apply behind a dispatch slot with an AVX-512 VBMI kernel beside it (#41), bit-identical on ARM against a real index_bits 6 container and still never executed on any machine here; WASTE_DUMP_SCORES (#45) and WASTE_CCR_LAMBDA (#46); the working set printed by `waste plan`, which was quoted by the line below it and never shown; and a test for the fp8 block-scale mapping whose only stub had replaced it with the identity (#40). Fixed: the five gaps of #36 and the two that survived the first attempt — VirtualLock bounded by the minimum working set rather than the maximum, so WASTE_MLOCK wired nothing on Windows twice over; diskbench truncating its offset through a 32-bit off_t at its own default file size, where the quiet half read the wrong place successfully and kept the working set inside an SSD's SLC cache; container JSON through Python text mode, which made the same conversion produce byte-different containers on Windows; a missing cmp reporting `expert cache changes results` on a clean checkout (#42); plus #35, #30, and the CLI help that said one thread per core when it is one per logical CPU (#44). Recorded as measured and not adopted, which is the half of this file that is easy to drop: the budget resolver's quantum stands after Gate 7 (§63); cache-conditional routing stays a knob because it clears README's KL bar and not its continuation bar; the thread default did not move despite 16 threads measuring 1.6x below the plateau; no budget policy fixes two K3 opens on 64 GB (§64, #31 closed, #49 opened for the residue); and VQ4P is not a throughput upgrade over VQ3R on a GB10 despite complete and exact CUDA coverage (§62). 53 passed, 0 failed, 6 skipped against Kimi-Linear and K3.
Resolves #39
What changed
tests/test_fp8_blocks.pywith aligned tiles, a partial final row and column, missing scale companions, and gross shape mismatch cases.mxfp4.STandconvert.ShardReaderagree when both read the configured block size.tests/run.sh, with an explicit SKIP when torch is unavailable.Validation
python tests/test_fp8_blocks.pypasses all 5 checks.python tests/test_convert_resume.pypasses.python tests/test_convert_chat.pypasses.git diff --checkpasses.The test stays synthetic and does not require model weights or a multi-hour conversion.