Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion crates/gpu-gates/src/bin/gate_qwen3_serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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
Expand Down Expand Up @@ -1872,6 +1879,41 @@ 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, 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 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::<u32>().is_ok())
&& devices[1]["device"] == "CPU"
&& 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) {
Expand Down
24 changes: 21 additions & 3 deletions crates/gpu-gates/src/bin/shared/serve_seats/qwen3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -1443,6 +1443,24 @@ pub fn run(args: &[String]) -> Result<ServeError, GateError> {
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 {
Expand All @@ -1456,15 +1474,15 @@ pub fn run(args: &[String]) -> Result<ServeError, GateError> {
slot_ctx,
vocab,
device,
EngineProps::default(),
props,
0,
)?,
_ => SeatEngine::spawn(
move || Q3::<Body35>::open(&open, slot_ctx, slots, pass, load, &levers, (kv, vision)),
slot_ctx,
vocab,
device,
EngineProps::default(),
props,
0,
)?,
};
Expand Down
Loading