use super::{capacity_inputs, Qwen3MoeCudaModel, MIB};
use crate::infer::qwen3_moe_dispatch::gpu::{cpu_reference, gpu_logits, load_moe_layers};
use crate::infer::qwen3_moe_dispatch::qwen3_moe_shape;
const DEFAULT_MODEL_PATH: &str = "/home/noah/models/Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf";
const PROBE_TEXT: &str = "The history of the printing press begins in the fifteenth century, \
when Johannes Gutenberg combined movable metal type, oil-based ink and a wooden screw press \
into a system that could reproduce books quickly and cheaply. Within fifty years, presses \
operated in more than two hundred cities across Europe, and the number of books in \
circulation grew from thousands to millions, changing how ideas spread.";
const POSITIONS: usize = 64;
const EXACT_REFERENCE_COSINE_FLOOR: f32 = 0.9999;
fn model_path() -> String {
std::env::var("APR_QWEN3MOE_GGUF").unwrap_or_else(|_| DEFAULT_MODEL_PATH.to_string())
}
const CHAT_TURN_START: [u32; 3] = [151_644, 872, 198];
fn assert_parity_after(prefix: &[u32], label: &str) {
let path = model_path();
if !std::path::Path::new(&path).exists() {
eprintln!("SKIP: {path} is absent");
return;
}
let executor = crate::cuda_executor_or_skip!(0);
let mapped = crate::gguf::MappedGGUFModel::from_path(&path).expect("map the GGUF");
let model = crate::gguf::OwnedQuantizedModel::from_mapped(&mapped).expect("CPU model");
let shape = qwen3_moe_shape(&mapped).expect("MoE shape");
let layers = load_moe_layers(&mapped, model.config().num_layers).expect("MoE layers");
let text = mapped.model.encode(PROBE_TEXT).expect("tokenize");
let mut probe = prefix.to_vec();
probe.extend(text.iter().take(POSITIONS - prefix.len()));
assert_eq!(
probe.len(),
POSITIONS,
"the probe text must tokenize to >= {POSITIONS} tokens"
);
let mut gpu = match Qwen3MoeCudaModel::with_max_seq_len(
&model,
&layers,
shape,
mapped.data(),
executor,
POSITIONS + 2,
) {
Ok(g) => g,
Err(e @ crate::error::RealizarError::CapacityRefused(_)) => {
eprintln!("SKIP: {e}");
return;
},
Err(e) => panic!("build the CUDA model: {e}"),
};
let t0 = std::time::Instant::now();
let cpu = cpu_reference(&model, &layers, shape, mapped.data(), &probe).expect("CPU reference");
let cpu_ms = t0.elapsed().as_secs_f64() * 1e3;
let decode_token = crate::infer::argmax_u32(&cpu[POSITIONS - 1]);
let t1 = std::time::Instant::now();
let got = gpu_logits(&mut gpu, &probe, decode_token).expect("GPU forward");
let gpu_ms = t1.elapsed().as_secs_f64() * 1e3;
assert_eq!(got.len(), POSITIONS + 1);
assert_eq!(cpu.len(), POSITIONS + 1);
let mut argmax_mismatches = 0;
for (pos, (c, g)) in cpu.iter().zip(&got).enumerate() {
let cos = crate::infer::logits_cosine_similarity(c, g);
let (ca, ga) = (crate::infer::argmax_u32(c), crate::infer::argmax_u32(g));
if ca != ga {
argmax_mismatches += 1;
}
eprintln!("[qwen3moe {label}] pos {pos:2}: cosine {cos:.6} argmax cpu {ca} gpu {ga}");
}
let report = crate::infer::f2_multi_position_report(&cpu, &got);
eprintln!(
"[qwen3moe {label}] {} positions: min cosine (pos >= 1) {:.6}, argmax mismatches \
{argmax_mismatches}, CPU {cpu_ms:.0} ms, GPU {gpu_ms:.0} ms",
cpu.len(),
report.min_cosine_real
);
assert!(
report.accepted,
"[{label}] the runtime F2 rule rejects this GPU forward: {}",
crate::infer::f2_divergence_msg(&report, crate::infer::F2ProbePath::Serial)
);
assert_eq!(
argmax_mismatches, 0,
"[{label}] argmax must agree at every position"
);
for (pos, (c, g)) in cpu.iter().zip(&got).enumerate() {
let cos = crate::infer::logits_cosine_similarity(c, g);
assert!(
cos >= EXACT_REFERENCE_COSINE_FLOOR,
"[{label}] pos {pos}: cosine {cos:.6} < {EXACT_REFERENCE_COSINE_FLOOR} against the \
FP32-activation CPU reference"
);
}
}
#[test]
#[serial_test::serial]
fn qwen3moe_cuda_forward_matches_cpu_at_64_positions() {
assert_parity_after(&[], "e2e");
}
#[test]
#[serial_test::serial]
fn qwen3moe_cuda_forward_matches_cpu_after_a_chat_turn_start() {
assert_parity_after(&CHAT_TURN_START, "chat");
}
const WEIGHTS_30B_A3B: usize = (16788 + 492 + 243) * MIB;
#[test]
fn a_busy_discrete_card_is_refused_with_the_arithmetic() {
use crate::capacity::{plan, CapacityVerdict, DeviceMemory, RefusalKind};
let busy = DeviceMemory::Discrete {
free: 16_000 * MIB as u64,
total: 24_564 * MIB as u64,
};
let CapacityVerdict::Refused(r) = plan(&capacity_inputs(WEIGHTS_30B_A3B, 48, 512, 66, 0, busy))
else {
panic!("16000 MiB free cannot hold 17523 MiB of weights");
};
assert_eq!(r.kind, RefusalKind::CoTenant, "{}", r.reason);
for part in ["weights 17523 MiB", "against 16000 MiB free of 24564 MiB"] {
assert!(r.reason.contains(part), "missing {part:?} in: {}", r.reason);
}
let idle = DeviceMemory::Discrete {
free: 23_900 * MIB as u64,
total: 24_564 * MIB as u64,
};
assert!(matches!(
plan(&capacity_inputs(WEIGHTS_30B_A3B, 48, 512, 66, 0, idle)),
CapacityVerdict::Fits(_)
));
}
#[test]
fn unified_memory_is_budgeted_from_mem_available_less_the_headroom() {
use crate::capacity::{plan, CapacityVerdict, DeviceMemory};
let gx10 = DeviceMemory::Unified {
available: 92_443 * MIB as u64,
total: 122_502 * MIB as u64,
cuda_free: 16_056 * MIB as u64,
};
assert!(
matches!(
plan(&capacity_inputs(WEIGHTS_30B_A3B, 48, 512, 66, 0, gx10)),
CapacityVerdict::Fits(_)
),
"the gx10 measurement must fit"
);
let starved = DeviceMemory::Unified {
available: 30_000 * MIB as u64,
total: 122_502 * MIB as u64,
cuda_free: 16_056 * MIB as u64,
};
let CapacityVerdict::Refused(r) =
plan(&capacity_inputs(WEIGHTS_30B_A3B, 48, 512, 66, 0, starved))
else {
panic!("30000 MiB available less a 16384 MiB headroom cannot hold 17523 MiB");
};
assert!(r.reason.contains("MemAvailable 30000 MiB"), "{}", r.reason);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum RoutingFault {
WrongExpert,
DropTopExpert,
UniformWeights,
}
pub(super) fn inject(
fault: Option<RoutingFault>,
mut routes: Vec<(usize, f32)>,
num_experts: usize,
) -> Vec<(usize, f32)> {
let k = routes.len().max(1) as f32;
match fault {
None => {},
Some(RoutingFault::WrongExpert) => {
for r in &mut routes {
r.0 = (r.0 + 1) % num_experts;
}
},
Some(RoutingFault::DropTopExpert) => {
if let Some(top) = routes.first_mut() {
top.1 = 0.0;
}
},
Some(RoutingFault::UniformWeights) => {
for r in &mut routes {
r.1 = 1.0 / k;
}
},
}
routes
}
#[test]
#[serial_test::serial]
fn qwen3moe_parity_rejects_injected_routing_faults() {
let path = model_path();
if !std::path::Path::new(&path).exists() {
eprintln!("SKIP: {path} is absent");
return;
}
let executor = crate::cuda_executor_or_skip!(0);
let mapped = crate::gguf::MappedGGUFModel::from_path(&path).expect("map the GGUF");
let model = crate::gguf::OwnedQuantizedModel::from_mapped(&mapped).expect("CPU model");
let shape = qwen3_moe_shape(&mapped).expect("MoE shape");
let layers = load_moe_layers(&mapped, model.config().num_layers).expect("MoE layers");
let text = mapped.model.encode(PROBE_TEXT).expect("tokenize");
let mut probe = CHAT_TURN_START.to_vec();
probe.extend(text.iter().take(POSITIONS - CHAT_TURN_START.len()));
let mut gpu = match Qwen3MoeCudaModel::with_max_seq_len(
&model,
&layers,
shape,
mapped.data(),
executor,
POSITIONS + 2,
) {
Ok(g) => g,
Err(e @ crate::error::RealizarError::CapacityRefused(_)) => {
eprintln!("SKIP: {e}");
return;
},
Err(e) => panic!("build the CUDA model: {e}"),
};
let cpu = cpu_reference(&model, &layers, shape, mapped.data(), &probe).expect("CPU reference");
let decode_token = crate::infer::argmax_u32(&cpu[POSITIONS - 1]);
let mut verdicts = Vec::new();
for fault in [
None,
Some(RoutingFault::WrongExpert),
Some(RoutingFault::DropTopExpert),
Some(RoutingFault::UniformWeights),
] {
gpu.fault = fault;
let got = gpu_logits(&mut gpu, &probe, decode_token).expect("GPU forward");
let min_cos = cpu
.iter()
.zip(&got)
.map(|(c, g)| crate::infer::logits_cosine_similarity(c, g))
.fold(1.0f32, f32::min);
let mismatches = cpu
.iter()
.zip(&got)
.filter(|(c, g)| crate::infer::argmax_u32(c) != crate::infer::argmax_u32(g))
.count();
let exact_ok = min_cos >= EXACT_REFERENCE_COSINE_FLOOR && mismatches == 0;
let f2 = crate::infer::f2_multi_position_report(&cpu, &got);
eprintln!(
"[qwen3moe fault] {fault:?}: min cosine {min_cos:.6}, argmax mismatches \
{mismatches}/{}, exact-reference check {}, runtime F2 {}",
cpu.len(),
if exact_ok { "PASS" } else { "REJECT" },
if f2.accepted { "ACCEPT" } else { "REJECT" },
);
verdicts.push((fault, exact_ok, f2.accepted));
}
gpu.fault = None;
assert!(
verdicts[0].1 && verdicts[0].2,
"the control (no fault) must pass both checks, or the rejections prove nothing"
);
for &(fault, exact_ok, f2_ok) in &verdicts[1..] {
assert!(
!exact_ok,
"{fault:?} passed the exact-reference check: it cannot fail"
);
if matches!(
fault,
Some(RoutingFault::WrongExpert | RoutingFault::UniformWeights)
) {
assert!(!f2_ok, "{fault:?} passed the runtime F2 guard");
}
}
}