use super::runner::run_scenario;
use super::scenarios;
use super::tests::SERIAL;
const VERIFY_LABELS: [&str; 5] = [
"decode_verify_graphed(",
"decode_verify_graphed_k3(",
"decode_verify_graphed_k4(",
"decode_and_verify_fused(",
"decode_verify_dflash(",
];
fn dflash_trace(num_drafts: usize, ep: bool) -> Vec<String> {
let mut sc = scenarios::dflash("dflash_ctx", 1);
sc.opts.num_drafts = num_drafts;
sc.cfg.ep = ep;
let _g = SERIAL.lock().unwrap_or_else(|e| e.into_inner());
run_scenario(&sc)
}
fn verify_shape(line: &str) -> (usize, usize) {
let tokens = line
.split("tokens=[")
.nth(1)
.and_then(|r| r.split(']').next())
.expect("tokens in the verify line");
let k = tokens.split(", ").count();
let len = line
.split(":len=")
.nth(1)
.and_then(|r| r.split(|c: char| !c.is_ascii_digit()).next())
.and_then(|d| d.parse().ok())
.expect("len in the verify line");
(k, len)
}
fn field(line: &str, key: &str) -> usize {
line.split(&format!(", {key}="))
.nth(1)
.and_then(|r| r.split(|c: char| !c.is_ascii_digit()).next())
.and_then(|d| d.parse().ok())
.unwrap_or_else(|| panic!("no {key}= in {line}"))
}
fn check_every_verify_commits_its_rows(trace: &[String]) -> Vec<&'static str> {
let mut seen = Vec::new();
for (i, line) in trace.iter().enumerate() {
let Some(label) = VERIFY_LABELS.iter().find(|l| line.starts_with(**l)) else {
continue;
};
seen.push(*label);
let (k, len_after) = verify_shape(line);
let pre = len_after - k;
let rest = &trace[i + 1..];
let end = rest
.iter()
.position(|l| VERIFY_LABELS.iter().any(|v| l.starts_with(v)))
.unwrap_or(rest.len());
let own = &rest[..end];
let state_commit = own
.iter()
.position(|l| l.starts_with("commit_accepted_prefix("));
let ctx: Vec<&String> = own[..state_commit.unwrap_or(own.len())]
.iter()
.filter(|l| l.starts_with("commit_ctx("))
.collect();
assert_eq!(
ctx.len(),
1,
"verify at line {i} ({line}) commits the drafter context {} times before its \
state commit",
ctx.len()
);
assert_eq!(
field(ctx[0], "base"),
pre,
"verify at line {i} ({line}): {} must sit at the anchor's position {pre}",
ctx[0]
);
if let Some(c) = state_commit {
let rows = field(&own[c], "na");
assert_eq!(
field(ctx[0], "n"),
rows,
"verify at line {i} ({line}): {} must commit the {rows} rows the state keeps",
ctx[0]
);
}
}
seen
}
#[test]
fn every_single_rank_verify_width_commits_its_accepted_rows() {
for (nd, label) in [
(1, "decode_and_verify_fused("),
(2, "decode_and_verify_fused("),
(3, "decode_and_verify_fused("),
(5, "decode_verify_dflash("),
] {
let trace = dflash_trace(nd, false);
let seen = check_every_verify_commits_its_rows(&trace);
assert!(
seen.contains(&label),
"{nd} drafts ran no {label} verify: {seen:?}"
);
}
}
#[test]
fn every_multi_rank_verify_width_commits_its_accepted_rows() {
for (nd, label) in [
(1, "decode_verify_graphed("),
(2, "decode_verify_graphed_k3("),
(3, "decode_verify_graphed_k4("),
] {
let trace = dflash_trace(nd, true);
let seen = check_every_verify_commits_its_rows(&trace);
assert!(
seen.contains(&label),
"{nd} drafts ran no {label} verify: {seen:?}"
);
}
}
fn dflash_think_trace(seam_serial: bool) -> Vec<String> {
let mut sc = scenarios::dflash("dflash_think", 1);
sc.opts.think_start_token = Some(10);
sc.opts.think_end_token = Some(13);
sc.opts.dflash_seam_serial = seam_serial;
let _g = SERIAL.lock().unwrap_or_else(|e| e.into_inner());
run_scenario(&sc)
}
fn check_every_propose_sees_every_row(trace: &[String]) -> usize {
let mut rows: Vec<usize> = Vec::new();
let mut proposes = 0;
for line in trace {
if let Some(r) = line.strip_prefix("prefill(n=") {
let n: usize = r.split(',').next().unwrap().parse().unwrap();
rows.extend(0..n);
} else if line.starts_with("commit_ctx(") {
let base = field(line, "base");
rows.extend(base..base + field(line, "n"));
} else if line.starts_with("run_mtp_propose_multi(") {
let pos = field(line, "pos");
let mut seen: Vec<usize> = rows.iter().copied().filter(|&r| r < pos).collect();
seen.sort_unstable();
assert_eq!(
seen,
(0..pos).collect::<Vec<_>>(),
"{line}: the drafter context does not hold one row per position below {pos}"
);
proposes += 1;
}
}
proposes
}
#[test]
fn the_thinking_seam_keeps_one_ctx_row_per_position() {
for seam_serial in [true, false] {
let trace = dflash_think_trace(seam_serial);
assert!(
trace.iter().any(|l| l.starts_with("decode_batch(")),
"seam_serial={seam_serial}: the thinking span ran no serial decode"
);
let n = check_every_propose_sees_every_row(&trace);
assert!(n >= 2, "seam_serial={seam_serial}: only {n} proposes ran");
}
}