Skip to content

gpu: the host tier nine-slot pieces, handoff_9 and the card sum Nine entry (Bolt offload) - #391

Merged
midagedev merged 4 commits into
mainfrom
bolt-b1-handoff9-r3
Oct 17, 2026
Merged

midagedev merged 4 commits into
mainfrom
bolt-b1-handoff9-r3

Conversation

@midagedev

Copy link
Copy Markdown
Owner

Supersedes #343 (the same review-fixed content rebased onto origin/main; #343 conflicts with main's tools/unsafe-ratchet.txt, which moved gpu to 1896/206 — here main's PIN lines are kept and one PIN(2026-10-17) line carries our measured delta to 1899/206).

What

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). The nine-slot card combine is a row of the card slots' one family owner: CardSlots::Nine → ds41_ffn_card_acc_9 (card_acc_at::<9>) through enqueue_card_acc's existing CardAcc validation — per the #343 review, no second combine owner in elem.rs (weighted_sum_card, its launcher and the weighted_expert_sum_keep split are gone; elem.rs carries only main's own changes). gate_hybrid's combine clauses call CardSlotKernels/CardAcc and judge against the shared oracle runtime::combine::card_sum; the stray place is n_card itself, so the place <= n_card mutant fails the clause. The refusal lists that stopped refusing 9 (handoff8/10, the prefill card sum) carry PIN(2026-10-16) reasons.

Add-class proof

just ptx-compare ec48c9515 (origin/main → this PR), gate_e2e and generate_ds41 both rc 0, added-only: added 2: ds41_ffn_card_acc_9 ds41_ffn_handoff_9, removed none, changed none. ptx-shapes rows pinned 0/0 FAIL-first (red on exactly the two rows at a wrong pin, measured spill=0 jit_local=0). Unsafe ratchet: main's lines kept, one PIN(2026-10-17) line, gpu measured 1899 blocks / 206 fns.

GPU Evidence

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 ec48c95 (origin/main), head bolt-b1-handoff9-r3. Gates through tools/gate-batch.sh --round-ledger (lane A the 3090, lane B the A6000; jobs s2490, s2491, s2497, s2526, s2532), compares lane any (jobs s2537–s2546):

  • gate-ptx-spill rc 0 (228 s) — 340/273 entries, violations 0.
  • gate-gpu-ds41-prefill rc 0 (507 s).
  • gate-gpu-moe rc 0 (486 s).
  • gate-gpu-lib rc 0 (277 s); a first try timed out at the 900 s bound under card contention (job s2499) and counted red as a hung gate must — the rerun on a quiet card is the green above.
  • gate-gpu-hybrid rc 0 (164 s).

Mutants carry over from #343's head (card_acc_at and the combine clauses are byte-identical here; the rebase touched other lines): boundary / keep-host / order-desc / skip-not-fault each killed by exactly its own clause in gate-gpu-hybrid, the handoff place-id mutant by the 9-clause places check in gate-gpu-ds41-prefill, clean runs green.

Scope: just affected ec48c9515..HEAD selects 129 gates + 2 weekly; the five above ran, dated reasons (2026-10-17) for the rest: the only kernel-level change vs main is the two added entries with no engine caller, every other selected gate reaches it through an unchanged binary whose content main's landing ran green; the touched crate's lib gate ran here; the two weekly items stay with the weekly cadence.

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

midagedev and others added 3 commits October 17, 2026 10:38
…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>
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>
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>
@midagedev midagedev added needs-gpu Changes code a card must check, and carries no gate run on a card gpu The card engine: crates/gpu*, crates/app labels Oct 17, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: MUST_FIX: two new hybrid clauses duplicate contracts already covered by the card-slot library gate.

Must fix

1. Keep HOST and invalid-place checks in one gate

crates/gpu-gates/src/bin/gate_hybrid.rs:1447 repeats the HOST/NaN and invalid-place/fault checks in crates/gpu/src/card_slots.rs:706, whose loop this PR also extends to nine slots. Both call enqueue_card_acc directly; the hybrid clauses exercise no additional boundary interaction. This is kind B duplication under R14 and the one-test-per-contract rule.

