use memra_engine::cache::Cache;
use memra_engine::forward::argmax;
use memra_engine::hybrid::HybridModel;
use memra_engine::Engine;
use memra_gguf::GgufFile;
fn arg_val(rest: &[String], key: &str) -> Option<String> {
rest.iter().position(|a| a == key).and_then(|i| rest.get(i + 1)).cloned()
}
fn pool_stats() -> (u64, u64) {
use cudarc::driver::sys;
unsafe {
let mut pool: sys::CUmemoryPool = std::ptr::null_mut();
if sys::cuDeviceGetDefaultMemPool(&mut pool, 0) != sys::CUresult::CUDA_SUCCESS {
return (0, 0);
}
let (mut reserved, mut used) = (0u64, 0u64);
let _ = sys::cuMemPoolGetAttribute(
pool,
sys::CUmemPool_attribute_enum::CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT,
&mut reserved as *mut u64 as *mut core::ffi::c_void,
);
let _ = sys::cuMemPoolGetAttribute(
pool,
sys::CUmemPool_attribute_enum::CU_MEMPOOL_ATTR_USED_MEM_CURRENT,
&mut used as *mut u64 as *mut core::ffi::c_void,
);
(reserved, used)
}
}
fn mb(b: u64) -> f64 { b as f64 / (1024.0 * 1024.0) }
fn eager_ref(e: &Engine, m: &HybridModel, prompt: &[u32], n: usize)
-> Result<Vec<u32>, Box<dyn std::error::Error>> {
let mut cache = Cache::new(e, &m.cfg, prompt.len() + n + 8)?;
let mut ll = Vec::new();
for &t in prompt { ll = m.decode_step(e, t, &mut cache)?; }
let mut tok = argmax(&ll) as u32;
let mut out = Vec::with_capacity(n);
out.push(tok);
for _ in 1..n {
ll = m.decode_step(e, tok, &mut cache)?;
tok = argmax(&ll) as u32;
out.push(tok);
}
Ok(out)
}
fn session_run(e: &Engine, m: &HybridModel, prompt: &[u32], budget: usize, n: usize,
recap_at: Option<usize>, canary_at: Option<usize>)
-> Result<Vec<u32>, Box<dyn std::error::Error>> {
let (mut sess, first) = m.graph_session_new(e, prompt, budget)?;
let mut out = Vec::with_capacity(n);
out.push(first);
for i in 1..n {
if recap_at == Some(i) { m.graph_session_recapture_pub(e, &mut sess)?; }
if canary_at == Some(i) {
e.set_u32_one(&mut sess.gs.token_d, 1234)?;
}
out.push(sess.step(e, m)?);
}
Ok(out)
}
fn diff(a: &[u32], b: &[u32]) -> Option<usize> {
if a.len() != b.len() { return Some(a.len().min(b.len())); }
a.iter().zip(b.iter()).position(|(x, y)| x != y)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = std::env::args().skip(1);
let path = args.next().expect("usage: graph-warmup-stress <model.gguf> [--cycles N] [--canary]");
let rest: Vec<String> = args.collect();
let cycles: usize = arg_val(&rest, "--cycles").and_then(|v| v.parse().ok()).unwrap_or(10);
let large_n: usize = arg_val(&rest, "--large-steps").and_then(|v| v.parse().ok()).unwrap_or(160);
let small_n: usize = arg_val(&rest, "--small-steps").and_then(|v| v.parse().ok()).unwrap_or(90);
let canary = rest.iter().any(|a| a == "--canary");
let large_budget = 4096usize;
let small_budget = small_n + 6;
let e = Engine::new(0)?;
let g = GgufFile::open(&path)?;
let m = HybridModel::load_without_mtp(&e, &g)?;
let prompt: Vec<u32> = (0..48u32).map(|j| 55 + j * 31).collect();
let warm = std::env::var("MEMRA_GRAPH_WARMUPS").unwrap_or_else(|_| "(default)".into());
println!("model {path} arch {} ({} layers) cycles={cycles} large={large_n}tok/@{large_budget} \
small={small_n}tok/@{small_budget} MEMRA_GRAPH_WARMUPS={warm} canary={canary}",
g.arch().unwrap_or("?"), m.layers.len());
let (r0, u0) = pool_stats();
println!("[pool] post-load: reserved {:.0} MB used {:.0} MB", mb(r0), mb(u0));
let ref_small = eager_ref(&e, &m, &prompt, small_n)?;
let ref_large = eager_ref(&e, &m, &prompt, large_n)?;
let (r1, u1) = pool_stats();
println!("[pool] post-eager-ref: reserved {:.0} MB used {:.0} MB", mb(r1), mb(u1));
let mut fails = 0usize;
let mut canary_caught = false;
for c in 1..=cycles {
let out_l = session_run(&e, &m, &prompt, large_budget, large_n, Some(large_n / 2), None)?;
let (ra, ua) = pool_stats();
let out_s = session_run(&e, &m, &prompt, small_budget, small_n, Some(small_n / 2),
if canary && c == 1 { Some(small_n / 3) } else { None })?;
let (rb, ub) = pool_stats();
let out_s2 = session_run(&e, &m, &prompt, small_budget, small_n, Some(small_n / 2), None)?;
let out_l2 = session_run(&e, &m, &prompt, large_budget, large_n, Some(large_n / 2), None)?;
let mut cycle_ok = true;
for (label, out, r) in [("L->", &out_l, &ref_large), ("->S", &out_s, &ref_small),
("S->", &out_s2, &ref_small), ("->L", &out_l2, &ref_large)] {
let canary_arm = canary && c == 1 && label == "->S";
match diff(out, r) {
None if canary_arm => {
println!("cycle {c} {label}: CANARY NOT CAUGHT (corrupted stream still matched — comparator blind)");
cycle_ok = false;
}
None => {}
Some(i) if canary_arm => {
println!("cycle {c} {label}: canary caught at token {i} (expected — comparator has teeth)");
canary_caught = true;
}
Some(i) => {
println!("cycle {c} {label}: MISMATCH at token {i} (graph {} vs eager {})",
out.get(i).copied().unwrap_or(0), r.get(i).copied().unwrap_or(0));
cycle_ok = false;
}
}
}
println!("cycle {c}: {} [pool after L-drop: {:.0}/{:.0} MB, after S: {:.0}/{:.0} MB rsv/used]",
if cycle_ok { "OK" } else { "FAIL" }, mb(ra), mb(ua), mb(rb), mb(ub));
if !cycle_ok { fails += 1; }
}
{
let (mut sa, fa) = m.graph_session_new(&e, &prompt, small_budget)?;
let mut out_a = vec![fa];
for _ in 1..40 { out_a.push(sa.step(&e, &m)?); }
let (mut sb, fb) = m.graph_session_new(&e, &prompt, large_budget)?;
let mut out_b = vec![fb];
for _ in 1..40 { out_b.push(sb.step(&e, &m)?); }
for _ in 40..small_n { out_a.push(sa.step(&e, &m)?); } drop(sa); m.graph_session_recapture_pub(&e, &mut sb)?; for _ in 40..large_n { out_b.push(sb.step(&e, &m)?); }
let da = diff(&out_a, &ref_small);
let db = diff(&out_b, &ref_large);
if da.is_none() && db.is_none() {
println!("overlap arm: OK (A survived B's pool growth; B survived A's free + recapture)");
} else {
println!("overlap arm: MISMATCH (A diff {da:?}, B diff {db:?})");
fails += 1;
}
}
let (rz, uz) = pool_stats();
println!("[pool] end: reserved {:.0} MB used {:.0} MB", mb(rz), mb(uz));
if canary {
if canary_caught && fails == 0 {
println!("CANARY GATE PASS: injected graph-memory corruption was detected; all clean arms held");
Ok(())
} else {
Err(format!("CANARY GATE FAIL: caught={canary_caught} other_fails={fails}").into())
}
} else if fails == 0 {
println!("ALL GREEN: graph-warmup-stress ({cycles} cycles x 4 arms + overlap, bit-identical, no fault)");
Ok(())
} else {
Err(format!("graph-warmup-stress FAILED: {fails} failing cycle(s)").into())
}
}