Repository navigation
Conversation
There was a problem hiding this comment.
Verdict: MUST_FIX: Remove the redundant constructor layer.
Must fix
1. Keep one constructor for explicit leg arms
crates/gpu/src/card_leg.rs:594 Kind B, fewest elements: of_arms forwards all four arguments unchanged to with_arms. The two functions implement one operation with no separate contract.
Collapsing them now removes a name before more callers adopt it. Replace both definitions with this definition, keep the public constructor's documentation, and change the three internal LegStacks::with_arms calls to LegStacks::of_arms.
pub fn of_arms(
w: &'a Weights,
names: [&'a str; 3],
arms: LegArms,
roles: (&'static str, &'static str),
) -> Result<LegStacks<'a>, GpuError> {
let [gate, up, down] = names;
let (gate, up, down) = (
LegStack::of(w, gate, arms.gate_up, kernels::card_planes_runs, roles.0)?,
LegStack::of(w, up, arms.gate_up, kernels::card_planes_runs, roles.0)?,
LegStack::of(w, down, arms.down, kernels::card_planes_runs, roles.1)?,
);
if up.ty != gate.ty {
return Err(GpuError::Tensor {
what: WHAT,
name: up.name.to_owned(),
need: "the gate stack's type",
});
}
Ok(LegStacks { gate, up, down })
}Non-blocking
⚠ Supply decode and prefill timing evidence: crates/gpu/src/arch/qwen3moe/placed.rs:1633.
Each newly carded common layer adds four expert-path launches per decode token: 4 × newly carded common layers (input quantization, gate/up, hidden quantization, down). Wide prompts move host arithmetic to routed GEMMs.
The float sum order/precision class requires the owning gate and a timed A/B. Attach same-lease decode and prefill results on the contributor's card; the PR explicitly postpones timing.
Checked
- Duplicates/elements: read both constructor definitions and all call sites. Collapsing them removes one function. Dryer reports zero pairs and excludes gpu/gpu-gates.
- Complexity: CardLeg::launch and shadow add quant and leg dispatch branches, consistent with the diagnostics' reported growth.
- Silent failure: the constructor propagates stack errors and rejects mismatched gate/up types; the proposed replacement preserves both checks.
- Tests: inspected the Q8_0/Q6_K hand-launch comparison and the placed-load gate. Runtime gates were not rerun.
- Gates: the raised unsafe and model-tax limits have dated PIN reasons.
- Escape catalog: C1–C4 do not match the cited constructor or dispatch changes.
Notes
Static validation only. The PR body lacks the nvidia-smi line, both tested commit hashes, exact model paths and gate output required for card evidence. Its fixture summary reports one red item.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_qwen35moe_e2e.rs, crates/gpu-gates/src/record.rs, crates/gpu/src/arch/qwen3moe/body35.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)
|
Decode A/B, RTX 3090, one lease.
Both are inside the band, but below the derived ×1.4 and ×1.5. Two of the four Q8_0 rows carry |
There was a problem hiding this comment.
Verdict: MUST_FIX: two validation checks repeat existing owners, and the new route block carries an unused activation choice.
Must fix
1. Share the routed-stack shape check
crates/gpu/src/arch/qwen3moe/placed.rs:1235 repeats crates/gpu/src/arch/qwen3moe/body.rs:283: resident KQuant form, gate/up/down dimensions and expert-row counts (R14).
These memory-layout checks encode the same fact. Reusing the existing validator removes the repeated layout logic (kind B).
Make stack_files pub(super), then replace body::stack_tys with:
pub(super) fn stack_tys(
w: &Weights,
names: [&str; 3],
shape: (usize, usize, usize),
l: usize,
) -> Result<[SiteTy; 3], GpuError> {
let raw = super::placed::stack_files(w, names, shape, l)?;
let site = |i: usize| {
SiteTy::of_ggml(raw[i]).ok_or_else(|| {
GpuError::shape(
"qwen3moe::Body::load",
format!("{} is {}; no launch family reads it", names[i], raw[i]),
)
})
};
let tys = [site(0)?, site(1)?, site(2)?];
stack_entries(tys, l)?;
Ok(tys)
}2. Reuse the existing card-eligibility predicate
crates/placement/src/accepts.rs:212 repeats the gate/up equality and role checks owned by crates/placement/src/accepts.rs:394 (R14).
One owner avoids separate eligibility edits in the load and residency paths (kind B). Replace the classifier with:
pub fn qwen35_leg([gate, up, down]: [GgmlType; 3]) -> Option<LegSplit> {
if leg_runs(Program::Qwen35Body, [gate, up, down]) != Some(true) {
return None;
}
Some(if qwen35_gate_up(gate).is_some() && qwen35_down(down).is_some() {
LegSplit::Dispatch
} else {
LegSplit::Common
})
}3. Remove the unused activation-rule choice
crates/gpu/src/card_leg.rs:296 adds rule and alternative-rule dispatch. Its only constructor, crates/gpu/src/arch/qwen3moe/placed.rs:1685, always supplies Act::SiluMul. No second caller is added.
The fewest-elements contract makes this unused field and branch a kind B must-fix.
Delete RouteBlock::rule and its initializer. Replace the grouped SwiGLU call with:
gemm.enqueue_swiglu_quant(stream, g, u, n_slots, act, fault)?;Replace the entire match self.rule in the Blocks32 arm with:
g32.enqueue_swiglu_quant32(stream, g, u, n_slots, act, fault)?;Non-blocking
⚠ Timed proof is pending: crates/gpu/src/arch/qwen3moe/placed.rs:1633 runs four card-leg launches per common layer/token and changes host arithmetic to card q8_1 arithmetic. The float-precision change class requires its gate and timed A/B. Attach same-lease decode and prefill results on the contributor's card; the body defers them.
Optimization headroom
- G. Per-launch and per-sync fixed cost: crates/gpu/src/arch/qwen3moe/placed.rs:1633 quantizes normed rows again after
routealready produced q8_1. Reusing that result removes one launch per common layer/token.
Checked
Duplicates: both cited validation copies confirmed. Dryer reported zero pairs and excluded GPU files.
Elements: the new card_leg::RouteBlock has one constructor, always using Act::SiluMul; its replacement launchers exist.
Performance: traced route's q8_1 output and the common leg's four launches, including the repeated input quantization.
Inline: replacement verified against the added line and existing leg_runs implementation.
Tests: hardware tests not run. The PR body reports gates and FAIL-first mutants.
Escape catalog: no matching patterns.
Notes
The evidence lacks the nvidia-smi card/driver line and gate commands with output.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_qwen35moe_e2e.rs, crates/gpu-gates/src/record.rs, crates/gpu/src/arch/qwen3moe/body35.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)
| /// residency stack table and the placed side read. | ||
| #[must_use] | ||
| pub fn qwen35_leg([gate, up, down]: [GgmlType; 3]) -> Option<LegSplit> { | ||
| if gate != up || !prompt_leg_gate_up(gate) || !prompt_leg_down(down) { |
There was a problem hiding this comment.
This guard repeats leg_runs; reuse the existing card-eligibility predicate.
| if gate != up || !prompt_leg_gate_up(gate) || !prompt_leg_down(down) { | |
| if leg_runs(Program::Qwen35Body, [gate, up, down]) != Some(true) { |
|
The three must-fix items are in dc5e512: body::stack_tys reads its stacks through placed::stack_files, qwen35_leg reads leg_runs(Program::Qwen35Body, …), and RouteBlock drops its rule field (every caller ran SiluMul). Proof:
|
There was a problem hiding this comment.
Since the last review:
- Fixed: routed-stack shape checks now share
stack_files. - Fixed: card eligibility now reuses
leg_runs. - Fixed:
RouteBlockno longer carries an unused activation choice. - The earlier timed-proof question concerns code unchanged by this increment and is excluded under the incremental-review scope rule.
Verdict: CLEAN: the three blocking findings are fixed, and no must-fix finding remains in this increment.
Checked
Duplicates: no new definitions; both validation copies now reuse existing owners.
Complexity: RouteBlock::enqueue loses the activation-choice match. Its caller previously supplied Act::SiluMul; the selected launchers preserve that rule.
Silent failure: four paths followed: missing tensor, wrong shape, unsupported type and unequal gate/up. They return named errors or refuse card placement.
Tests: no tests changed. Source inspection shows that dropping gate/up equality from leg_runs would fail the existing classifier assertion at accepts.rs:594; the mutant was not run. Builds and hardware gates were not run.
Gates: no pins, thresholds or test cases changed in this increment.
Escape catalog: no C1–C4 pattern matched.
Notes
The PR body lacks the card/driver nvidia-smi line and gate commands with their output required for complete GPU evidence.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_qwen35moe_e2e.rs, crates/gpu-gates/src/record.rs, crates/gpu/src/arch/qwen3moe/body.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)
…(Q6_K, IQ3_XXS, IQ4_XS and Q8_0 gate·up; IQ3_XXS, IQ4_XS, Q5_1, Q8_0 and IQ4_NL down); the coverage pins and the host-only causes follow the table (#75) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_K gate·up arms; Body35's placed layers launch them (the common leg's plan rule still admits neither) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he common card leg; the dispatch's layers stay bit-identical Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…four fixture variants (q35iq4xs, q35q80, q35iq4q8, q35q6k) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gate_up, prompt_leg_down, LegSplit); only qwen35_leg names the family Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s Qwen35Body's own program rows, coverage.rs's comes down Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arms (with_arms folded in) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aced card leg (RTX 3090, ctx 262144) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
body::stack_tys reads its stacks through placed::stack_files, qwen35_leg reads leg_runs(Program::Qwen35Body, ...), and RouteBlock drops its rule field: every caller ran SiluMul. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Since the last review:
- Still fixed: routed-stack validation shares
stack_files. - Still fixed: card eligibility reuses
leg_runs. - Still fixed:
RouteBlockcarries no unused activation choice.
Verdict: CLEAN: the model-tax increase matches the source count and has a dated reason.
Checked
Duplicates: 0 new items; dryer reports 0 pairs. This increment changes one table row.
Complexity: no functions changed. The crapper results concern earlier commits.
Silent failure: 0 new sites; no runtime behavior changed.
Tests: no tests changed. Independent counting confirms 31 production lines matching the qwen token; the old allowance of 30 rejects the source. One extra matching line exceeds the new allowance. Full checks and hardware gates were not run.
Gates: tools/model-tax.tsv:169 rises from 30 to 31. Its PIN(2026-10-22): explains the shared-classifier call at accepts.rs:212; the count confirms the reason. The two-sided check still rejects both excess and unused allowance.
Escape catalog: no C1–C4 pattern matched.
Notes
GPU evidence remains incomplete: the supplied material lacks the card/driver nvidia-smi line and gate commands with their output required by CONTRIBUTING.md.
Card check: needs-gpu. This pull request changes crates/gpu-gates/src/bin/gate_qwen35moe_e2e.rs, crates/gpu-gates/src/record.rs, crates/gpu/src/arch/qwen3moe/body.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)
Part of #75. Qwen3.5/3.6-35B-A3B files with Q8_0, Q6_K, IQ3_XXS or IQ4_XS experts kept every routed expert on the host. The placed load now runs those layers on the common card leg, so a 24 GB card holds 44–57 % of the experts at the default context.
What changes:
accepts.rs: Body35's placed card leg takes the common leg's routed rows (gate·up Q6_K, IQ3_XXS, IQ4_XS, Q8_0; down IQ3_XXS, IQ4_XS, Q5_1, Q8_0, IQ4_NL). The common leg's prompt rows have their own names (prompt_leg_gate_up,prompt_leg_down,LegSplit).q6k_gate_up_sel) and the Q8_0 and Q6_K gate·up arms.Plan on the RTX 3090,
bloomery-serve --model qwen3 --plan,--placeunset [measured]:Predicted decode [derived from that plan, uniform routing, not timed]: Q8_0 ×1.4 at ctx 262144 and ×1.6 at 16384; UD-Q6_K ×1.5 and ×1.7. The timed A/B comes later on this PR.
Evidence:
gate-gpu-qwen35moe-leg: the common-placed layers against the host path on the base fixture and four requantized variants (q35iq4xs,q35q80,q35iq4q8,q35q6k). The wide arm's error is 1.9e-2 to 2.3e-2 against the band 1e-1. The prompt call is bit-identical to the graph step on every load.just affected origin/mainon the fixture tier: 229 items, red 1 (qwen35moe-e2eunjoined variant: the card had 649 MB free from a co-tenant; rerun alone).gate-placement,gate-gpu-gates-lib,gate-gpu-qwen3moe-e2e,gate-gpu-qwen4exp-iqleg,gate-gpu-qwen3moe-down,gate-gpu-qwen38-residency,gate-gpu-qwen35moe-e2egreen (7, red 0).q6k_gate_up_sel(on top of gpu: make the partial head-256 cache append unsafe #612's 2101 → 2112);model-taxaccepts.rs qwen 26 → 30 (Body35's own program rows), coverage.rs 63 → 61. Each carries aPINline.Review fix:
LegStacks::with_armsis folded intoof_arms, so one constructor remains (beadc2e, host only).Cards: the maintainer's box, RTX 3090 and RTX A6000. The gates ran at 12f6953 on main 3938149, and at ade2c45 on main 1e8e923 for the rebase. The fixture tier reads the qwen35moe fixture and its requantized variants under
/models. The timed decode and prompt A/B follows on this PR.This work was written with AI help: a Claude subagent wrote the change, and Claude reviewed it and ran the gates.
🤖 Generated with Claude Code