use rane::{f32_to_fp16, mil, Buffer, Program};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let oc = 64usize;
let seq = 64usize;
println!("ANE reduce_sum fp32-accumulator test\n");
println!("--- 3 chunks of v=31 ic=32, each tile=30752 โ expected sum=92256 (>65504) ---");
test("3-chunk reduce_sum", 96, oc, seq, 31.0, 3, 92256)?;
println!("\n--- 4 chunks: expected sum=123008 ---");
test("4-chunk reduce_sum", 128, oc, seq, 31.0, 4, 123008)?;
println!("\n--- 8 chunks: expected sum=246016 ---");
test("8-chunk reduce_sum", 256, oc, seq, 31.0, 8, 246016)?;
println!("\n--- 68 chunks (Pearl scale): expected sum=2091136 ---");
test("Pearl 68-chunk", 2176, oc, seq, 31.0, 68, 2091136)?;
Ok(())
}
fn test(
label: &str,
ic: usize,
oc: usize,
seq: usize,
fill_val: f32,
n_chunks: usize,
expected: i32,
) -> Result<(), Box<dyn std::error::Error>> {
let program = mil::matmul_split_reduce(ic, oc, seq, n_chunks);
let mut model = match Program::compile(&program, &[]) {
Ok(m) => m,
Err(e) => {
let s = format!("{e}");
let short: String = s.chars().take(100).collect();
println!(" [{label}] compile FAILED: {short}");
return Ok(());
}
};
if let Err(e) = model.load() {
let s = format!("{e}");
let short: String = s.chars().take(100).collect();
println!(" [{label}] load FAILED: {short}");
return Ok(());
}
let input = Buffer::new(program.input_size())?;
let output = Buffer::new(program.output_size())?;
let sp = program.input_spatial;
let vfill = f32_to_fp16(fill_val);
input.write(|data| {
for d in data.iter_mut() {
*d = 0;
}
for ch in 0..ic {
for s in 0..seq {
data[ch * sp + s] = vfill;
}
for o in 0..oc {
data[ch * sp + seq + o] = vfill;
}
}
});
if let Err(e) = model.run(&input, &output) {
let s = format!("{e}");
let short: String = s.chars().take(100).collect();
println!(" [{label}] eval FAILED: {short}");
return Ok(());
}
let (val_str, correct) = output.read_f32(|data| {
let n = oc * seq;
let v0 = data[0];
let n_correct = data[..n].iter().filter(|&&v| v as i32 == expected).count();
(format!("{v0:.1}"), n_correct == n)
});
let status = if correct { "โ" } else { "โ" };
println!(" [{label:24}] got={val_str:>14} expected={expected:>10} {status}");
Ok(())
}