use std::io::{Read, Write};
use std::path::Path;
use anyhow::Result;
use crate::model::TernModel;
pub fn write_tern<W: Write>(writer: &mut W, model: &TernModel) -> Result<()> {
let bytes = bincode::serialize(model)?;
writer.write_all(&bytes)?;
Ok(())
}
pub fn read_tern<R: Read>(reader: &mut R) -> Result<TernModel> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes)?;
let model = bincode::deserialize(&bytes)?;
Ok(model)
}
pub fn save_tern(path: &Path, model: &TernModel) -> Result<()> {
let mut f = std::fs::File::create(path)?;
write_tern(&mut f, model)
}
pub fn load_tern(path: &Path) -> Result<TernModel> {
let mut f = std::fs::File::open(path)?;
read_tern(&mut f)
}
#[allow(dead_code)]
pub fn load_gguf(_path: &Path) -> Result<Vec<(String, Vec<f32>, Vec<usize>)>> {
anyhow::bail!(
"GGUF loader not yet implemented. \
Enable the `gguf` feature and implement load_gguf() in format.rs. \
See TODO comment above for the implementation guide."
)
}
#[allow(dead_code)]
pub fn load_safetensors(_dir: &Path) -> Result<Vec<(String, Vec<f32>, Vec<usize>)>> {
anyhow::bail!(
"SafeTensors loader not yet implemented. \
Enable the `safetensors` feature and implement load_safetensors() in format.rs."
)
}
pub fn synthetic_layers(
n_layers: usize,
hidden: usize,
seed: u64,
) -> Vec<(String, Vec<f32>, Vec<usize>)> {
let mut state = seed.wrapping_add(1);
let mut next_f32 = move || -> f32 {
state = state.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
let bits = (state >> 33) as u32;
(bits as f32 / u32::MAX as f32) * 4.0 - 2.0
};
(0..n_layers).map(|i| {
let name = format!("model.layers.{i}.mlp.weight");
let weights: Vec<f32> = (0..hidden * hidden).map(|_| next_f32()).collect();
let shape = vec![hidden, hidden];
(name, weights, shape)
}).collect()
}