use memra_engine::Engine;
use memra_engine::dflash::DflashDraft;
fn read_f32(p: &str) -> Vec<f32> {
let b = std::fs::read(p).unwrap_or_else(|e| panic!("{p}: {e}"));
b.chunks_exact(4)
.map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]]))
.collect()
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let ckpt = std::env::args()
.nth(1)
.unwrap_or_else(|| "/data/ai-ml/hf-models/dspark-gemma4-31b-draft/backbone-only".into());
let cache = std::env::args()
.nth(2)
.unwrap_or_else(|| "/data/cache".into());
let e = Engine::new(0)?;
let m = DflashDraft::load(&e, std::path::Path::new(&ckpt))?;
let c = &m.cfg;
println!(
"loaded dflash draft: {} layers, hidden {}, block {}, taps {:?}",
c.n_layer, c.hidden, c.block_size, c.target_layer_ids
);
let th = read_f32(&format!("{cache}/dflash-target_hidden.f32"));
let ne = read_f32(&format!("{cache}/dflash-noise_embedding.f32"));
let ctx = th.len() / (c.target_layer_ids.len() * c.hidden);
assert_eq!(ne.len(), c.block_size * c.hidden);
let th_d = e.htod(&th)?;
let ne_d = e.htod(&ne)?;
let pos: Vec<i32> = (0..(ctx + c.block_size) as i32).collect();
let out = m.forward(&e, &th_d, &ne_d, &pos, ctx)?;
let got = e.dtoh(&out)?;
let want = read_f32(&format!("{cache}/dflash-final.f32"));
assert_eq!(got.len(), want.len());
let (mut md, mut mi) = (0f32, 0usize);
for (i, (a, b)) in got.iter().zip(&want).enumerate() {
let d = (a - b).abs();
if d > md {
md = d;
mi = i;
}
}
let mx = want.iter().fold(0f32, |a, v| a.max(v.abs()));
let rel = md / mx;
println!(
"final: maxdiff {md:.3e} (idx {mi}: got {} want {}), max|ref| {mx:.2}, rel-to-max {rel:.3e}",
got[mi], want[mi]
);
let pass = rel < 2e-3;
println!("DFLASH-PARITY: {}", if pass { "PASS" } else { "FAIL" });
std::process::exit(if pass { 0 } else { 1 });
}