use rane::mil;
use rane::Program;
use std::fmt::Write as _;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let ic = 8usize;
let oc = 8usize;
let seq = 8usize;
let program = mil::matmul(ic, oc, seq);
println!("Compiling matmul({ic}ร{oc}, seq={seq})...");
let model = Program::compile(&program, &[])?;
println!(" tmp_dir: {}", model.tmp_dir().display());
println!();
dump_dir(model.tmp_dir(), 0);
drop(model);
Ok(())
}
fn dump_dir(dir: &std::path::Path, depth: usize) {
let indent = " ".repeat(depth);
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
let mut entries: Vec<_> = entries.flatten().collect();
entries.sort_by_key(|e| e.file_name());
for entry in entries {
let path = entry.path();
let name = entry.file_name();
let name = name.to_string_lossy();
let meta = entry.metadata().unwrap();
if meta.is_dir() {
println!("{indent}[dir] {name}/");
dump_dir(&path, depth + 1);
} else {
let size = meta.len();
println!("{indent}[file] {name} ({size} bytes)");
match std::fs::read(&path) {
Ok(data) => {
hex_dump(&data, (size.min(512)) as usize, depth + 1);
if size > 512 {
search_dtype_candidates(&data, depth + 1);
}
}
Err(e) => println!("{indent} <read error: {e}>"),
}
}
}
}
fn hex_dump(data: &[u8], max: usize, depth: usize) {
let indent = " ".repeat(depth);
let n = data.len().min(max);
for row in 0..(n + 15) / 16 {
let lo = row * 16;
let hi = (lo + 16).min(n);
let mut hex = String::new();
let mut asc = String::new();
for &b in &data[lo..hi] {
let _ = write!(hex, "{b:02x} ");
asc.push(if b.is_ascii_graphic() || b == b' ' {
b as char
} else {
'.'
});
}
println!("{indent}{lo:06x} {hex:<48} {asc}");
}
if data.len() > max {
println!(
"{indent} ... ({} bytes total, showing first {max})",
data.len()
);
}
}
fn search_dtype_candidates(data: &[u8], depth: usize) {
let indent = " ".repeat(depth);
println!("{indent}--- dtype candidate scan (looking for 0x01/0x02/0x03 at likely offsets) ---");
let magic = [0xEFu8, 0xBE, 0xAD, 0xDE];
let mut found = false;
for i in 0..data.len().saturating_sub(8) {
if data[i..i + 4] == magic {
let ctx_start = i.saturating_sub(16);
let ctx_end = (i + 32).min(data.len());
println!("{indent} DEADBEEF @ 0x{i:x}:");
hex_dump(&data[ctx_start..ctx_end], 64, depth + 2);
found = true;
}
}
if !found {
println!("{indent} no DEADBEEF magic found");
}
let f32_one = 1.0f32.to_bits().to_le_bytes();
let mut f32_count = 0usize;
for i in 0..data.len().saturating_sub(4) {
if data[i..i + 4] == f32_one {
let ctx_start = i.saturating_sub(8);
let ctx_end = (i + 12).min(data.len());
if f32_count < 5 {
println!(
"{indent} f32(1.0) @ 0x{i:x}: {:?}",
&data[ctx_start..ctx_end]
);
}
f32_count += 1;
}
}
if f32_count > 0 {
println!("{indent} total f32(1.0) occurrences: {f32_count}");
}
if data.len() > 64 {
println!("{indent}--- last 64 bytes ---");
hex_dump(&data[data.len() - 64..], 64, depth + 1);
}
}