//! Real-model bring-up for OpenVINO IR files. Pass the //! `.xml` path — the sibling `.bin` is auto-resolved. //! //! ```bash //! cargo run --release --example load_openvino -- path/to/model.xml //! ``` use jouleclaw_loader_gguf::openvino::read_openvino_ir; use std::collections::BTreeMap; use std::path::PathBuf; use std::time::Instant; fn main() -> Result<(), Box> { let args: Vec = std::env::args().collect(); if args.len() < 2 { eprintln!("usage: load_openvino "); std::process::exit(1); } let path = PathBuf::from(&args[1]); println!("xml: {}", path.display()); let t0 = Instant::now(); let m = read_openvino_ir(&path).map_err(|e| format!("parse: {:?}", e))?; let load_secs = t0.elapsed().as_secs_f64(); println!("bin: {}", m.bin_path.display()); println!(); println!("=== load ==="); println!(" load_wall_clock_secs: {:.3}", load_secs); println!(" net_name: {}", m.net_name); println!(" ir_version: {}", m.ir_version); println!(" const_count: {}", m.tensors.len()); println!(" bin_size: {} ({})", m.bin_mmap.len(), humanize_bytes(m.bin_mmap.len() as u64)); let total_data: u64 = m.tensors.iter().map(|t| t.bin_size).sum(); println!(); println!("=== tensor data ==="); println!( " total_const_bytes: {} ({})", total_data, humanize_bytes(total_data), ); // Dtype distribution. let mut counts: BTreeMap = BTreeMap::new(); for t in &m.tensors { let key = format!("{:?}", t.dtype); let e = counts.entry(key).or_insert((0, 0)); e.0 += 1; e.1 += t.bin_size; } println!(); println!("=== dtype distribution ==="); for (k, (c, b)) in &counts { println!(" {:<14} count={:>5} size={}", k, c, humanize_bytes(*b)); } // Top 10 tensors. let mut sorted: Vec<&_> = m.tensors.iter().collect(); sorted.sort_by_key(|a| std::cmp::Reverse(a.bin_size)); println!(); println!("=== top 10 tensors by byte size ==="); for t in sorted.iter().take(10) { println!( " {:?} {:<60} {:>14} ({})", t.dtype, truncate(&t.name, 60), t.bin_size, humanize_bytes(t.bin_size), ); } Ok(()) } fn truncate(s: &str, max: usize) -> String { if s.len() <= max { s.to_string() } else { format!("…{}", &s[s.len() - max + 1..]) } } fn humanize_bytes(n: u64) -> String { const KB: u64 = 1024; const MB: u64 = KB * 1024; const GB: u64 = MB * 1024; if n >= GB { format!("{:.2} GiB", n as f64 / GB as f64) } else if n >= MB { format!("{:.2} MiB", n as f64 / MB as f64) } else if n >= KB { format!("{:.2} KiB", n as f64 / KB as f64) } else { format!("{} B", n) } }