Remove these copies now so later slot changes keep one contract owner. Preserve the distinct all-card comparison and rerun checks. Remove the unused card_sum import, replace the added module-doc paragraph with //! The nine-slot card combine matches weighted_sum bit for bit and reruns identically., and replace the added inner block and its preceding comment with:

// PIN(2026-10-17): remove duplicate HOST/invalid-place clauses;
// card_slots' library gate owns those contracts, including nine slots.
{
    const E: usize = 9;
    const M: usize = 3;
    let rows = R_HIDDEN;
    let w: Vec<f32> = (0..M * E)
        .map(|i| 0.05 + 0.04 * ((i / E + i % E) % 7) as f32)
        .collect();
    let val =
        |t: usize, e: usize, d: usize| ((t * 31 + e * 17 + d * 5) % 97) as f32 * 0.25 - 3.0;
    let down: Vec<f32> = (0..M * E)
        .flat_map(|i| (0..rows).map(move |d| val(i / E, i % E, d)))
        .collect();
    let sel: Vec<u32> = (0..M * E)
        .map(|i| ((i / E + i % E) % R_CARD) as u32)
        .collect();
    let down_dev = DeviceBuffer::from_host(stream, &down)?;
    let w_dev = DeviceBuffer::from_host(stream, &w)?;
    let sel_dev = DeviceBuffer::from_host(stream, &sel)?;
    let kernels = CardSlotKernels::load(gpu.context())?;
    let sum = |acc: &mut DeviceBuffer<f32>| {
        kernels.enqueue_card_acc(
            stream,
            &CardAcc {
                down: &down_dev,
                w: &w_dev,
                sel: &sel_dev,
                n: rows,
                m: M,
                n_card: R_CARD,
                n_used: E,
                w_pitch: E,
                fault: gpu.layer_sink(R_LAYER)?,
            },
            acc,
        )
    };
    gpu.clear_fault()?;
    let mut full = DeviceBuffer::<f32>::zeroed(stream, rows * M)?;
    let mut card = DeviceBuffer::<f32>::zeroed(stream, rows * M)?;
    gpu.elem()
        .enqueue_weighted_sum(stream, &down_dev, &w_dev, rows, E as u32, M, &mut full)?;
    sum(&mut card)?;
    stream.synchronize()?;
    let full_y = full.to_host_vec(stream)?;
    let card_y = card.to_host_vec(stream)?;
    sum(&mut card)?;
    stream.synchronize()?;
    let rerun = bits_equal(&card_y, &card.to_host_vec(stream)?);
    let same = bits_equal(&full_y, &card_y);
    let pass = same && rerun && gpu.take_fault()?.is_none();
    println!(
        "refusal card_acc_9: weighted_sum bits {same}, rerun {rerun}: {}",
        verdict(pass)
    );
    ok &= pass;
}

Checked

Duplicates: the HOST and invalid-place clauses use the same launcher and oracle as the library gate. The replacement removes 86 lines and adds no owner.

Complexity: refusal_arm gains three combine clauses. enqueue_handoff and enqueue_card_acc gain dispatch arms through their existing validation.

Silent failure: card_acc_at marks invalid places with NaNs and raises ExpertId. No new swallowed-error defaults appear in the diff.

Tests: library assertions cover nine slots, HOST rows containing NaNs, invalid places at n_card and HOST - 1, the fault site/layer, and unaffected tokens. CUDA gates were not run in this review.

Gates: refusal-list changes and the unsafe ratchet have dated PIN reasons. The PR reports FAIL-first checks for the new PTX rows and runtime clauses.

Escape catalog: no C1–C4 shell patterns match this diff.

Notes

