use std::collections::BTreeMap;
pub const BF16_BYTES: u64 = 2;
pub const FP32_BYTES: u64 = 4;
pub const INT64_BYTES: u64 = 8;
pub const DEFAULT_WINDOW_PAGE: usize = 128;
pub const AUTO_KV_SLACK_BYTES: u64 = 2 << 30;
pub const NO_WINDOW_SLOT: i64 = -1;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Dsv4Args {
pub head_dim: u64,
pub index_head_dim: u64,
pub n_layers: usize,
pub compress_ratios: Vec<u32>,
}
impl Dsv4Args {
pub fn ratios(&self) -> &[u32] {
let end = self.n_layers.min(self.compress_ratios.len());
&self.compress_ratios[..end]
}
}
pub fn ring_size_for_ratio(ratio: u32) -> usize {
match ratio {
4 => 8,
128 => 128,
_ => panic!("no ring for ratio {ratio} (only 4 / 128)"),
}
}
pub const CSA_RATIO: u32 = 4;
pub const HCA_RATIO: u32 = 128;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LayerCompressor {
None,
Csa,
Hca,
}
impl LayerCompressor {
pub fn from_ratio(ratio: u32) -> Option<Self> {
match ratio {
0 => Some(LayerCompressor::None),
CSA_RATIO => Some(LayerCompressor::Csa),
HCA_RATIO => Some(LayerCompressor::Hca),
_ => None,
}
}
pub fn ratio(self) -> u32 {
match self {
LayerCompressor::None => 0,
LayerCompressor::Csa => CSA_RATIO,
LayerCompressor::Hca => HCA_RATIO,
}
}
pub fn has_indexer(self) -> bool {
matches!(self, LayerCompressor::Csa)
}
pub fn projection_width_multiple(self) -> usize {
match self {
LayerCompressor::Csa => 2,
LayerCompressor::None | LayerCompressor::Hca => 1,
}
}
pub fn overlapping(self) -> bool {
matches!(self, LayerCompressor::Csa)
}
pub fn visible_compressed(self, pos: usize) -> usize {
match self.ratio() {
0 => 0,
r => (pos + 1) / r as usize,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UnknownCompressRatio {
pub layer: usize,
pub ratio: u32,
}
impl std::fmt::Display for UnknownCompressRatio {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { layer, ratio } = self;
write!(
f,
"layer {layer} has compress ratio {ratio}, which is none of 0 (no compressor), \
{CSA_RATIO} (CSA) or {HCA_RATIO} (HCA); these are three different mechanisms, \
so there is no nearest one to fall back to"
)
}
}
impl std::error::Error for UnknownCompressRatio {}
impl Dsv4Args {
pub fn compressors(&self) -> Result<Vec<LayerCompressor>, UnknownCompressRatio> {
self.ratios()
.iter()
.enumerate()
.map(|(layer, &ratio)| {
LayerCompressor::from_ratio(ratio).ok_or(UnknownCompressRatio { layer, ratio })
})
.collect()
}
}
pub fn dsv4_reserved_window_pages(max_running_req: usize, radix: bool) -> usize {
2 * (max_running_req + 1) + if radix { 3 * max_running_req } else { 0 } + 1
}
pub fn dsv4_window_floor_pages(
max_seq_len: usize,
max_running_req: usize,
radix: bool,
page: usize,
) -> usize {
assert!(page > 0, "a window page holds at least one position");
let prefill_reach_pages = max_seq_len.div_ceil(page);
prefill_reach_pages.min(8) + dsv4_reserved_window_pages(max_running_req, radix)
}
fn kv_bytes(args: &Dsv4Args) -> u64 {
args.head_dim * BF16_BYTES
}
fn index_bytes(args: &Dsv4Args) -> u64 {
args.index_head_dim * BF16_BYTES
}
fn state_bytes(args: &Dsv4Args, ratio: u32) -> u64 {
let overlap = u64::from(ratio == 4);
2 * (1 + overlap) * args.head_dim * FP32_BYTES
}
fn idx_state_bytes(args: &Dsv4Args) -> u64 {
2 * 2 * args.index_head_dim * FP32_BYTES
}
fn scaled(ratio: f64, count: usize) -> usize {
assert!(
ratio.is_finite() && ratio >= 0.0,
"swa_ratio must be a non-negative fraction of the full history, got {ratio}"
);
ferrox_core::placement::round_half_even(ratio * count as f64).max(0) as usize
}
pub fn dsv4_cache_per_page(args: &Dsv4Args, swa_ratio: f64, page: usize) -> u64 {
assert!(page > 0, "a window page holds at least one position");
let kv_b = kv_bytes(args);
let idx_b = index_bytes(args);
let mut total = 0u64;
for ratio in args.ratios().iter().copied() {
total += scaled(swa_ratio, page) as u64 * kv_b;
if ratio == 0 {
continue;
}
total += (page as u64 / u64::from(ratio)) * kv_b;
if ratio == 4 {
total += (page as u64 / 4) * idx_b;
total += scaled(swa_ratio, ring_size_for_ratio(4)) as u64 * idx_state_bytes(args);
}
total += scaled(swa_ratio, ring_size_for_ratio(ratio)) as u64 * state_bytes(args, ratio);
}
total
}
pub fn dsv4_kv_unit_bytes(args: &Dsv4Args, page: usize) -> u64 {
assert!(page > 0, "a window page holds at least one position");
let kv_b = kv_bytes(args);
let idx_b = index_bytes(args);
let mut per_page = page as u64 * INT64_BYTES;
for ratio in args.ratios().iter().copied() {
if ratio == 0 {
continue;
}
per_page += (page as u64 / u64::from(ratio)) * kv_b;
if ratio == 4 {
per_page += (page as u64 / 4) * idx_b;
}
}
per_page.div_ceil(page as u64)
}
pub fn dsv4_window_unit_bytes(args: &Dsv4Args, page: usize) -> u64 {
assert!(page > 0, "a window page holds at least one position");
let kv_b = kv_bytes(args);
let ratios = args.ratios();
let mut per_page = ratios.len() as u64 * page as u64 * kv_b;
for ratio in ratios.iter().copied() {
if ratio == 0 {
continue;
}
per_page += ring_size_for_ratio(ratio) as u64 * state_bytes(args, ratio);
if ratio == 4 {
per_page += ring_size_for_ratio(4) as u64 * idx_state_bytes(args);
}
}
per_page.div_ceil(page as u64)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Dsv4LayerSizes {
pub ratio: u32,
pub ring_size: usize,
pub cmp_blocks: usize,
pub idx_blocks: Option<usize>,
pub state_slots: usize,
pub idx_state_slots: Option<usize>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Dsv4PoolSizes {
pub page: usize,
pub swa_ratio: f64,
pub full_token: usize,
pub n_win_slots: usize,
pub n_win_pages: usize,
pub layers: Vec<Option<Dsv4LayerSizes>>,
}
impl Dsv4PoolSizes {
pub fn num_pages(&self) -> usize {
self.full_token / self.page
}
}
pub fn dsv4_pool_sizes(
num_pages: usize,
args: &Dsv4Args,
swa_ratio: f64,
page: usize,
n_win_pages: Option<usize>,
) -> Dsv4PoolSizes {
assert!(page > 0, "a window page holds at least one position");
let full_token = num_pages * page;
let n_win_pages = match n_win_pages {
Some(pages) => pages,
None => scaled(swa_ratio, full_token).div_ceil(page),
};
let n_win_pages = n_win_pages.min(num_pages);
let n_win_slots = n_win_pages * page;
let mut layers = Vec::with_capacity(args.ratios().len());
for ratio in args.ratios().iter().copied() {
if ratio == 0 {
layers.push(None);
continue;
}
assert!(
page.is_multiple_of(ratio as usize),
"P={page} must be divisible by ratio {ratio}"
);
let ring_size = ring_size_for_ratio(ratio);
layers.push(Some(Dsv4LayerSizes {
ratio,
ring_size,
cmp_blocks: full_token / ratio as usize,
idx_blocks: (ratio == 4).then_some(full_token / 4),
state_slots: n_win_pages * ring_size,
idx_state_slots: (ratio == 4).then(|| n_win_pages * ring_size_for_ratio(4)),
}));
}
Dsv4PoolSizes {
page,
swa_ratio,
full_token,
n_win_slots,
n_win_pages,
layers,
}
}
pub fn dsv4_pool_bytes(sizes: &Dsv4PoolSizes, args: &Dsv4Args, n_scratch: usize) -> u64 {
let ratios = args.ratios();
assert_eq!(
sizes.layers.len(),
ratios.len(),
"these sizes were built for a {}-layer stack, not a {}-layer one",
sizes.layers.len(),
ratios.len()
);
let kv_b = kv_bytes(args);
let idx_b = index_bytes(args);
let n_scratch = n_scratch as u64;
let mut total = ratios.len() as u64 * sizes.n_win_slots as u64 * kv_b;
total += (sizes.full_token as u64 + 1) * INT64_BYTES;
for layer in sizes.layers.iter().flatten() {
total += (layer.cmp_blocks as u64 + n_scratch) * kv_b;
total += (layer.state_slots as u64 + 1) * state_bytes(args, layer.ratio);
if layer.ratio == 4 {
let idx_blocks = layer
.idx_blocks
.expect("a ratio-4 layer has an indexer tier");
let idx_state = layer
.idx_state_slots
.expect("a ratio-4 layer has an indexer ring");
total += (idx_blocks as u64 + n_scratch) * idx_b;
total += (idx_state as u64 + 1) * idx_state_bytes(args);
}
}
total
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Dsv4BudgetTooSmall {
pub available_bytes: u64,
pub needed_bytes: u64,
pub min_pages: usize,
pub floor_win_pages: usize,
}
impl std::fmt::Display for Dsv4BudgetTooSmall {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"DSV4 KV budget {} bytes cannot fit the minimal pool ({} pages incl. the window \
working-set floor {}, needing {} bytes); raise memory_ratio or lower \
max_running_req/max_seq_len",
self.available_bytes, self.min_pages, self.floor_win_pages, self.needed_bytes
)
}
}
impl std::error::Error for Dsv4BudgetTooSmall {}
pub fn dsv4_solve_num_pages(
available_bytes: u64,
args: &Dsv4Args,
swa_ratio: f64,
floor_win_pages: usize,
page: usize,
n_scratch: usize,
) -> Result<Dsv4PoolSizes, Dsv4BudgetTooSmall> {
let sizes_at = |num: usize| -> Dsv4PoolSizes {
let win = floor_win_pages.max(scaled(swa_ratio, num * page).div_ceil(page));
dsv4_pool_sizes(num, args, swa_ratio, page, Some(win))
};
let lo0 = floor_win_pages.max(2);
let needed = dsv4_pool_bytes(&sizes_at(lo0), args, n_scratch);
if needed > available_bytes {
return Err(Dsv4BudgetTooSmall {
available_bytes,
needed_bytes: needed,
min_pages: lo0,
floor_win_pages,
});
}
let mut lo = lo0;
let mut hi = lo.max((available_bytes / dsv4_cache_per_page(args, 0.0, page).max(1)) as usize);
while dsv4_pool_bytes(&sizes_at(hi), args, n_scratch) <= available_bytes {
hi *= 2;
}
while lo < hi - 1 {
let mid = (lo + hi) / 2;
if dsv4_pool_bytes(&sizes_at(mid), args, n_scratch) <= available_bytes {
lo = mid;
} else {
hi = mid;
}
}
Ok(sizes_at(lo))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Dsv4AutoCost {
pub cache_per_page: u64,
pub fixed_cache_size: u64,
pub min_reserve_tokens: usize,
}
pub fn dsv4_auto_cost_model(
args: &Dsv4Args,
swa_ratio: f64,
floor_win_pages: usize,
page: usize,
n_scratch: usize,
) -> Dsv4AutoCost {
let per_page = dsv4_cache_per_page(args, swa_ratio, page) + page as u64 * INT64_BYTES;
let n0 = floor_win_pages.max(2);
let win0 = floor_win_pages.max(scaled(swa_ratio, n0 * page).div_ceil(page));
let base = dsv4_pool_bytes(
&dsv4_pool_sizes(n0, args, swa_ratio, page, Some(win0)),
args,
n_scratch,
);
let slack_pages = AUTO_KV_SLACK_BYTES.div_ceil(per_page.max(1)) as usize;
Dsv4AutoCost {
cache_per_page: per_page,
fixed_cache_size: base.saturating_sub(n0 as u64 * per_page),
min_reserve_tokens: (n0 + slack_pages) * page,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FreeListExhausted {
pub needed_units: usize,
pub available_units: usize,
pub capacity: usize,
pub page_unit: usize,
}
impl std::fmt::Display for FreeListExhausted {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"window free list out of slots: requested {} units, have {} (capacity {}, unit {})",
self.needed_units, self.available_units, self.capacity, self.page_unit
)
}
}
impl std::error::Error for FreeListExhausted {}
#[derive(Debug, Clone)]
pub struct FreeListAllocator {
capacity: usize,
page_unit: usize,
free: Vec<usize>,
}
impl FreeListAllocator {
pub fn new(capacity: usize, page_unit: usize) -> Self {
assert!(page_unit > 0, "a unit spans at least one slot");
assert!(
capacity.is_multiple_of(page_unit),
"capacity {capacity} must be a multiple of page_unit {page_unit}"
);
let mut allocator = FreeListAllocator {
capacity,
page_unit,
free: Vec::new(),
};
allocator.reset();
allocator
}
pub fn alloc(&mut self, n_units: usize) -> Result<Vec<usize>, FreeListExhausted> {
if n_units > self.free.len() {
return Err(FreeListExhausted {
needed_units: n_units,
available_units: self.free.len(),
capacity: self.capacity,
page_unit: self.page_unit,
});
}
Ok(self.free.split_off(self.free.len() - n_units))
}
pub fn free(&mut self, units: &[usize]) {
for base in units.iter().copied() {
assert!(
base.is_multiple_of(self.page_unit) && base < self.capacity,
"{base} is not a unit base of a {}-slot unit inside a capacity of {}",
self.page_unit,
self.capacity
);
self.free.push(base);
}
}
pub fn available(&self) -> usize {
self.free.len() * self.page_unit
}
pub fn free_units(&self) -> usize {
self.free.len()
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn page_unit(&self) -> usize {
self.page_unit
}
pub fn reset(&mut self) {
let n_units = self.capacity / self.page_unit;
self.free = (0..n_units).map(|unit| unit * self.page_unit).collect();
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Dsv4WindowCtx {
pub window_slot: i64,
pub prev_window_slot: i64,
pub window_slots_topk: Vec<i64>,
}
pub fn window_ring_position(pos: i64, j: usize, win: usize) -> Option<i64> {
assert!(win > 0, "a ring holds at least one slot");
if (j as i64) > pos {
return None;
}
let p = pos - (pos - j as i64).rem_euclid(win as i64);
(p >= 0).then_some(p)
}
#[derive(Debug, Clone)]
pub struct Dsv4WindowPool {
page: usize,
full_token: usize,
n_win_slots: usize,
full_to_window: Vec<i64>,
allocator: FreeListAllocator,
chunk_budget: usize,
}
impl Dsv4WindowPool {
pub fn new(sizes: &Dsv4PoolSizes, max_running_req: usize, radix: bool) -> Self {
let page = sizes.page;
assert!(
sizes.full_token >= page && sizes.full_token.is_multiple_of(page),
"the full anchor must be whole pages and hold the dummy page"
);
assert!(
sizes.n_win_slots >= page && sizes.n_win_slots.is_multiple_of(page),
"the window pool must be whole pages and hold the dummy page"
);
let mut pool = Dsv4WindowPool {
page,
full_token: sizes.full_token,
n_win_slots: sizes.n_win_slots,
full_to_window: vec![NO_WINDOW_SLOT; sizes.full_token + 1],
allocator: FreeListAllocator::new(sizes.n_win_slots - page, page),
chunk_budget: 0,
};
pool.bind_window_pages(sizes.full_token - page, sizes.n_win_slots - page);
let n_win_pages = (sizes.n_win_slots / page) - 1;
let reserved = dsv4_reserved_window_pages(max_running_req, radix);
pool.chunk_budget = page.max(n_win_pages.saturating_sub(reserved) / 2 * page);
pool
}
pub fn page_size(&self) -> usize {
self.page
}
pub fn swa_num_tokens(&self) -> usize {
(self.n_win_slots - self.page) + 1
}
pub fn swa_available_size(&self) -> usize {
self.allocator.available()
}
pub fn prefill_chunk_budget(&self) -> usize {
self.chunk_budget
}
pub fn bind_window_pages(&mut self, full_page_base: usize, window_page_base: usize) {
assert!(
full_page_base.is_multiple_of(self.page) && window_page_base.is_multiple_of(self.page),
"window bindings are page-aligned: full {full_page_base}, window {window_page_base}"
);
for offset in 0..self.page {
self.full_to_window[full_page_base + offset] = (window_page_base + offset) as i64;
}
}
pub fn unbind_window_pages(&mut self, full_locs: &[i64]) {
for loc in full_locs.iter().copied().filter(|loc| *loc >= 0) {
self.full_to_window[loc as usize] = NO_WINDOW_SLOT;
}
}
pub fn alloc_swa(&mut self, full_indices: &[i64]) -> Result<(), FreeListExhausted> {
if full_indices.is_empty() {
return Ok(());
}
let page = self.page;
assert!(
full_indices.len().is_multiple_of(page),
"alloc_swa needs whole pages, got {} slots",
full_indices.len()
);
let mut bases = Vec::with_capacity(full_indices.len() / page);
for chunk in full_indices.chunks(page) {
let base = chunk[0];
assert!(
base >= 0 && (base as usize).is_multiple_of(page),
"alloc_swa pages start at a page base, got {base}"
);
for (offset, loc) in chunk.iter().copied().enumerate() {
assert_eq!(
loc,
base + offset as i64,
"alloc_swa pages must be contiguous ascending"
);
}
debug_assert_eq!(
self.full_to_window[base as usize], NO_WINDOW_SLOT,
"full page {base} already holds a window page; binding over it would leak it"
);
bases.push(base as usize);
}
let wbases = self.allocator.alloc(bases.len())?;
for (fbase, wbase) in bases.into_iter().zip(wbases) {
for offset in 0..page {
self.full_to_window[fbase + offset] = (wbase + offset) as i64;
}
}
Ok(())
}
pub fn free_swa(&mut self, full_indices: &[i64]) {
let page = self.page;
let mut counts: BTreeMap<usize, usize> = BTreeMap::new();
for loc in full_indices.iter().copied().filter(|loc| *loc >= 0) {
*counts.entry(loc as usize / page * page).or_insert(0) += 1;
}
if counts.is_empty() {
return;
}
let partial: Vec<(usize, usize)> = counts
.iter()
.filter(|(_, count)| **count != page)
.map(|(base, count)| (*base, *count))
.take(4)
.collect();
assert!(
partial.is_empty(),
"free_swa got partial pages (base, count): {partial:?}"
);
let mut freed = Vec::with_capacity(counts.len());
for base in counts.into_keys() {
let window_slot = self.full_to_window[base];
for offset in 0..page {
self.full_to_window[base + offset] = NO_WINDOW_SLOT;
}
if window_slot >= 0 {
freed.push(window_slot as usize / page * page);
}
}
self.allocator.free(&freed);
}
pub fn translate(&self, full_loc: i64) -> i64 {
if full_loc < 0 {
return NO_WINDOW_SLOT;
}
self.full_to_window[full_loc as usize]
}
pub fn state_loc(window_slot: i64, ring_size: usize, page: usize) -> i64 {
assert!(
ring_size > 0 && page.is_multiple_of(ring_size),
"ring_size {ring_size} must divide P={page}, or two pages share a ring block"
);
if window_slot < 0 {
return NO_WINDOW_SLOT;
}
let pages = window_slot / page as i64;
pages * ring_size as i64 + window_slot % ring_size as i64
}
pub fn window_ctx(&self, pos: usize, full_locs: &[i64]) -> Dsv4WindowCtx {
let win = self.page;
let window_slots_topk = (0..win)
.map(|j| match window_ring_position(pos as i64, j, win) {
Some(p) => self.translate(full_locs[p as usize]),
None => NO_WINDOW_SLOT,
})
.collect();
Dsv4WindowCtx {
window_slot: self.translate(full_locs[pos]),
prev_window_slot: self.translate(full_locs[pos.saturating_sub(1)]),
window_slots_topk,
}
}
pub fn check_integrity(&self) {
let page = self.page;
let n_full_pages = self.full_token / page;
let mut seen = vec![false; self.n_win_slots / page];
let mut bound = 0usize;
assert_eq!(
self.full_to_window[self.full_token - page],
(self.n_win_slots - page) as i64,
"the reserved dummy page lost its permanent binding"
);
assert_eq!(
self.full_to_window[self.full_token], NO_WINDOW_SLOT,
"the trailing sentinel row was written"
);
for full_page in 0..n_full_pages - 1 {
let base = full_page * page;
let window_slot = self.full_to_window[base];
for offset in 0..page {
let expected = if window_slot < 0 {
NO_WINDOW_SLOT
} else {
window_slot + offset as i64
};
assert_eq!(
self.full_to_window[base + offset],
expected,
"full page {base} is bound partially or out of order at offset {offset}"
);
}
if window_slot < 0 {
continue;
}
assert!(
(window_slot as usize).is_multiple_of(page),
"window base {window_slot} is not page-aligned; its ring block aliases"
);
let index = window_slot as usize / page;
assert!(
!std::mem::replace(&mut seen[index], true),
"window page {window_slot} is bound to two full pages"
);
bound += 1;
}
for base in self.free_bases() {
assert!(
!std::mem::replace(&mut seen[base / page], true),
"window page {base} is both free and bound, or free twice"
);
}
let capacity_units = self.allocator.capacity() / page;
assert_eq!(
self.allocator.free_units() + bound,
capacity_units,
"window pages leaked or double-freed: {} free + {bound} bound != {capacity_units}",
self.allocator.free_units()
);
}
fn free_bases(&self) -> Vec<usize> {
self.allocator.free.clone()
}
}
#[cfg(test)]
mod tests {
#[test]
fn the_shipped_schedule_reads_as_three_different_mechanisms() {
let args = Dsv4Args {
head_dim: 64,
index_head_dim: 32,
n_layers: 8,
compress_ratios: vec![0, 0, 4, 128, 4, 128, 4, 0],
};
assert_eq!(
args.compressors().unwrap(),
vec![
LayerCompressor::None,
LayerCompressor::None,
LayerCompressor::Csa,
LayerCompressor::Hca,
LayerCompressor::Csa,
LayerCompressor::Hca,
LayerCompressor::Csa,
LayerCompressor::None,
]
);
}
#[test]
fn the_indexer_and_the_projection_width_follow_from_the_mechanism() {
assert!(LayerCompressor::Csa.has_indexer());
assert!(!LayerCompressor::Hca.has_indexer());
assert!(!LayerCompressor::None.has_indexer());
assert_eq!(LayerCompressor::Csa.projection_width_multiple(), 2);
assert_eq!(LayerCompressor::Hca.projection_width_multiple(), 1);
assert_eq!(LayerCompressor::None.projection_width_multiple(), 1);
assert!(LayerCompressor::Csa.overlapping());
assert!(!LayerCompressor::Hca.overlapping());
}
#[test]
fn a_query_sees_one_compressed_entry_per_completed_block() {
let csa = LayerCompressor::Csa;
assert_eq!(csa.visible_compressed(0), 0, "no block is complete yet");
assert_eq!(csa.visible_compressed(2), 0);
assert_eq!(csa.visible_compressed(3), 1, "the first block just closed");
assert_eq!(csa.visible_compressed(7), 2);
assert_eq!(csa.visible_compressed(8), 2);
let hca = LayerCompressor::Hca;
assert_eq!(hca.visible_compressed(126), 0);
assert_eq!(hca.visible_compressed(127), 1);
assert_eq!(hca.visible_compressed(255), 2);
for pos in [0, 1, 127, 1_000_000] {
assert_eq!(LayerCompressor::None.visible_compressed(pos), 0);
}
}
#[test]
fn an_unknown_ratio_is_refused_and_names_its_layer() {
assert_eq!(LayerCompressor::from_ratio(7), None);
assert_eq!(LayerCompressor::from_ratio(64), None);
let args = Dsv4Args {
head_dim: 64,
index_head_dim: 32,
n_layers: 3,
compress_ratios: vec![0, 64, 128],
};
let err = args.compressors().unwrap_err();
assert_eq!(
err,
UnknownCompressRatio {
layer: 1,
ratio: 64
}
);
assert!(err.to_string().contains("layer 1"));
}
#[test]
fn the_schedule_and_the_sizing_read_the_same_truncated_array() {
let args = Dsv4Args {
head_dim: 64,
index_head_dim: 32,
n_layers: 3,
compress_ratios: vec![4, 128, 0, 4],
};
assert_eq!(args.ratios(), &[4, 128, 0]);
let compressors = args.compressors().unwrap();
assert_eq!(compressors.len(), args.ratios().len());
for (c, &r) in compressors.iter().zip(args.ratios()) {
assert_eq!(c.ratio(), r);
}
}
#[test]
fn the_ring_table_and_the_compressor_table_agree_on_which_ratios_exist() {
for ratio in [CSA_RATIO, HCA_RATIO] {
assert!(LayerCompressor::from_ratio(ratio).is_some());
assert!(ring_size_for_ratio(ratio) > 0);
}
assert_eq!(LayerCompressor::from_ratio(0), Some(LayerCompressor::None));
assert!(std::panic::catch_unwind(|| ring_size_for_ratio(0)).is_err());
}
use super::*;
const P: usize = DEFAULT_WINDOW_PAGE;
fn args() -> Dsv4Args {
Dsv4Args {
head_dim: 8,
index_head_dim: 4,
n_layers: 4,
compress_ratios: vec![0, 4, 128, 4],
}
}
fn expected_bytes(num_pages: usize, win_pages: usize, n_scratch: usize) -> u64 {
19456 * win_pages as u64
+ 2576 * num_pages as u64
+ 64 * n_scratch as u64
+ 456
}
#[test]
fn ring_sizes_are_fixed_per_ratio() {
assert_eq!(ring_size_for_ratio(4), 8);
assert_eq!(ring_size_for_ratio(128), 128);
}
#[test]
#[should_panic(expected = "no ring for ratio 8")]
fn an_unsupported_ratio_has_no_ring() {
ring_size_for_ratio(8);
}
#[test]
fn the_reserved_window_pages_follow_the_code_not_the_docstring() {
assert_eq!(dsv4_reserved_window_pages(2, true), 2 * 3 + 3 * 2 + 1);
assert_eq!(dsv4_reserved_window_pages(2, false), 2 * 3 + 1);
assert_ne!(dsv4_reserved_window_pages(2, false), 2 * 2 + 1);
}
#[test]
fn the_window_floor_caps_the_prefill_reach_at_eight_pages() {
assert_eq!(
dsv4_window_floor_pages(2048, 2, true, P),
8 + dsv4_reserved_window_pages(2, true)
);
assert_eq!(
dsv4_window_floor_pages(256, 2, true, P),
2 + dsv4_reserved_window_pages(2, true)
);
}
#[test]
fn the_per_page_cost_sums_every_tier_over_the_layers() {
assert_eq!(
dsv4_cache_per_page(&args(), 0.5, P),
4096 + 2 * (512 + 256 + 256 + 512) + (16 + 4096)
);
assert_eq!(dsv4_cache_per_page(&args(), 0.0, P), 2 * (512 + 256) + 16);
}
#[test]
fn the_ratio_scaling_rounds_halves_to_even() {
let args = args();
let half_down = dsv4_cache_per_page(&args, 0.0625, P);
assert_eq!(half_down, 4 * 8 * 16 + 2 * (512 + 256) + (16 + 8 * 64));
let half_up = dsv4_cache_per_page(&args, 0.1875, P);
assert_eq!(
half_up,
4 * 24 * 16 + 2 * (512 + 256 + 2 * 64 + 2 * 128) + (16 + 24 * 64)
);
}
#[test]
fn the_unit_costs_round_bytes_per_token_up() {
assert_eq!(dsv4_kv_unit_bytes(&args(), P), 21);
assert_eq!(dsv4_window_unit_bytes(&args(), P), 152);
}
#[test]
fn the_window_tier_is_sized_independently_of_the_full_anchor() {
let args = args();
let sizes = dsv4_pool_sizes(64, &args, 0.1, P, None);
assert_eq!(sizes.full_token, 64 * P);
assert_eq!(sizes.n_win_pages, 7);
assert_eq!(sizes.n_win_slots, 7 * P);
assert_eq!(sizes.layers[0], None, "a ratio-0 layer has no tiers");
let ratio4 = sizes.layers[1].unwrap();
assert_eq!(ratio4.cmp_blocks, 64 * P / 4, "full-anchored");
assert_eq!(ratio4.idx_blocks, Some(64 * P / 4));
assert_eq!(ratio4.state_slots, 7 * 8, "window-anchored");
assert_eq!(ratio4.idx_state_slots, Some(7 * 8));
let ratio128 = sizes.layers[2].unwrap();
assert_eq!(ratio128.cmp_blocks, 64 * P / 128);
assert_eq!(ratio128.idx_blocks, None);
assert_eq!(ratio128.state_slots, 7 * 128);
}
#[test]
fn an_explicit_window_is_capped_at_the_full_history() {
let sizes = dsv4_pool_sizes(8, &args(), 0.5, P, Some(64));
assert_eq!(
sizes.n_win_pages, 8,
"a window past the history is bytes nobody can address"
);
assert_eq!(dsv4_pool_sizes(8, &args(), 4.0, P, None).n_win_pages, 8);
}
#[test]
fn the_pool_bytes_are_the_sum_of_every_allocated_row() {
let args = args();
let sizes = dsv4_pool_sizes(64, &args, 0.1, P, Some(21));
assert_eq!(dsv4_pool_bytes(&sizes, &args, 1), expected_bytes(64, 21, 1));
assert_eq!(
dsv4_pool_bytes(&sizes, &args, 3) - dsv4_pool_bytes(&sizes, &args, 1),
2 * 64
);
}
#[test]
fn dividing_the_budget_by_the_per_page_cost_overshoots_it() {
let args = args();
let floor = 21;
let available = 500_000;
let solved = dsv4_solve_num_pages(available, &args, 0.5, floor, P, 1).expect("fits");
let naive =
(available / (dsv4_cache_per_page(&args, 0.5, P) + P as u64 * INT64_BYTES)) as usize;
assert_eq!(naive, 40);
let naive_sizes = dsv4_pool_sizes(naive, &args, 0.5, P, Some(floor.max(naive.div_ceil(2))));
assert!(
dsv4_pool_bytes(&naive_sizes, &args, 1) > available,
"the division must be the one that overshoots"
);
assert_eq!(solved.num_pages(), 35);
assert!(dsv4_pool_bytes(&solved, &args, 1) <= available);
}
#[test]
fn a_small_budget_pins_the_window_at_its_floor_and_shrinks_the_full_anchor() {
let args = args();
let floor = 21;
let available = 900_000;
let solved = dsv4_solve_num_pages(available, &args, 0.1, floor, P, 1).expect("fits");
assert_eq!(solved.n_win_pages, floor, "the window pinned at its floor");
assert_eq!(solved.num_pages(), 190, "the full anchor took the rest");
assert!(solved.num_pages() > solved.n_win_pages * 4);
assert_eq!(solved.layers[1].unwrap().cmp_blocks, 190 * P / 4);
let inflated = floor as f64 / floor.max(2) as f64; let inflated_sizes = dsv4_pool_sizes(solved.num_pages(), &args, inflated, P, None);
assert!(inflated_sizes.n_win_pages > solved.n_win_pages);
assert!(
dsv4_pool_bytes(&inflated_sizes, &args, 1) > available,
"inflating swa_ratio to carry the floor busts the budget"
);
}
#[test]
fn the_solved_pool_is_the_largest_that_fits() {
let args = args();
let available = 900_000;
let solved = dsv4_solve_num_pages(available, &args, 0.1, 21, P, 1).expect("fits");
let bytes = dsv4_pool_bytes(&solved, &args, 1);
assert!(bytes <= available);
let one_more = dsv4_pool_sizes(
solved.num_pages() + 1,
&args,
0.1,
P,
Some(21.max(scaled(0.1, (solved.num_pages() + 1) * P).div_ceil(P))),
);
assert!(dsv4_pool_bytes(&one_more, &args, 1) > available);
}
#[test]
fn a_budget_below_the_minimal_pool_is_refused_at_config_time() {
let args = args();
let err = dsv4_solve_num_pages(100_000, &args, 0.1, 21, P, 1).unwrap_err();
assert_eq!(err.min_pages, 21);
assert_eq!(err.floor_win_pages, 21);
assert!(err.needed_bytes > err.available_bytes);
assert!(err.to_string().contains("working-set floor 21"));
}
#[test]
fn the_auto_cost_model_is_affine_through_the_minimal_pool() {
let args = args();
let floor = 21;
let cost = dsv4_auto_cost_model(&args, 0.1, floor, P, 1);
assert_eq!(
cost.cache_per_page,
dsv4_cache_per_page(&args, 0.1, P) + P as u64 * INT64_BYTES
);
let n0 = floor.max(2);
let base = dsv4_pool_bytes(&dsv4_pool_sizes(n0, &args, 0.1, P, Some(floor)), &args, 1);
assert_eq!(
cost.fixed_cache_size + n0 as u64 * cost.cache_per_page,
base
);
let slack_pages = AUTO_KV_SLACK_BYTES.div_ceil(cost.cache_per_page) as usize;
assert_eq!(cost.min_reserve_tokens, (n0 + slack_pages) * P);
}
fn pool() -> Dsv4WindowPool {
let sizes = dsv4_pool_sizes(8, &args(), 0.5, P, Some(5));
Dsv4WindowPool::new(&sizes, 2, true)
}
fn page_locs(full_page: usize) -> Vec<i64> {
let base = (full_page * P) as i64;
(0..P as i64).map(|offset| base + offset).collect()
}
#[test]
fn every_unit_base_is_a_multiple_of_the_page_unit() {
let mut allocator = FreeListAllocator::new(8 * P, P);
assert_eq!(allocator.available(), 8 * P);
let taken = allocator.alloc(3).expect("three of eight");
assert_eq!(taken.len(), 3);
assert!(taken.iter().all(|base| base.is_multiple_of(P)), "{taken:?}");
assert_eq!(taken, vec![5 * P, 6 * P, 7 * P]);
assert_eq!(allocator.available(), 5 * P);
allocator.free(&taken);
assert_eq!(allocator.available(), 8 * P);
assert_eq!(allocator.alloc(1).unwrap(), vec![7 * P]);
}
#[test]
#[should_panic(expected = "is not a unit base")]
fn returning_a_base_that_is_not_a_unit_base_is_refused() {
let mut allocator = FreeListAllocator::new(8 * P, P);
allocator.free(&[P + 1]);
}
#[test]
fn an_oversized_allocation_takes_nothing() {
let mut allocator = FreeListAllocator::new(4 * P, P);
let err = allocator.alloc(5).unwrap_err();
assert_eq!(err.needed_units, 5);
assert_eq!(err.available_units, 4);
assert_eq!(allocator.available(), 4 * P, "nothing was taken");
allocator.alloc(4).expect("the free list is intact");
}
#[test]
fn an_exhausted_window_pool_binds_nothing() {
let mut pool = pool();
let mut locs = Vec::new();
for full_page in 0..5 {
locs.extend(page_locs(full_page));
}
let err = pool.alloc_swa(&locs).unwrap_err();
assert_eq!(err.needed_units, 5);
assert_eq!(err.available_units, 4);
assert_eq!(pool.translate(0), NO_WINDOW_SLOT);
pool.check_integrity();
}
#[test]
fn alloc_swa_preserves_in_page_offsets() {
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).expect("one of four");
let base = pool.translate(0);
assert!(base >= 0 && (base as usize).is_multiple_of(P));
for offset in 0..P as i64 {
assert_eq!(pool.translate(offset), base + offset);
}
pool.check_integrity();
}
#[test]
#[should_panic(expected = "whole pages")]
fn alloc_swa_refuses_a_partial_page() {
let mut pool = pool();
let _ = pool.alloc_swa(&page_locs(0)[..P - 1]);
}
#[test]
#[should_panic(expected = "contiguous ascending")]
fn alloc_swa_refuses_a_page_that_is_not_contiguous_ascending() {
let mut pool = pool();
let mut locs = page_locs(0);
locs.swap(3, 9);
let _ = pool.alloc_swa(&locs);
}
#[test]
#[should_panic(expected = "partial pages")]
fn free_swa_refuses_partial_pages() {
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).unwrap();
pool.free_swa(&page_locs(0)[..P - 1]);
}
#[test]
fn freeing_the_same_page_twice_is_a_no_op() {
let mut pool = pool();
pool.alloc_swa(&page_locs(1)).unwrap();
assert_eq!(pool.swa_available_size(), 3 * P);
pool.free_swa(&page_locs(1));
assert_eq!(pool.swa_available_size(), 4 * P);
assert_eq!(pool.translate(P as i64), NO_WINDOW_SLOT);
pool.free_swa(&page_locs(1));
assert_eq!(
pool.swa_available_size(),
4 * P,
"the second free took nothing"
);
pool.free_swa(&page_locs(2));
assert_eq!(pool.swa_available_size(), 4 * P);
pool.check_integrity();
}
#[test]
fn a_negative_or_unbound_loc_translates_to_the_sentinel() {
let pool = pool();
assert_eq!(pool.translate(-1), NO_WINDOW_SLOT);
assert_eq!(pool.translate(-99), NO_WINDOW_SLOT);
assert_eq!(pool.translate(0), NO_WINDOW_SLOT);
assert_eq!(pool.translate((8 * P) as i64), NO_WINDOW_SLOT);
}
#[test]
fn the_dummy_page_is_bound_outside_the_free_list() {
let pool = pool();
assert_eq!(pool.translate((7 * P) as i64), (4 * P) as i64);
assert_eq!(pool.swa_available_size(), 4 * P);
assert_eq!(pool.swa_num_tokens(), 4 * P + 1);
pool.check_integrity();
}
#[test]
fn the_prefill_chunk_cap_halves_what_is_left_after_the_reserve() {
let sizes = dsv4_pool_sizes(128, &args(), 0.5, P, Some(41));
let pool = Dsv4WindowPool::new(&sizes, 2, true);
let reserved = dsv4_reserved_window_pages(2, true); assert_eq!(pool.prefill_chunk_budget(), (40 - reserved) / 2 * P);
assert_eq!(pool.prefill_chunk_budget(), 13 * P);
let tiny = Dsv4WindowPool::new(&dsv4_pool_sizes(8, &args(), 0.5, P, Some(5)), 2, true);
assert_eq!(tiny.prefill_chunk_budget(), P);
}
#[test]
fn state_loc_is_derived_so_two_pages_never_share_a_ring_block() {
let ring = 8;
for offset in 0..P as i64 {
assert_eq!(Dsv4WindowPool::state_loc(offset, ring, P), offset % 8);
assert_eq!(
Dsv4WindowPool::state_loc(P as i64 + offset, ring, P),
8 + offset % 8
);
}
assert_eq!(Dsv4WindowPool::state_loc(NO_WINDOW_SLOT, ring, P), -1);
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).unwrap();
pool.alloc_swa(&page_locs(1)).unwrap();
let stored = Dsv4WindowPool::state_loc(pool.translate(0), ring, P);
pool.free_swa(&page_locs(0));
pool.alloc_swa(&page_locs(2)).unwrap();
let recycled = Dsv4WindowPool::state_loc(pool.translate((2 * P) as i64), ring, P);
assert_eq!(
stored, recycled,
"the recycled page inherits the ring block, so a stored state_loc reads its carry"
);
assert_eq!(
Dsv4WindowPool::state_loc(pool.translate(0), ring, P),
NO_WINDOW_SLOT
);
pool.check_integrity();
}
#[test]
#[should_panic(expected = "must divide")]
fn a_ring_that_does_not_divide_the_page_is_refused() {
Dsv4WindowPool::state_loc(0, 7, P);
}
#[test]
fn the_ring_names_the_latest_position_congruent_to_each_slot() {
let win = 4;
let held: Vec<i64> = (0..win)
.map(|j| window_ring_position(10, j, win).unwrap())
.collect();
assert_eq!(held, vec![8, 9, 10, 7]);
assert_eq!(window_ring_position(1, 0, win), Some(0));
assert_eq!(window_ring_position(1, 1, win), Some(1));
assert_eq!(window_ring_position(1, 2, win), None);
assert_eq!(window_ring_position(1, 3, win), None);
assert_ne!(window_ring_position(1, 3, win), Some(3));
}
#[test]
fn the_window_context_reads_the_ring_through_the_live_mapping() {
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).unwrap();
let full_locs: Vec<i64> = (0..P as i64).collect();
let ctx = pool.window_ctx(3, &full_locs);
assert_eq!(ctx.window_slot, pool.translate(3));
assert_eq!(ctx.prev_window_slot, pool.translate(2));
assert_eq!(ctx.window_slots_topk.len(), P);
for (j, slot) in ctx.window_slots_topk.iter().enumerate() {
let expected = if j <= 3 {
pool.translate(j as i64)
} else {
NO_WINDOW_SLOT
};
assert_eq!(*slot, expected, "ring slot {j}");
}
let first = pool.window_ctx(0, &full_locs);
assert_eq!(first.prev_window_slot, pool.translate(0));
}
#[test]
fn the_window_pool_conserves_every_page() {
let sizes = dsv4_pool_sizes(64, &args(), 0.5, P, Some(9));
let mut pool = Dsv4WindowPool::new(&sizes, 1, true);
let live_pages = 4;
for full_page in 0..48 {
pool.alloc_swa(&page_locs(full_page % 60))
.unwrap_or_else(|err| panic!("page {full_page}: {err}"));
if full_page >= live_pages {
pool.free_swa(&page_locs((full_page - live_pages) % 60));
}
pool.check_integrity();
}
assert_eq!(pool.swa_available_size(), (8 - live_pages) * P);
}
#[test]
#[should_panic(expected = "leaked or double-freed")]
fn the_invariant_catches_a_leaked_window_page() {
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).unwrap();
pool.unbind_window_pages(&page_locs(0));
pool.check_integrity();
}
#[test]
#[should_panic(expected = "bound to two full pages")]
fn the_invariant_catches_a_window_page_bound_twice() {
let mut pool = pool();
pool.alloc_swa(&page_locs(0)).unwrap();
let window_base = pool.translate(0) as usize;
pool.bind_window_pages(P, window_base);
pool.check_integrity();
}
}