use super::*;
use crate::scheduler::test_support::active_seq;
use metrale_speculative::prompt_lookup::{PromptLookupConfig, PromptLookupSeq};
const CFG: PromptLookupConfig = PromptLookupConfig {
ngram: 2,
max_drafts: 3,
max_seqs: 8,
min_match: 2,
miss_backoff: 0,
};
fn with_copy() -> ActiveSeq {
let (mut a, _rx) = active_seq(0, 1);
let mut pl = PromptLookupSeq::new(&CFG);
assert!(pl.propose(&[1, 2, 3, 4, 5, 1, 2], 3).is_some());
a.prompt_lookup = Some(Box::new(pl));
a
}
#[test]
fn the_drafter_keeps_its_accepts_only_for_its_own_drafts() {
let (mut a, _rx) = active_seq(0, 1);
assert_eq!(drafter_accepted(&a, 2), 2);
a.prompt_lookup = Some(Box::new(PromptLookupSeq::new(&CFG)));
assert_eq!(drafter_accepted(&a, 2), 2, "state without a copy in flight");
let a = with_copy();
assert_eq!(copy_in_flight(&a), 3);
assert_eq!(
drafter_accepted(&a, 2),
0,
"a copy is a full reject for the drafter"
);
}
#[test]
fn settling_reads_the_accepts_from_the_seq_len_advance() {
let sched = crate::scheduler::sched_ctx::SchedCtx::for_test();
let mut active = vec![with_copy(), with_copy()];
for a in active.iter_mut() {
a.seq.seq_len = 100;
}
active[0].seq.seq_len = 103;
active[1].seq.seq_len = 104;
settle_copies(&mut active, &sched, &[(0, 100), (1, 100)]);
assert_eq!(sched.prompt_lookup_stats.get(), [2, 6, 5]);
for a in &active {
assert_eq!(copy_in_flight(a), 0, "no mark outlives its verify");
}
assert_eq!(
active[0].prompt_lookup.as_ref().map(|p| p.window()),
Some(1)
);
assert_eq!(
active[1].prompt_lookup.as_ref().map(|p| p.window()),
Some(3)
);
}
#[test]
fn a_sequence_that_did_not_advance_settles_as_a_miss() {
let sched = crate::scheduler::sched_ctx::SchedCtx::for_test();
let mut active = vec![with_copy()];
active[0].seq.seq_len = 50;
settle_copies(&mut active, &sched, &[(0, 50)]);
assert_eq!(sched.prompt_lookup_stats.get(), [1, 3, 0]);
}
#[test]
fn long_copies_are_bucketed_to_powers_of_two() {
let mk = |n: u32| (0..n).collect::<Vec<u32>>();
for (n, want) in [
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 4),
(7, 4),
(8, 8),
(15, 8),
(16, 16),
] {
assert_eq!(bucket_copy(mk(n)).len(), want, "copy of {n}");
}
assert_eq!(
bucket_copy(mk(6)),
vec![0, 1, 2, 3],
"a bucket keeps the copy's prefix"
);
}