GPU evidence is incomplete: the body names a head branch instead of a commit hash and supplies gate summaries without raw command output or the model path. gpu.json records false.

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 HOST/NaN and invalid-place clauses duplicate the card-slot library
gate's contracts (R14, one test per contract); card_slots' hw test covers
nine slots, HOST rows holding NaN, invalid places at n_card and HOST - 1,
the fault site and the unaffected tokens. The clause that stays is the
distinct one: with every place a card slot the nine-slot entry equals
weighted_sum bit for bit and reruns identically.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the last review: must-fix 1 is fixed. The duplicate HOST and invalid-place clauses are removed; the all-card comparison and rerun checks remain at crates/gpu-gates/src/bin/gate_hybrid.rs:1349.

Verdict: CLEAN: the incremental change resolves the earlier finding and preserves its required coverage.

Checked

Duplicates: 0 new functions, types or constants. All six dryer pairs read: four kernel-wrapper pairs already use shared cores; two name mappings concern different enums. These pairs are unchanged since the previous review.

Complexity: refusal_arm loses two clauses. The diagnostic growth in enqueue_handoff and enqueue_card_acc is dispatch-arm growth already reviewed; neither launcher changes this round.

Silent failure: 0 new suppression sites. The rewritten launch closure propagates errors with ?; comparison failures accumulate into the gate's error result.

Tests: omitting slot 8 from the loop at crates/gpu/src/card_slots.rs:391 makes the retained weighted_sum comparison fail. Changing place < n_card to <= fails the library gate's fault assertion. The library gate includes nine slots, HOST rows containing NaNs, both invalid-place boundaries and unaffected tokens. Its recipe includes ignored tests. Mutation checks were static; CUDA gates were not run here.

Gates: the removed clauses have a dated PIN reason and retain coverage in the library gate. No thresholds move.

Escape catalog: no C1–C4 patterns match. The incremental change affects gate setup only; it adds no engine hot-path work.

Notes

GPU evidence remains incomplete: the body names a head branch instead of a commit hash and supplies gate summaries without command output or the model path. gpu.json records false.

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)

@midagedev
midagedev merged commit 7cc066d into main Oct 17, 2026
6 checks passed
@midagedev

Copy link
Copy Markdown
Owner Author

Review fix applied as written in fdc5111 (the two duplicate clauses removed, the all-card comparison kept, the card_sum import, module-doc line and the PIN(2026-10-17) comment replaced with the review's). Reruns: gate-gpu-hybrid real tier rc 0, 46 s (job s2594; the fixture tier defers it as a real-file recipe), gate-gpu-lib fixture tier rc 0, 19 s (job s2590), both --round-ledger.

Mutant coverage moved to the library gate, shown on gate-gpu-lib against card_acc_at (jobs s2652, s2659): both place <= n_card (boundary) and place < n_card || place == HOST (keep-host) end with card_slots::tests::hw_a_place_between_the_card_and_the_host_faults_the_sum ... FAILED and 272 passed; 1 failed — the clause the review named as the owner. Caveat, stated plainly: the runner's final clean run did not complete green in either attempt — one red on the unrelated card-room hw test (hw_a_held_card_leaves_the_room_its_open_reads, a negative room delta with the card shared by the release sitting, s2641) and one timeout at the 900 s bound under the same load (s2667) — so the runner prints no kill above can be read pending one green clean run; that run is queued for the quiet window and will be appended here. The tree content itself is lib-green in the quiet windows (s2590, and the merged batch runs).

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

@midagedev

Copy link
Copy Markdown
Owner Author

Appendix (third attempt, jobs s2677-era): the two kills reproduce exactly as above (both end on hw_a_place_between_the_card_and_the_host_faults_the_sum ... FAILED); the clean run again reached the 900 s bound under the release sitting's load. The completing green clean run is one just gate-gpu-lib away in the post-sitting quiet window and will be appended then; the merged content's lib green in a quiet window is already on record (s2590, fixture tier, 19 s).

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gpu The card engine: crates/gpu*, crates/app needs-gpu Changes code a card must check, and carries no gate run on a card

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant