Repository navigation
Conversation
…lot pieces (Bolt offload) `HandoffSlots::Nine` picks the new `ds41_ffn_handoff_9` entry (`handoff_at`'s contract at nine slots; no `_9_cols` or `_9_tier`: Bolt's prompt uses the batch port, which needs no handoff launch). `weighted_sum_card` is the routed combine over the card's slots: `weighted_expert_sum`'s rule over the slots whose place is below `n_card`, the plain sum's own expression, order and contraction, so with every slot on the card the two are bit for bit equal; a place at HOST is skipped with its weight and down row unread, and a place in `[n_card, HOST)` raises `FaultSite::ExpertId` and NaNs every value of its token. elem.rs splits `weighted_expert_sum`'s loop into `weighted_expert_sum_keep` (`#[inline(always)]`, a keep predicate the plain sum holds always true), so the two entries cannot drift apart; `weighted_sum`'s PTX does not move (ptx-compare vs ce1c310: added exactly the two entries, nothing changed). Gates: gate_deepseek41_prefill's raise sites gain the 9 case (past ids at slots 4 and 8); the refused counts become 5, 7 and 11 — PIN(2026-10-16): 9 became a built count. gate_hybrid's refusal arm holds the combine: every slot a card slot == `weighted_sum` bit for bit; HOST slots (their down rows NaN, unread by the contract) against the fused host transcription — the device compiles both kernels' `acc += w*down` to an fma, measured (the plain mul-then-add transcription failed the first run); a place in `[n_card, HOST)` raises the layer's ExpertId and NaNs exactly its token. ptx-shapes.tsv pins both entries 0/0 (FAIL-first: unpinned red on exactly them, then green 334/334 and 267/267); the unsafe ratchet rises by the five new blocks and `weighted_expert_sum_keep` (PIN in tools/unsafe-ratchet.txt). Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Verdict: MUST_FIX: The card combine duplicates existing owners, and removed refusal cases lack a dated reason.
Must fix
1. Extend the existing card-combine owner
crates/gpu/src/elem.rs:1298 repeats crates/gpu/src/card_slots.rs:330: ascending FMA over card slots, unread HOST terms, and ExpertId plus token NaNs for invalid places. Its new launcher also repeats the existing CardAcc interface and validation (R14, R8).
Only the gate calls the new API, so consolidating it now avoids migrating engine callers later.
Add Nine to CardSlots and its of/n/entry/refusal/launcher dispatch. Remove weighted_sum_card, enqueue_weighted_sum_card and weighted_expert_sum_keep; restore weighted_expert_sum's original body. Add this entry in card_slots_kernels:
/// Sum the card's nine routed slots for each output value.
#[allow(clippy::too_many_arguments,
reason = "kernel entry: flat device ABI (R8)")]
#[kernel]
#[launch_bounds(256)]
#[launch_contract(
domain = 1, block = (256, 1, 1),
requires = (
w_pitch >= 9, down.len() >= 9 * n * m,
w.len() >= w_pitch * m, sel.len() >= 9 * m,
acc.len() >= n * m
)
)]
pub fn ds41_ffn_card_acc_9(
down: &[f32], w: &[f32], sel: &[u32],
n: u32, m: u32, n_card: u32, w_pitch: u32,
fault: FaultSink, mut acc: DisjointSlice<f32>,
) {
let i = thread::index_1d().get();
if i >= n as usize * m as usize { return; }
// SAFETY: i < n*m; the launch contract bounds nine slots,
// their down rows and weights at w_pitch >= 9.
let v = unsafe {
card_acc_at::<9>(
down, w, sel, n as usize, n_card,
w_pitch as usize, fault, i,
)
};
// SAFETY: i < n*m <= acc.len(); thread i alone writes acc[i].
unsafe { *acc.get_unchecked_mut(i) = v };
}The new dispatch arm uses the existing cfg, n, m, n_card and w_pitch:
CardSlots::Nine => {
let prep = mo.prepare_ds41_ffn_card_acc_9(cfg)?;
mo.ds41_ffn_card_acc_9(
stream, &prep, a.down, a.w, a.sel, n, m,
n_card, w_pitch, a.fault, acc,
)?;
}Load CardSlotKernels once in the gate. Replace its four combine calls with enqueue_card_acc and CardAcc; for the first call:
let slots = bloomery_gpu::card_slots::CardSlotKernels::load(gpu.context())?;
slots.enqueue_card_acc(stream, &bloomery_gpu::card_slots::CardAcc {
down: &down_dev, w: &w_dev, sel: &sel_dev,
n: rows, m: M, n_card: n_card as usize,
n_used: E, w_pitch: E, fault: gpu.layer_sink(R_LAYER)?,
}, &mut card)?;This deletes the second launcher, predicate helper and fault/filter implementation. Recheck unchanged entries' PTX and the new entry's gates.
2. Reuse the host combine oracle
crates/gpu-gates/src/bin/gate_hybrid.rs:1383 repeats crates/runtime/src/combine.rs:62 (R14). Both own the same filter and ascending fused sum.
Using the owner now prevents the gate oracle from drifting when that contract changes. Replace sum_over:
let sum_over = |down: &[f32], sel: &[u32], t: usize, d: usize| {
runtime::combine::card_sum::<E>(
std::array::from_fn(|e| down[(t * E + e) * rows + d]),
std::array::from_fn(|e| w[t * E + e]),
std::array::from_fn(|e| sel[t * E + e] < n_card),
)
};3. Date the removed refusal clauses
crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs:1344 and line 1384 remove the nine-slot refusal cases without the required dated reason.
Record the contract change now while its replacement coverage is in this diff. Add before the first changed refusal list:
// PIN(2026-10-16): handoff8/10 stop refusing 9; the built nine-slot entry is checked by handoff9_cases.Non-blocking
⚠ Exercise the first invalid place: crates/gpu-gates/src/bin/gate_hybrid.rs:1489 uses n_card + 3. No new input equals n_card, so the production mutant place <= n_card passes every assertion. Covering this boundary now closes that gap with one line:
sel_bad[E + 6] = n_card;Checked
Duplicates: 9 new named functions/constants checked; two dryer pairs read, both necessary entry wrappers over handoff_at. Other duplicates are listed above.
Complexity: refusal_arm 65→108 adds a combine stage; enqueue_handoff 22→26 adds one dispatch arm. Neither count alone is a finding.
Silent failure: 3 paths followed; bad ids raise ExpertId, HOST terms are skipped, invalid places raise ExpertId and NaN the token.
Tests: restoring nine-slot refusal or leaving past ids as places fails assertions. HOST summing, reversed order and silent invalid-place skipping have reported killed mutants; the boundary mutant survives.
Gates: unsafe ratchet has a dated PIN; removed refusal clauses need one.
Escapes: no catalog pattern matched. Hot path class: add, no engine caller; no added decode launches or allocations.
Notes
Static review only; GPU gates were not run here. The PR reports card/driver and gate results but omits nvidia-smi output and the model file from the required evidence list.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs, crates/gpu-gates/src/bin/gate_hybrid.rs, crates/gpu/src/elem.rs … and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.
🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)
| [0, 3, 5, past, 9, 12, 300, past + 616], | ||
| [0.25, 0.125, 0.25, 0.125, 0.0625, 0.0625, 0.0625, 0.0625], | ||
| &[5, 7, 9], | ||
| &[5, 7], |
There was a problem hiding this comment.
Date why handoff8/10 remove the nine-slot refusal cases.
| &[5, 7], | |
| // PIN(2026-10-16): handoff8/10 stop refusing 9; the built nine-slot entry is checked by handoff9_cases. | |
| &[5, 7], |
| // every value NaN, the others the transcription. | ||
| gpu.clear_fault()?; | ||
| let mut sel_bad = sel_h.clone(); | ||
| sel_bad[E + 6] = n_card + 3; |
There was a problem hiding this comment.
Cover the first invalid place so changing the production comparison to <= fails this clause.
| sel_bad[E + 6] = n_card + 3; | |
| sel_bad[E + 6] = n_card; |
The PR 343 review: a second card combine in elem.rs duplicates the card slots' family owner. `CardSlots::Nine` now picks `ds41_ffn_card_acc_9` (`card_acc_at`'s contract at nine slots) through `enqueue_card_acc`'s existing `CardAcc` validation; `weighted_sum_card`, `enqueue_weighted_sum_card` and the `weighted_expert_sum_keep` split are deleted and `weighted_expert_sum` keeps its original body, so elem.rs is byte for byte the base again. gate_hybrid's combine clauses call `CardSlotKernels`/`CardAcc` and judge against the shared oracle `runtime::combine::card_sum` (the hand transcription deleted); the stray place is now `n_card` itself, the first value in `[n_card, HOST)`, so the `place <= n_card` mutant fails the clause. gate_deepseek41_prefill's handoff8/10 refusal lists keep the dated reason for the nine-slot cases they stopped refusing. ptx-shapes: `weighted_sum_card`'s rows out, `ds41_ffn_card_acc_9` in at 0/0 (FAIL-first red on exactly the two rows at a wrong pin); unsafe ratchet gpu 1874 -> 1872 blocks, 204 -> 203 fns. Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Since the last review:
- Existing combine owner: fixed at crates/gpu/src/card_slots.rs:339.
- Host combine oracle: fixed at crates/gpu-gates/src/bin/gate_hybrid.rs:1388.
- Dated refusal reason: fixed at crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs:1344.
- First invalid place: fixed at crates/gpu-gates/src/bin/gate_hybrid.rs:1479.
Verdict: MUST_FIX: The prefill gate still expects nine-slot card sums to be unsupported.
Must fix
1. Update the prefill gate's unsupported slot counts
crates/gpu/src/card_slots.rs:72 accepts nine slots. The existing sum refusal case still tests 9 through FfnBatchKernels, which delegates to this owner. Its down buffer has 7,200 values; nine slots require 8,100. The result is a buffer error named ds41_ffn_card_acc_9, so refused_by_name returns false and just gate-gpu-ds41-prefill fails.
Updating the caller now avoids shipping a failing verification path.
Replace the sum refusal loop header at line 1618 with:
// PIN(2026-10-16): nine-slot sums are covered by the card_slots gate; 11 remains unsupported.
for n_used in [5, 7, 11] {Replace its description at line 1527 with:
/// - the sum refuses 5, 7 and 11 slots; the gather refuses 5, 7 and 9,
/// by name, nothing written;
Rerun just gate-gpu-ds41-prefill.
Non-blocking
⚠ Refresh the replacement kernel's evidence: crates/gpu/src/card_slots.rs:339 replaces weighted_sum_card, but the PR body reports runs at the earlier head with that deleted entry.
Attach the add/delete-class PTX comparison, spill gate FAIL-first, and current gate-gpu-lib, gate-gpu-hybrid and gate-gpu-ds41-prefill output.
Checked
Duplicates: the nine-slot entry reuses card_acc_at; the hybrid gate now uses runtime::combine::card_sum.
Complexity: the new entry delegates to the shared core; the launcher adds one dispatch arm.
Silent failure: empty extents and short buffers return shape errors; HOST terms stay unread; invalid places raise ExpertId and NaN their token.
Tests: source trace confirms the stale nine-slot refusal fails. The hardware test includes nine slots and checks HOST skipping, invalid-place faults and empty-card sums.
Gates: the handoff refusal reason has its PIN; the unsafe ratchet decreases with a PIN. No numeric band moves.
Escapes: no catalog pattern matched. The new entry has no engine caller; no decode launches, copies or allocations are added.
Notes
Static validation; GPU gates were not run here. The evidence also lacks the required nvidia-smi output and model file.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs, crates/gpu-gates/src/bin/gate_hybrid.rs, crates/gpu/src/card_slots.rs … and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.
🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)
The nine-slot entry is built, so the clause that refused 9 through CardSlots now refuses only 5 and 7, with the dated reason; the nine-slot entry itself is checked by gate_hybrid combine clauses and gate-gpu-lib places test. The gather clause keeps refusing 9: its family has no nine-slot entry. Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Since the last review:
- Unsupported-count gate: fixed at crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs:1621.
Verdict: CLEAN: This increment removes the obsolete nine-slot refusal and records the dated reason.
Checked
Duplicates: no new functions, types or constants in this increment.
Complexity: the existing refusal loop loses one case; no new branching.
Silent failure: counts 5 and 7 return named Shape errors before launch; the gate checks refusal and untouched output.
Tests: static mutation reasoning at crates/gpu/src/card_slots.rs:74 shows accepting 7 as Six fails the refusal check. Removing Nine at line 72 makes the existing hybrid gate's nine-slot launch error.
Gates: the removed refusal has PIN(2026-10-16) and a reason. Existing hybrid and library gates check nine-slot success, HOST skipping and invalid-place faults. No numeric bands change.
Escapes: no catalog pattern matched. No ledger lessons are in force. This increment changes gate code only.
Notes
Static validation only. GPU gates and mutations were not executed.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_deepseek41_prefill.rs, crates/gpu-gates/src/bin/gate_hybrid.rs, crates/gpu/src/card_slots.rs … and carries no gate run on a card (CONTRIBUTING's evidence list); a maintainer adds gpu-verified after one.
🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)
|
Superseded by #391 (the same review-fixed content rebased onto origin/main; the only conflict was tools/unsafe-ratchet.txt, resolved by keeping main's PIN lines and adding one PIN(2026-10-17) for our measured delta). All five owning gates re-ran green there through --round-ledger; ptx-compare against origin/main is added-only (ds41_ffn_card_acc_9 + ds41_ffn_handoff_9). This comment was written by a bot (GLM-5.3 agent in the Claude Code harness) under the lead's direction. 🤖 Generated with Claude Code |
|
Superseded by #391 (merged). Written by a bot (Claude agent) for the maintainer. |
What
The host tier's nine-slot pieces for Bolt offload (B1 of #328's offload row):
HandoffSlots::Nineand theds41_ffn_handoff_9entry:handoff_at's contract at nine slots, wired throughenqueue_handoff; no_9_cols/_9_tier(Bolt's prompt uses the batch port, which needs no handoff launch).weighted_sum_card: the routed combine over the card's slots —weighted_expert_sum's rule over the slots whose placeselis belown_card. A place atHOSTis skipped with its weight and down row unread; a place in[n_card, HOST)raisesFaultSite::ExpertIdand NaNs every value of its token.weighted_expert_sum's loop is split intoweighted_expert_sum_keep(#[inline(always)], a keep predicate the plain sum holds always true) so the two entries cannot drift apart.enqueue_weighted_sum_cardbesideenqueue_weighted_sum.Gates:
gate_deepseek41_prefill's raise sites gain the 9 case (past ids at slots 4 and 8; the refused counts become 5, 7 and 11 — 9 became a built count).gate_hybrid's refusal arm holds the combine on synthetic inputs (it ownscard_sel, the places writer): all-card places ==weighted_sumbit for bit; HOST slots (their down rows NaN, unread by the contract) against the fused host transcription; a place in[n_card, HOST)faults and NaNs exactly its token. Measured: the device compiles both kernels'acc += w*downto an fma — the plain mul-then-add transcription failed the first run, the fused one is bit for bit.Add-class proof
just ptx-compare ce1c310ff gate_e2e→ rc 0 (job s1840) andjust ptx-compare ce1c310ff generate_ds41 --features gpu,deepseek41→ added-only (rc 0):added 2: ds41_ffn_handoff_9 weighted_sum_card,removed none,changed none—weighted_sum's PTX does not move.just gate-ptx-spillFAIL-first:generate_ds41 ds41_ffn_handoff_9 unpinned spill=0 jit_local=0+weighted_sum_card unpinned(334 entries, 2 violations, FAIL) → pins 0/0 intools/ref/ptx-shapes.tsv→entries=334 pinned=334 violations=0 PASS,gate_e2e entries=267 pinned=267 violations=0 PASS.weighted_expert_sum_keep), dated line intools/unsafe-ratchet.txt.GPU Evidence
ws box, NVIDIA GeForce RTX 3090 (sm_86), driver 615.71.09, CUDA 13.4 (JIT cc 8.6). Base ce1c310, head 65c396b (= this PR). All runs through the box queue, lane 3090 (s1840 started before the
any-lane note; later jobsany):gate-gpu-libjob s1787 —gate-gpu-lib rc=0 251s try=1 lane=A tier=realgate-gpu-ds41-prefilljob s1791 —gate-gpu-ds41-prefill rc=0 839s try=1 lane=A tier=real(handoff9 clauses PASS: places/image PASS at inside and past ids; refuse 5/7/11 by name)gate-gpu-hybridjob s1814 —refusal weighted_sum_card every slot a card slot: == weighted_sum bits true, rerun identical true, word clean PASS/HOST slots skipped, their rows unread (NaN): == the host transcription bits PASS/a place in [n_card, HOST): token NaN true, other tokens the transcription true, word "layer 2 site expert_id" PASS;refusal verdict PASSgate-gpu-moejob s1811 —PASSED: gate_moe_fused fused 4-launch MoE routed half bit-identical to the 8-launch op path (h, Q8Blocks32, down, y, reruns, graph replays)gate-ptx-spilljob s1779 — lines above.Mutants
tools/mutant-run.sh(logs kept by the round):keep-host(HOST terms summed → the NaN-rows clause),order-desc(descending order → the transcription clause; the all-card identity clause stays PASS, as designed),skip-not-fault([n_card, HOST)skipped silently → the word/token clause).mutant-run: 3 mutants, 3 killed, 0 survived — PASS.place-id(a past id's place left as the id → the handoff9 places check):mutant-run: 1 mutants, 1 killed, 0 survived — PASS.GPU Evidence (review fix, 2026-10-17)
ws box, NVIDIA GeForce RTX 3090 + RTX A6000 (sm_86), driver 615.71.09, CUDA 13.4 (JIT cc 8.6), ptxas 13.3.73. Base ce1c310, head 570ddb7 (= this PR after the review fix; commits 3054319 + 570ddb7 on the first-push 65c396b). All runs through the box queue, lane
any.ptx-spill FAIL-first, then green. The two new
ds41_ffn_card_acc_9rows pinned 4/4 first:pinned to the measured 0/0, rerun:
ptx-spill bin=generate_ds41 entries=334 violations=0 PASSandptx-spill bin=gate_e2e entries=267 violations=0 PASS. (The two spill jobs' attach ids were rotated by the queue daemon; the outputs above are verbatim from the runs' logs.)Add-class proof,
just ptx-compare ce1c310ff(job s2275 = gate_e2e, s2283 = generate_ds41--features gpu,deepseek41; s2266 the base-side build), both rc 0:weighted_sum_card(added by the first push, removed by the review fix) nets out of the table; nothing existing moved.Gates. job s2286
gate-gpu-hybridexit 0 — the reworked clauses:job s2301
gate-gpu-ds41-prefillexit 0 (the clause whose 9-refusal the fix removed went FAIL-first on the first run — job s2290,card_acc of 9 slots: refused (ds41_ffn_card_acc_9: down holds 7200 words, 8100 needed); sums untouched true: FAIL— then[5, 7]+ the dated reason):job s2295
gate-gpu-libexit 0 (the card-slots places test now loops SLOTS_9); job s2297gate-gpu-moeexit 0.Mutants (
tools/mutant-run.sh --clean once, jobs s2336–s2377 = the four card_acc mutants + clean, s2310/s2321 = the handoff mutant + clean), every mutant killed by exactly its own clause, clean runs green:The review's surviving
place <= n_cardmutant is dead (thesel_bad[E + 6] = n_cardclause kills it).This PR was written by a bot (GLM-5.3 agent in the Claude Code harness) under the lead's direction.
🤖 Generated with Claude Code