From df2a360083bbf5f4f6e3343f66fade4e7df7c725 Mon Sep 17 00:00:00 2001 From: midagedev Date: Thu, 15 Oct 2026 08:39:25 +0900 Subject: [PATCH 1/2] gpu-gates: the qwen3 seat reports its plan's placement in /props The qwen3 seat, which also serves qwen35moe files (Qwen3.6, MiniCPM-V 4.7), passed an empty engine block to /props, so a client such as toktape saw no placement: a 3060 tape of MiniCPM-V 4.7, with 6,105 experts on the host, recorded `placement.devices` as null. The V4.1, GLM, MiMo and Qwen3.8 seats already report it through bind::placement_of. Now a placed load reports the plan its open makes, from the same plan and levers: the card, then the host, each with its bytes by class. A whole-card load opens with no plan, so it reports no placement and its stderr says why. gate_qwen3_serve's slots arms check it: `placed_props_engine_placement_is_the_plans` (two devices, GPU then CPU, each device's bytes its classes' sum, routed experts on the host exactly when the plan record's host_experts is not 0), and `props_engine_whole_load_names_no_placement` on the whole-card arm. Co-Authored-By: Claude Opus 5.5 --- crates/gpu-gates/src/bin/gate_qwen3_serve.rs | 53 ++++++++++++++++++- .../src/bin/shared/serve_seats/qwen3.rs | 24 +++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/crates/gpu-gates/src/bin/gate_qwen3_serve.rs b/crates/gpu-gates/src/bin/gate_qwen3_serve.rs index 75541df9c..4de05519f 100644 --- a/crates/gpu-gates/src/bin/gate_qwen3_serve.rs +++ b/crates/gpu-gates/src/bin/gate_qwen3_serve.rs @@ -129,7 +129,14 @@ //! out holds the second slot's fixed stores past the plan's count — the //! open refuses by name and the placed qwen35moe server never listens //! (`placed_slots_load_names_the_split` red); one counted for every slot -//! names twice the planes and the clause is red. `slots_count_their_checkpoints` +//! names twice the planes and the clause is red. +//! `placed_props_engine_placement_is_the_plans`: the placed arm's `/props` +//! `engine.placement` is its plan's — the card, then the host, each device's +//! bytes its classes' sum, routed experts on the host exactly when the plan +//! record's `host_experts` is not 0; `props_engine_whole_load_names_no_placement`: +//! the whole-card arm opens with no plan, so it reports none and its line +//! says why. FAIL-first: a seat that reports no placement is red on the +//! placed arm. `slots_count_their_checkpoints` //! reads both servers' stderr: a qwen35moe file's two sequences each pin //! up to the body's budget at the slot's context of checkpoints on the host, and //! the seat's `checkpoints:` line names two sequences and twice the budget @@ -1872,6 +1879,50 @@ mod gate { &named("props_names_the_slot_ctx"), total.is_some_and(|t| n_ctx == t / 2), ); + // `/props`' placement is the plan's when the load placed one (its plan record printed): the + // card, then the host, each device's bytes its classes' sum, and routed experts on the host + // exactly when the record puts them there. A whole-card load has no plan: no placement, and + // the seat's line says why. + let placement = &props["engine"]["placement"]; + match plan.as_ref().and_then(Option::as_ref) { + Some(rec) => { + let devices = placement["devices"].as_array().cloned().unwrap_or_default(); + let summed = |d: &Value| { + d["classes"] + .as_object() + .map(|c| c.values().filter_map(|b| b.as_u64()).sum::()) + }; + let host_experts = devices + .get(1) + .and_then(|d| d["classes"]["experts"].as_u64()) + .unwrap_or(0); + println!("{}: props placement {placement}", arm.dir); + check( + ok, + &named("props_engine_placement_is_the_plans"), + devices.len() == 2 + && devices[0]["device"] + .as_str() + .and_then(|d| d.strip_prefix("GPU")) + .is_some_and(|n| n.parse::().is_ok()) + && devices[1]["device"] == "CPU" + && devices.iter().all(|d| { + d["bytes"].as_u64().is_some() && d["bytes"].as_u64() == summed(d) + }) + && devices[0]["bytes"].as_u64().is_some_and(|b| b > 0) + && u64_of(Some(rec), "host_experts") + .is_some_and(|h| (h > 0) == (host_experts > 0)), + ); + } + None => check( + ok, + &named("props_engine_whole_load_names_no_placement"), + placement.is_null() + && log.contains( + "/props leaves the placement out: a whole-card load opens with no plan", + ), + ), + } // The whole arm's set total is its whole-fit verdict's, held by the // two slots' planes; the placed arm's is the plan's. if let (Total::Set, Some(t)) = (arm.total, total) { diff --git a/crates/gpu-gates/src/bin/shared/serve_seats/qwen3.rs b/crates/gpu-gates/src/bin/shared/serve_seats/qwen3.rs index e8544f0c2..8a80c8709 100644 --- a/crates/gpu-gates/src/bin/shared/serve_seats/qwen3.rs +++ b/crates/gpu-gates/src/bin/shared/serve_seats/qwen3.rs @@ -182,7 +182,7 @@ use bloomery_gpu::model::{GpuModel, MAX_PASS_ROWS, Slots, StepMode}; use bloomery_gpu::{Gpu, Qwen3moeModel}; use bloomery_gpu_gates::bind::{ ChatSurface, Listen, Pass, Seat, SeatEngine, SlotStep, Vocab, arm_screen, bind_server, - note_line, parallel_line, slots_given, + note_line, parallel_line, placement_of, slots_given, }; use bloomery_gpu_gates::generate::Place; use bloomery_gpu_gates::record::{self, Record}; @@ -1443,6 +1443,24 @@ pub fn run(args: &[String]) -> Result { load.print_plan(&levers, vision.as_ref())?; std::process::exit(0); } + // `/props`' placement: a placed load's plan, the one its open makes from the same plan and + // levers; a whole-card load opens with no plan, so it reports none and says so. + let placement = match &load { + Q3Load::Placed { q, total, .. } => { + let plan = q.plan(*total, &plan_levers)?; + placement_of(NAME, plan.machine, &plan) + } + Q3Load::Whole(_) => { + eprintln!( + "{NAME}: /props leaves the placement out: a whole-card load opens with no plan" + ); + None + } + }; + let props = EngineProps { + placement, + ..EngineProps::default() + }; drop(split); let open = path.clone(); let device = match &load { @@ -1456,7 +1474,7 @@ pub fn run(args: &[String]) -> Result { slot_ctx, vocab, device, - EngineProps::default(), + props, 0, )?, _ => SeatEngine::spawn( @@ -1464,7 +1482,7 @@ pub fn run(args: &[String]) -> Result { slot_ctx, vocab, device, - EngineProps::default(), + props, 0, )?, }; From 3c3c68335b81f4ace4e426d786cd5c6bff8f0e05 Mon Sep 17 00:00:00 2001 From: midagedev Date: Thu, 15 Oct 2026 10:06:49 +0900 Subject: [PATCH 2/2] gpu-gates: drop the qwen3 props byte-sum the serve API already pins The seat gate repeated the serializer's per-device class sum. The placement check keeps the card, the host, the card's bytes and the host experts. The byte-sum promise leaves the two comments. --- crates/gpu-gates/src/bin/gate_qwen3_serve.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/crates/gpu-gates/src/bin/gate_qwen3_serve.rs b/crates/gpu-gates/src/bin/gate_qwen3_serve.rs index 4de05519f..1cc25822e 100644 --- a/crates/gpu-gates/src/bin/gate_qwen3_serve.rs +++ b/crates/gpu-gates/src/bin/gate_qwen3_serve.rs @@ -131,9 +131,9 @@ //! (`placed_slots_load_names_the_split` red); one counted for every slot //! names twice the planes and the clause is red. //! `placed_props_engine_placement_is_the_plans`: the placed arm's `/props` -//! `engine.placement` is its plan's — the card, then the host, each device's -//! bytes its classes' sum, routed experts on the host exactly when the plan -//! record's `host_experts` is not 0; `props_engine_whole_load_names_no_placement`: +//! `engine.placement` is its plan's — the card, then the host, routed experts +//! on the host exactly when the plan record's `host_experts` is not 0; +//! `props_engine_whole_load_names_no_placement`: //! the whole-card arm opens with no plan, so it reports none and its line //! says why. FAIL-first: a seat that reports no placement is red on the //! placed arm. `slots_count_their_checkpoints` @@ -1880,18 +1880,12 @@ mod gate { total.is_some_and(|t| n_ctx == t / 2), ); // `/props`' placement is the plan's when the load placed one (its plan record printed): the - // card, then the host, each device's bytes its classes' sum, and routed experts on the host - // exactly when the record puts them there. A whole-card load has no plan: no placement, and - // the seat's line says why. + // card, then the host, and routed experts on the host exactly when the record puts them + // there. A whole-card load has no plan: no placement, and the seat's line says why. let placement = &props["engine"]["placement"]; match plan.as_ref().and_then(Option::as_ref) { Some(rec) => { let devices = placement["devices"].as_array().cloned().unwrap_or_default(); - let summed = |d: &Value| { - d["classes"] - .as_object() - .map(|c| c.values().filter_map(|b| b.as_u64()).sum::()) - }; let host_experts = devices .get(1) .and_then(|d| d["classes"]["experts"].as_u64()) @@ -1906,9 +1900,6 @@ mod gate { .and_then(|d| d.strip_prefix("GPU")) .is_some_and(|n| n.parse::().is_ok()) && devices[1]["device"] == "CPU" - && devices.iter().all(|d| { - d["bytes"].as_u64().is_some() && d["bytes"].as_u64() == summed(d) - }) && devices[0]["bytes"].as_u64().is_some_and(|b| b > 0) && u64_of(Some(rec), "host_experts") .is_some_and(|h| (h > 0) == (host_experts > 0)),