use crate::tensor::{Device, Result, Tensor, TensorOptions};
pub(crate) const RAM_SHARE_CEILING: f64 = 0.90;
pub(crate) fn anchored_ram_budget(available: u64, held_bytes: u64, ram_max_usage: f64) -> u64 {
let total = available.saturating_add(held_bytes);
(total as f64 * ram_max_usage.min(RAM_SHARE_CEILING)) as u64
}
pub(crate) fn sample_cache_budget(
available: u64,
held_bytes: u64,
ring_bytes: u64,
ram_max_usage: f64,
) -> u64 {
anchored_ram_budget(available, held_bytes, ram_max_usage).saturating_sub(ring_bytes)
}
pub(crate) fn stager_ram_budget(
available: u64,
held_bytes: u64,
ram_max_usage: f64,
host_share: f64,
) -> u64 {
(anchored_ram_budget(available, held_bytes, ram_max_usage) as f64 * host_share) as u64
}
pub(crate) fn split_stager_budget(total: usize) -> (usize, usize) {
let stream = total / 4;
(total - stream, stream)
}
pub(crate) const RING_SLOTS_FALLBACK: usize = 4;
pub(crate) const RING_SLOTS_WITH_CACHE: usize = 8;
pub(crate) fn ring_slots_from_ram(
per_sample_bytes: usize,
batch_size: usize,
ram_max_usage: f64,
available: Option<u64>,
epoch_batches: usize,
) -> usize {
if ram_max_usage <= 0.0 {
return 0;
}
let Some(available) = available else {
return RING_SLOTS_FALLBACK.min(epoch_batches);
};
let batch_bytes = per_sample_bytes.saturating_mul(batch_size) as u64;
if batch_bytes == 0 {
return RING_SLOTS_FALLBACK.min(epoch_batches);
}
let budget = anchored_ram_budget(available, 0, ram_max_usage);
(budget / batch_bytes).min(epoch_batches as u64) as usize
}
const DOUBLE_BUFFER: usize = 2;
const FLOOR_FREE_RATIO: usize = 256;
pub(crate) fn prefetch_depth_from_vram(
per_sample_bytes: usize,
batch_size: usize,
device: Device,
max_usage: f64,
activation_reserve: usize,
) -> usize {
if !device.is_cuda() {
return DOUBLE_BUFFER; }
let batch_bytes = per_sample_bytes * batch_size;
if batch_bytes == 0 {
return DOUBLE_BUFFER; }
let idx = device.index() as i32;
let (used, total) = crate::tensor::cuda_memory_info_idx(idx)
.unwrap_or((u64::MAX, 0));
depth_from_probe(used, total, max_usage, activation_reserve, batch_bytes)
}
fn depth_from_probe(
used: u64,
total: u64,
max_usage: f64,
activation_reserve: usize,
batch_bytes: usize,
) -> usize {
let cap = (total as f64 * max_usage.clamp(0.5, 0.99)) as usize;
let budget = cap.saturating_sub(used as usize + activation_reserve);
let depth = budget / batch_bytes;
if depth > 0 {
return depth;
}
let free = total.saturating_sub(used) as usize;
let floor_bytes = DOUBLE_BUFFER.saturating_mul(batch_bytes);
if floor_bytes.saturating_mul(FLOOR_FREE_RATIO) <= free {
DOUBLE_BUFFER
} else {
0
}
}
const VIEW_SLACK_FACTOR: usize = 2;
pub(crate) fn retained_cost_estimate(rows: &[Tensor]) -> usize {
rows.iter()
.map(|t| {
let logical = t.nbytes();
let storage = t.storage_nbytes();
if storage > VIEW_SLACK_FACTOR.saturating_mul(logical) {
logical
} else {
storage
}
})
.sum()
}
pub(crate) fn retain_rows(rows: &[Tensor]) -> Result<(Vec<Tensor>, usize)> {
let mut out = Vec::with_capacity(rows.len());
let mut cost = 0usize;
for t in rows {
let logical = t.nbytes();
let storage = t.storage_nbytes();
if storage > VIEW_SLACK_FACTOR.saturating_mul(logical) {
let owned = Tensor::empty(
&t.shape(),
TensorOptions {
dtype: t.dtype(),
device: t.device(),
},
)?;
owned.copy_(t, false)?;
out.push(owned);
cost += logical;
} else {
out.push(t.clone());
cost += storage;
}
}
Ok((out, cost))
}
#[cfg(test)]
mod tests {
use super::*;
const PASCAL_USED: u64 = 5592 << 20; const PASCAL_TOTAL: u64 = 6_360_465_408; const OLMO_ACTIVATION_PEAK: usize = 1682 << 20;
const OLMO_BATCH_BYTES: usize = 16 << 10;
#[test]
fn a_model_above_the_cap_still_gets_a_double_buffer() {
let cap = (PASCAL_TOTAL as f64 * 0.90) as usize;
assert!(PASCAL_USED as usize > cap, "premise: the model alone is over the cap");
let depth = depth_from_probe(PASCAL_USED, PASCAL_TOTAL, 0.90, 0, OLMO_BATCH_BYTES);
assert_eq!(depth, DOUBLE_BUFFER);
let with_reserve = depth_from_probe(
PASCAL_USED, PASCAL_TOTAL, 0.90, OLMO_ACTIVATION_PEAK, OLMO_BATCH_BYTES,
);
assert_eq!(with_reserve, DOUBLE_BUFFER);
}
#[test]
fn the_activation_peak_is_what_drove_the_budget_to_zero() {
let used = 3 << 30; let honest = depth_from_probe(used, PASCAL_TOTAL, 0.90, 0, OLMO_BATCH_BYTES);
let double_counted = depth_from_probe(
used, PASCAL_TOTAL, 0.90, OLMO_ACTIVATION_PEAK, OLMO_BATCH_BYTES,
);
assert!(honest > 100_000, "honest probe should afford the whole chunk: {honest}");
assert!(
double_counted < honest / 2,
"charging the peak twice must visibly shrink the budget: {double_counted} vs {honest}",
);
}
#[test]
fn a_batch_too_large_for_the_headroom_keeps_the_sync_fallback() {
let free = PASCAL_TOTAL - PASCAL_USED; let fat_batch = (free / 4) as usize;
let depth = depth_from_probe(PASCAL_USED, PASCAL_TOTAL, 0.90, 0, fat_batch);
assert_eq!(depth, 0);
}
#[test]
fn a_failed_probe_declines_the_floor() {
let depth = depth_from_probe(u64::MAX, 0, 0.90, 0, OLMO_BATCH_BYTES);
assert_eq!(depth, 0);
}
#[test]
fn anchored_budget_is_a_fixed_point_both_ways() {
let a0: u64 = 1000;
let r = 0.5;
let b0 = anchored_ram_budget(a0, 0, r);
for held in [100u64, 400, 500] {
assert_eq!(anchored_ram_budget(a0 - held, held, r), b0);
}
}
#[test]
fn ram_share_is_ceilinged() {
assert_eq!(anchored_ram_budget(1000, 0, 5.0), 900);
assert_eq!(stager_ram_budget(1000, 0, 5.0, 1.0), 900);
}
#[test]
fn stager_budget_shares_and_anchors() {
assert_eq!(stager_ram_budget(1000, 0, 0.5, 0.5), 250);
assert_eq!(stager_ram_budget(800, 200, 0.5, 0.5), 250);
}
#[test]
fn stager_split_is_three_to_one() {
assert_eq!(split_stager_budget(100), (75, 25));
assert_eq!(split_stager_budget(0), (0, 0));
let (p, s) = split_stager_budget(7);
assert_eq!(p + s, 7);
}
#[test]
fn retention_prices_views_by_storage() {
use crate::tensor::Device;
let base = Tensor::from_f32(&[0.0; 64], &[8, 8], Device::CPU).unwrap();
let (rows, cost) = retain_rows(std::slice::from_ref(&base)).unwrap();
assert_eq!(cost, base.nbytes());
assert_eq!(rows[0].storage_nbytes(), base.storage_nbytes());
let row = base.select(0, 0).unwrap();
assert_eq!(row.nbytes(), 32);
assert!(row.storage_nbytes() >= 256);
assert_eq!(retained_cost_estimate(std::slice::from_ref(&row)), 32);
let (rows, cost) = retain_rows(std::slice::from_ref(&row)).unwrap();
assert_eq!(cost, 32);
assert_eq!(rows[0].storage_nbytes(), 32);
assert_eq!(rows[0].to_f32_vec().unwrap(), row.to_f32_vec().unwrap());
let half = base.narrow(0, 0, 4).unwrap();
assert_eq!(half.nbytes(), 128);
let est = retained_cost_estimate(std::slice::from_ref(&half));
assert_eq!(est, half.storage_nbytes());
let (rows, cost) = retain_rows(std::slice::from_ref(&half)).unwrap();
assert_eq!(cost, half.storage_nbytes());
assert_eq!(rows[0].storage_nbytes(), base.storage_nbytes());
}
}