use super::*;
pub(crate) const SAE_BYTES_PER_F64: usize = 8;
pub(crate) const SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES: usize = 2 * 1024 * 1024 * 1024;
pub(crate) const SAE_HOST_MEMORY_BUDGET_FRACTION_NUMERATOR: usize = 3;
pub(crate) const SAE_HOST_MEMORY_BUDGET_FRACTION_DENOMINATOR: usize = 5;
pub(crate) const SAE_CPU_L2_CACHE_BYTES: usize = 1024 * 1024;
pub(crate) const SAE_CHUNK_CACHE_MULTIPLE: usize = 8;
pub(crate) const SAE_MIN_STREAMING_CHUNK_ROWS: usize = 256;
pub(crate) const SAE_MATRIX_FREE_VECTOR_WORKSPACE_MULTIPLIER: usize = 32;
pub(crate) const SAE_HOST_MEMORY_RESERVE_FRACTION_DENOMINATOR: usize = 8;
pub(crate) const SAE_HOST_MEMORY_RESERVE_FLOOR_BYTES: usize = 256 * 1024 * 1024;
pub(crate) const SAE_MIN_DEVICE_POOL_IN_CORE_BUDGET_BYTES: usize = 64 * 1024 * 1024;
pub(crate) const SAE_DIRECT_ALWAYS_ADMIT_BYTES: usize = 16 * 1024 * 1024;
pub(crate) const fn sae_exact_stationarity_dim(coord_dim: usize, border_dim: usize) -> usize {
coord_dim.saturating_add(border_dim)
}
pub(crate) const fn sae_exact_stationarity_block_bytes(dim: usize) -> usize {
dim.saturating_mul(dim).saturating_mul(SAE_BYTES_PER_F64)
}
pub(crate) const SAE_EXACT_STATIONARITY_LIVE_DIM_BLOCKS: usize = 8;
pub(crate) const fn sae_exact_stationarity_resident_bytes(dim: usize) -> usize {
sae_exact_stationarity_block_bytes(dim)
.saturating_mul(SAE_EXACT_STATIONARITY_LIVE_DIM_BLOCKS)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SaeStreamingPlan {
pub streaming: bool,
pub chunk_size: usize,
pub estimated_full_batch_bytes: usize,
pub estimated_dense_schur_bytes: usize,
pub estimated_row_cross_bytes: usize,
pub estimated_direct_peak_bytes: usize,
pub estimated_matrix_free_peak_bytes: usize,
pub estimated_exact_stationarity_dim: usize,
pub estimated_exact_stationarity_bytes: usize,
pub in_core_budget_bytes: usize,
pub process_available_bytes: usize,
pub direct_admitted: bool,
pub exact_stationarity_admitted: bool,
pub matrix_free_admitted: bool,
}
pub(crate) fn sae_streaming_plan_from_budget(
n_obs: usize,
total_basis: usize,
k_atoms: usize,
d_max: usize,
border_dim: usize,
in_core_budget_bytes: usize,
chunk_window_bytes: usize,
process_available_bytes: usize,
) -> SaeStreamingPlan {
let per_row_words = total_basis
.saturating_mul(1 + d_max)
.saturating_add(k_atoms)
.max(1);
let per_row_bytes = per_row_words.saturating_mul(SAE_BYTES_PER_F64);
let full_batch_bytes = n_obs.saturating_mul(per_row_bytes);
let dense_schur_bytes = border_dim
.saturating_mul(border_dim)
.saturating_mul(SAE_BYTES_PER_F64);
let row_block_dim = k_atoms.saturating_mul(1usize.saturating_add(d_max));
let row_cross_bytes = n_obs
.saturating_mul(row_block_dim)
.saturating_mul(border_dim)
.saturating_mul(SAE_BYTES_PER_F64);
let p_out = border_dim / total_basis.max(1);
let direct_peak_bytes = full_batch_bytes
.saturating_add(row_cross_bytes)
.saturating_add(dense_schur_bytes);
let matrix_free_budget = in_core_budget_bytes;
let chunk_resident_bytes = chunk_window_bytes.min(full_batch_bytes.max(per_row_bytes));
let border_vector_bytes = border_dim
.saturating_mul(SAE_BYTES_PER_F64)
.saturating_mul(SAE_MATRIX_FREE_VECTOR_WORKSPACE_MULTIPLIER);
let mf_cross_bytes_per_active_atom = (1usize.saturating_add(d_max))
.saturating_mul(p_out)
.saturating_mul(SAE_BYTES_PER_F64)
.max(1);
let mf_cross_budget = matrix_free_budget
.saturating_sub(border_vector_bytes)
.saturating_sub(chunk_resident_bytes);
let mf_affordable_active =
(mf_cross_budget / n_obs.max(1) / mf_cross_bytes_per_active_atom).max(1);
let mf_active_atoms = k_atoms.min(mf_affordable_active);
let matrix_free_cross_bytes = n_obs
.saturating_mul(mf_active_atoms)
.saturating_mul(1usize.saturating_add(d_max))
.saturating_mul(p_out)
.saturating_mul(SAE_BYTES_PER_F64);
let matrix_free_peak_bytes = chunk_resident_bytes
.saturating_add(matrix_free_cross_bytes)
.saturating_add(border_vector_bytes);
let direct_fits_tiny = direct_peak_bytes <= SAE_DIRECT_ALWAYS_ADMIT_BYTES
&& direct_peak_bytes <= process_available_bytes;
let direct_admitted = direct_peak_bytes <= in_core_budget_bytes || direct_fits_tiny;
let exact_stationarity_dim = sae_exact_stationarity_dim(
n_obs.saturating_mul(k_atoms).saturating_mul(d_max),
border_dim,
);
let exact_stationarity_bytes = sae_exact_stationarity_resident_bytes(exact_stationarity_dim);
let host_budget_for_exact = sae_host_in_core_budget_from_available(process_available_bytes);
let exact_stationarity_fits_tiny = exact_stationarity_bytes <= SAE_DIRECT_ALWAYS_ADMIT_BYTES
&& exact_stationarity_bytes <= process_available_bytes;
let exact_stationarity_admitted =
exact_stationarity_bytes <= host_budget_for_exact || exact_stationarity_fits_tiny;
let matrix_free_admitted = matrix_free_peak_bytes <= matrix_free_budget;
let rows_per_chunk = (chunk_window_bytes / per_row_bytes).max(SAE_MIN_STREAMING_CHUNK_ROWS);
SaeStreamingPlan {
streaming: !direct_admitted,
chunk_size: if direct_admitted {
n_obs.max(1)
} else {
rows_per_chunk.min(n_obs).max(1)
},
estimated_full_batch_bytes: full_batch_bytes,
estimated_dense_schur_bytes: dense_schur_bytes,
estimated_row_cross_bytes: row_cross_bytes,
estimated_direct_peak_bytes: direct_peak_bytes,
estimated_matrix_free_peak_bytes: matrix_free_peak_bytes,
estimated_exact_stationarity_dim: exact_stationarity_dim,
estimated_exact_stationarity_bytes: exact_stationarity_bytes,
in_core_budget_bytes,
process_available_bytes,
direct_admitted,
exact_stationarity_admitted,
matrix_free_admitted,
}
}
pub fn sae_streaming_plan_for_shape(
n_obs: usize,
total_basis: usize,
k_atoms: usize,
d_max: usize,
border_dim: usize,
gpu_policy: gam_gpu::GpuPolicy,
) -> Result<SaeStreamingPlan, String> {
sae_streaming_plan_for_shape_with_available(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
gpu_policy,
sae_process_available_memory_bytes(),
)
}
pub fn sae_streaming_plan_for_shape_with_available(
n_obs: usize,
total_basis: usize,
k_atoms: usize,
d_max: usize,
border_dim: usize,
gpu_policy: gam_gpu::GpuPolicy,
host_available_bytes: usize,
) -> Result<SaeStreamingPlan, String> {
let host_available = host_available_bytes;
let host_budget = sae_host_in_core_budget_from_available(host_available);
let host_window = SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE;
let pessimistic_plan = sae_streaming_plan_from_budget(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
host_budget.min(SAE_MIN_DEVICE_POOL_IN_CORE_BUDGET_BYTES),
host_window,
host_available,
);
if pessimistic_plan.direct_admitted
&& pessimistic_plan.estimated_dense_schur_bytes <= host_budget
{
return Ok(sae_streaming_plan_from_budget(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
host_budget,
host_window,
host_available,
));
}
let (budget, chunk_window, host_available) =
match crate::gpu::device_runtime::GpuRuntime::resolve(gpu_policy)
.map_err(|error| format!("SAE streaming-plan CUDA admission failed: {error}"))?
{
Some(rt) if rt.device_count() > 0 => {
let aggregate_budget: usize = rt
.device_ordinals()
.iter()
.map(|&ord| rt.memory_budget_for(ord))
.sum();
if aggregate_budget > 0 {
let per_device_budget = aggregate_budget / rt.device_count();
let window = (per_device_budget / 16)
.max(SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE);
(
(aggregate_budget / 4).min(host_available),
window,
host_available,
)
} else {
(
host_budget,
SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE,
host_available,
)
}
}
Some(_) => (
host_budget,
SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE,
host_available,
),
None => (
host_budget,
SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE,
host_available,
),
};
Ok(sae_streaming_plan_from_budget(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
budget,
chunk_window,
host_available,
))
}
impl SaeStreamingPlan {
pub(crate) fn admitted_or_error(
self,
n: usize,
p: usize,
k_atoms: usize,
) -> Result<Self, String> {
if self.direct_admitted || self.matrix_free_admitted {
Ok(self)
} else {
Err(format!(
"SaeManifoldTerm::streaming_plan: predicted working set {} bytes exceeds budget {} bytes; shape n={n},p={p},K={k_atoms}",
self.estimated_matrix_free_peak_bytes, self.in_core_budget_bytes
))
}
}
pub(crate) fn solve_options_for_border_dim(self, border_dim: usize) -> ArrowSolveOptions {
let mut options = if self.direct_admitted {
ArrowSolveOptions::automatic(border_dim)
} else {
ArrowSolveOptions::inexact_pcg()
};
options.newton_schur_tikhonov_rel_floor =
Some(gam_solve::arrow_schur::SPECTRAL_DEFLATION_REL_FLOOR);
options
}
pub(crate) fn direct_logdet_admitted(self) -> bool {
self.direct_admitted && self.exact_stationarity_admitted
}
}
pub(crate) const fn sae_topk_admission_atom_basis_bound(d_max: usize) -> usize {
let periodic = 2 * d_max + 1;
let patch = 32 + ((d_max + 1) * (d_max + 2)) / 2;
if periodic > patch { periodic } else { patch }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SaeTopKCurvedBudget {
pub n_obs: usize,
pub output_dim: usize,
pub n_atoms: usize,
pub support_k: usize,
pub d_max: usize,
pub active_state_bytes: usize,
pub routing_workspace_bytes: usize,
pub decoder_bytes: usize,
pub border_vector_bytes: usize,
pub streaming_peak_bytes: usize,
pub streaming_budget_bytes: usize,
pub in_core_budget_bytes: usize,
pub streaming_admitted: bool,
}
pub(crate) fn sae_topk_curved_budget_from_budget(
n_obs: usize,
output_dim: usize,
n_atoms: usize,
d_max: usize,
support_k: usize,
in_core_budget_bytes: usize,
) -> SaeTopKCurvedBudget {
let active_state_bytes = n_obs
.saturating_mul(support_k)
.saturating_mul(2usize.saturating_add(d_max))
.saturating_mul(SAE_BYTES_PER_F64);
let basis_bound = sae_topk_admission_atom_basis_bound(d_max);
let routing_workspace_bytes = output_dim
.saturating_add(support_k.saturating_mul(2usize.saturating_add(d_max)))
.saturating_mul(SAE_BYTES_PER_F64);
let decoder_bytes = n_atoms
.saturating_mul(basis_bound)
.saturating_mul(output_dim)
.saturating_mul(SAE_BYTES_PER_F64);
let border_vector_bytes =
decoder_bytes.saturating_mul(SAE_MATRIX_FREE_VECTOR_WORKSPACE_MULTIPLIER);
let mut budget = SaeTopKCurvedBudget {
n_obs,
output_dim,
n_atoms,
support_k,
d_max,
active_state_bytes,
routing_workspace_bytes,
decoder_bytes,
border_vector_bytes,
streaming_peak_bytes: 0,
streaming_budget_bytes: in_core_budget_bytes,
in_core_budget_bytes,
streaming_admitted: false,
};
budget.streaming_peak_bytes = budget
.active_state_bytes
.saturating_add(budget.routing_workspace_bytes)
.saturating_add(budget.decoder_bytes)
.saturating_add(budget.border_vector_bytes);
budget.streaming_admitted = budget.streaming_peak_bytes <= budget.streaming_budget_bytes;
budget
}
pub(crate) fn sae_process_available_memory_bytes() -> usize {
gam_runtime::resource::process_available_memory_bytes()
}
pub(crate) const fn sae_host_in_core_budget_from_available(available: usize) -> usize {
let reserve = {
let frac = available / SAE_HOST_MEMORY_RESERVE_FRACTION_DENOMINATOR;
if frac > SAE_HOST_MEMORY_RESERVE_FLOOR_BYTES {
frac
} else {
SAE_HOST_MEMORY_RESERVE_FLOOR_BYTES
}
};
let usable = available.saturating_sub(reserve);
let fraction = (available.saturating_mul(SAE_HOST_MEMORY_BUDGET_FRACTION_NUMERATOR))
/ SAE_HOST_MEMORY_BUDGET_FRACTION_DENOMINATOR;
let floored = if fraction > SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES {
fraction
} else {
SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES
};
if floored < usable { floored } else { usable }
}
pub(crate) fn sae_host_in_core_budget_bytes() -> (usize, usize) {
let available = sae_process_available_memory_bytes();
(sae_host_in_core_budget_from_available(available), available)
}
#[cfg(test)]
mod host_budget_is_stationary_tests {
use super::*;
use gam_runtime::resource::memory_availability_probe_count;
const SWEEP_LOOKUPS: usize = 50_000;
#[test]
fn a_budget_sweep_costs_no_memory_probes() {
let primed = sae_host_in_core_budget_bytes();
let before = memory_availability_probe_count();
for _ in 0..SWEEP_LOOKUPS {
std::hint::black_box(sae_host_in_core_budget_bytes());
}
let probes = memory_availability_probe_count() - before;
assert_eq!(
probes, 0,
"{SWEEP_LOOKUPS} budget lookups took {probes} OS/cgroup probes; each probe opens \
/proc/meminfo plus the cgroup limit/usage files, so a per-work-unit probe puts that \
syscall traffic on the row-jet path (#2560 measured ~1100 six-file probes/second, \
over half the wall clock of a stuck fit). The budget must come from the process's \
one sampled observation. Primed reading: {primed:?}"
);
}
#[test]
fn the_budget_does_not_move_under_a_fit() {
let first = sae_host_in_core_budget_bytes();
for turn in 0..SWEEP_LOOKUPS {
let again = sae_host_in_core_budget_bytes();
assert_eq!(
again, first,
"the host budget moved at lookup {turn}: {again:?} vs {first:?}. Available memory \
is a live, shared quantity owned by the machine; a fit that reads it more than \
once is a fit whose route depends on what else the box was doing (#2560)."
);
}
}
}
#[cfg(test)]
mod cpu_sized_plan_laziness_tests {
use super::*;
use crate::gpu::device_runtime::GpuRuntime;
#[test]
fn cpu_sized_streaming_plan_never_probes_the_device() {
let before = GpuRuntime::resolution_call_count();
let plan = sae_streaming_plan_for_shape(700, 60, 6, 2, 144, gam_gpu::GpuPolicy::Auto)
.expect("CPU-sized plan must not require CUDA resolution");
assert!(
plan.direct_admitted,
"the CPU-sized fixture must be direct-admitted (peak {} B)",
plan.estimated_direct_peak_bytes
);
assert!(!plan.streaming);
assert_eq!(plan.chunk_size, 700);
assert_eq!(
GpuRuntime::resolution_call_count(),
before,
"planning a CPU-sized SAE fit must short-circuit BEFORE \
runtime resolution, so no CUDA context is ever created"
);
}
#[test]
fn oversized_streaming_plan_still_consults_the_device_budget() {
let before = GpuRuntime::resolution_call_count();
sae_streaming_plan_for_shape(2_000_000, 4_096, 512, 8, 32_768, gam_gpu::GpuPolicy::Auto)
.expect("oversized plan must preserve a successful CUDA resolution");
assert!(
GpuRuntime::resolution_call_count() > before,
"an oversized plan must resolve GpuRuntime for the \
pooled device budget exactly as before"
);
}
#[test]
fn early_return_carries_the_host_budget_not_the_decision_floor() {
let available = sae_process_available_memory_bytes();
let plan = sae_streaming_plan_for_shape_with_available(
700,
60,
6,
2,
144,
gam_gpu::GpuPolicy::Auto,
available,
)
.expect("CPU-sized plan must not require CUDA resolution");
assert_eq!(
plan.in_core_budget_bytes,
sae_host_in_core_budget_from_available(available),
"direct early-return must install the host budget"
);
}
}
#[cfg(test)]
mod host_in_core_budget_tests {
use super::*;
#[test]
fn budget_never_exceeds_available() {
let tiny = 512 * 1024 * 1024; let budget = sae_host_in_core_budget_from_available(tiny);
assert!(
budget <= tiny,
"budget {budget} must not exceed available {tiny}"
);
for &avail in &[
0usize,
1,
SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES - 1,
SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES,
SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES + 1,
16 * 1024 * 1024 * 1024,
] {
let budget = sae_host_in_core_budget_from_available(avail);
assert!(
budget <= avail,
"budget {budget} must not exceed available {avail}"
);
}
}
#[test]
fn ample_memory_uses_fraction_floored_at_2gib() {
let avail = 16 * 1024 * 1024 * 1024usize;
let budget = sae_host_in_core_budget_from_available(avail);
let fraction = avail * SAE_HOST_MEMORY_BUDGET_FRACTION_NUMERATOR
/ SAE_HOST_MEMORY_BUDGET_FRACTION_DENOMINATOR;
assert_eq!(budget, fraction);
assert!(budget >= SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES);
}
#[test]
fn budget_reserves_headroom_below_usable() {
for &avail in &[
256 * 1024 * 1024usize,
512 * 1024 * 1024,
2 * 1024 * 1024 * 1024,
16 * 1024 * 1024 * 1024,
128 * 1024 * 1024 * 1024,
] {
let reserve = (avail / SAE_HOST_MEMORY_RESERVE_FRACTION_DENOMINATOR)
.max(SAE_HOST_MEMORY_RESERVE_FLOOR_BYTES);
let usable = avail.saturating_sub(reserve);
let budget = sae_host_in_core_budget_from_available(avail);
assert!(
budget <= usable,
"budget {budget} must leave reserve free: usable={usable}, avail={avail}"
);
}
}
#[test]
fn below_floor_box_streams_not_oom() {
let avail = 1024 * 1024 * 1024usize; let reserve = (avail / SAE_HOST_MEMORY_RESERVE_FRACTION_DENOMINATOR)
.max(SAE_HOST_MEMORY_RESERVE_FLOOR_BYTES);
let usable = avail - reserve;
let budget = sae_host_in_core_budget_from_available(avail);
assert_eq!(
budget, usable,
"below-floor budget must collapse to usable {usable}, got {budget}"
);
assert!(budget < SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES);
let plan = sae_streaming_plan_from_budget(
10_000,
4_096,
8,
8,
64,
budget,
SAE_CPU_L2_CACHE_BYTES,
avail,
);
assert!(
!plan.direct_admitted || plan.estimated_direct_peak_bytes <= budget,
"a plan exceeding the usable budget must not be direct-admitted"
);
}
#[test]
fn tiny_plan_admits_when_budget_collapsed_but_large_plan_streams() {
let budget = 0usize;
let avail = 200 * 1024 * 1024usize;
let tiny =
sae_streaming_plan_from_budget(120, 3, 1, 1, 6, budget, SAE_CPU_L2_CACHE_BYTES, avail);
assert!(
tiny.estimated_direct_peak_bytes <= SAE_DIRECT_ALWAYS_ADMIT_BYTES,
"toy plan should be far below the always-admit size, got {} bytes",
tiny.estimated_direct_peak_bytes
);
assert!(
tiny.direct_admitted,
"a tiny dense plan ({} bytes) that fits the {avail}-byte available memory \
must be direct-admitted even when the in-core budget collapsed to 0",
tiny.estimated_direct_peak_bytes
);
assert!(
!tiny.streaming,
"a direct-admitted tiny plan must run in-core, not stream"
);
let large = sae_streaming_plan_from_budget(
10_000,
4_096,
8,
8,
64,
budget,
SAE_CPU_L2_CACHE_BYTES,
avail,
);
assert!(
large.estimated_direct_peak_bytes > SAE_DIRECT_ALWAYS_ADMIT_BYTES,
"large plan must exceed the always-admit size"
);
assert!(
!large.direct_admitted,
"a large dense plan must stay gated on the (collapsed) budget and stream, \
not be admitted by the tiny-plan relaxation"
);
}
}
#[cfg(test)]
mod exact_stationarity_admission_tests {
use super::*;
const WITNESS: (usize, usize, usize, usize, usize) = (508, 96, 8, 2, 72);
const WITNESS_MEASURED_DIM: usize = 7692;
fn plan_at(available: usize) -> SaeStreamingPlan {
let (n_obs, total_basis, k_atoms, d_max, border_dim) = WITNESS;
sae_streaming_plan_from_budget(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
sae_host_in_core_budget_from_available(available),
SAE_CPU_L2_CACHE_BYTES * SAE_CHUNK_CACHE_MULTIPLE,
available,
)
}
#[test]
fn the_priced_dimension_covers_the_measured_one() {
let plan = plan_at(64 * 1024 * 1024 * 1024);
let (n_obs, _, k_atoms, d_max, border_dim) = WITNESS;
assert_eq!(
plan.estimated_exact_stationarity_dim,
sae_exact_stationarity_dim(n_obs * k_atoms * d_max, border_dim),
"the plan must price the joint dimension through the shared expression"
);
assert!(
plan.estimated_exact_stationarity_dim >= WITNESS_MEASURED_DIM,
"priced dim {} is below the {WITNESS_MEASURED_DIM} the shipped \
[SAE-EXACT-DENSE] line reports for this shape; a memory bound that \
under-describes its own matrix is not a bound",
plan.estimated_exact_stationarity_dim
);
assert_eq!(
plan.estimated_exact_stationarity_bytes,
sae_exact_stationarity_resident_bytes(plan.estimated_exact_stationarity_dim)
);
}
#[test]
fn a_budget_below_the_dense_route_requirement_refuses_it() {
let required = plan_at(usize::MAX / 4).estimated_exact_stationarity_bytes;
assert!(
required > SAE_HOST_IN_CORE_USEFUL_WORK_FLOOR_BYTES,
"the witness's dense requirement ({required} B) must exceed the in-core \
floor, or the budget arithmetic below cannot straddle it"
);
let starved_available = (required.saturating_sub(1)
* SAE_HOST_MEMORY_BUDGET_FRACTION_DENOMINATOR)
/ SAE_HOST_MEMORY_BUDGET_FRACTION_NUMERATOR;
let roomy_available = required.saturating_mul(2);
assert!(
sae_host_in_core_budget_from_available(starved_available) < required,
"the starved side must genuinely be below the requirement"
);
assert!(
sae_host_in_core_budget_from_available(roomy_available) >= required,
"the roomy side must genuinely be at or above the requirement"
);
let starved = plan_at(starved_available);
let roomy = plan_at(roomy_available);
assert!(
starved.direct_admitted && roomy.direct_admitted,
"the full-batch direct plan ({} B) must be admitted on both sides, or the \
exact-Hessian ledger is not what moves the verdict",
starved.estimated_direct_peak_bytes
);
assert!(
starved.estimated_exact_stationarity_bytes > starved.estimated_direct_peak_bytes,
"the omitted term ({} B) must dominate the ledger that used to stand in for it \
({} B); if it did not, this issue would be a rounding correction",
starved.estimated_exact_stationarity_bytes,
starved.estimated_direct_peak_bytes
);
assert!(
!starved.exact_stationarity_admitted,
"a {required}-byte dense exact-stationarity route was admitted against a \
{}-byte budget",
sae_host_in_core_budget_from_available(starved_available)
);
assert!(
!starved.direct_logdet_admitted(),
"the predicate that dispatches to the dense exact route must refuse when the \
route does not fit; admitting an over-budget route is the defect (#2724)"
);
assert!(
roomy.exact_stationarity_admitted && roomy.direct_logdet_admitted(),
"and it must still admit the same route when the budget does cover it, or the \
bar refuses everything and proves nothing"
);
}
#[test]
fn a_toy_shape_survives_a_collapsed_budget() {
let available = 200 * 1024 * 1024usize; let plan =
sae_streaming_plan_from_budget(120, 3, 1, 1, 6, 0, SAE_CPU_L2_CACHE_BYTES, available);
assert!(
plan.estimated_exact_stationarity_bytes <= SAE_DIRECT_ALWAYS_ADMIT_BYTES,
"the toy shape's exact route ({} B) should be far below the always-admit size",
plan.estimated_exact_stationarity_bytes
);
assert!(
plan.direct_logdet_admitted(),
"a few-KiB exact route must survive a collapsed budget on a box that reports \
{available} bytes available (#1026)"
);
}
}
#[cfg(test)]
mod topk_curved_budget_tests {
use super::*;
#[test]
fn topk_curved_budget_formulas_are_the_documented_arithmetic() {
let (n, p, k, d, s) = (4096usize, 64usize, 10_000usize, 1usize, 8usize);
let budget_bytes = 8 * 1024 * 1024 * 1024usize;
let ledger = sae_topk_curved_budget_from_budget(n, p, k, d, s, budget_bytes);
assert_eq!(
ledger.active_state_bytes,
n * s * (2 + d) * SAE_BYTES_PER_F64
);
let m_hat = sae_topk_admission_atom_basis_bound(d);
assert_eq!(
m_hat,
32 + 3,
"d_max=1: patch bound 32 + (2ยท3)/2 dominates 2d+1=3"
);
assert_eq!(
ledger.routing_workspace_bytes,
(p + s * (2 + d)) * SAE_BYTES_PER_F64
);
assert_eq!(ledger.decoder_bytes, k * m_hat * p * SAE_BYTES_PER_F64);
assert_eq!(
ledger.border_vector_bytes,
ledger.decoder_bytes * SAE_MATRIX_FREE_VECTOR_WORKSPACE_MULTIPLIER
);
assert_eq!(
ledger.streaming_peak_bytes,
ledger.active_state_bytes
+ ledger.routing_workspace_bytes
+ ledger.decoder_bytes
+ ledger.border_vector_bytes
);
assert_eq!(ledger.streaming_budget_bytes, budget_bytes);
assert!(ledger.streaming_admitted);
}
#[test]
fn topk_routing_workspace_is_independent_of_atom_count() {
let shape = |k| sae_topk_curved_budget_from_budget(1024, 64, k, 2, 4, usize::MAX);
let ten_thousand = shape(10_000);
let twenty_thousand = shape(20_000);
assert_eq!(
ten_thousand.active_state_bytes,
twenty_thousand.active_state_bytes
);
assert_eq!(
ten_thousand.routing_workspace_bytes,
twenty_thousand.routing_workspace_bytes
);
assert_eq!(
ten_thousand.routing_workspace_bytes,
(64 + 4 * (2 + 2)) * SAE_BYTES_PER_F64
);
}
}
#[cfg(test)]
mod frozen_host_sample_tests {
use super::*;
const SHAPE: (usize, usize, usize, usize, usize) = (4_000, 256, 32, 2, 2_048);
fn route_at(available: usize) -> SaeStreamingPlan {
let (n_obs, total_basis, k_atoms, d_max, border_dim) = SHAPE;
sae_streaming_plan_for_shape_with_available(
n_obs,
total_basis,
k_atoms,
d_max,
border_dim,
gam_gpu::GpuPolicy::Off,
available,
)
.expect("plan resolves for an explicit host reading")
}
#[test]
fn the_route_really_does_depend_on_the_host_reading() {
let starved = route_at(0);
let roomy = route_at(1 << 40);
assert!(
starved.streaming,
"a host with no available bytes must refuse the direct plan; got {starved:?}"
);
assert!(
!roomy.streaming,
"a terabyte of headroom must admit the direct plan at this shape; got {roomy:?}"
);
}
#[test]
fn streaming_plan_follows_the_carried_sample_not_ambient_memory() {
let (mut term, _target, _rho) = crate::manifold::tests::small_two_atom_periodic_term();
term.gpu_policy = gam_gpu::GpuPolicy::Off;
term.host_available_bytes = 0;
let starved = term.streaming_plan().expect("plan at a starved reading");
term.host_available_bytes = 1 << 40;
let roomy = term.streaming_plan().expect("plan at a roomy reading");
assert!(
starved.streaming,
"carrying a zero host reading must route this term to streaming; got {starved:?}"
);
assert!(
!roomy.streaming,
"carrying a terabyte must route this term direct; got {roomy:?}"
);
assert_ne!(
starved.in_core_budget_bytes, roomy.in_core_budget_bytes,
"the two readings must produce different budgets, or the pair proves nothing"
);
let roomy_again = term.streaming_plan().expect("re-plan at the same reading");
assert_eq!(roomy.streaming, roomy_again.streaming);
assert_eq!(roomy.chunk_size, roomy_again.chunk_size);
assert_eq!(roomy.in_core_budget_bytes, roomy_again.in_core_budget_bytes);
assert_eq!(
roomy.process_available_bytes,
roomy_again.process_available_bytes
);
}
}