use candle_core::{Device, Tensor};
use cortex_rust::layers::bit_linear::BitLinear;
mod common;
#[test]
fn test_load_packed_real_model() {
let model_path = common::get_test_model_safetensors();
if !model_path.exists() {
eprintln!("Skipping test: model not found at {:?}", model_path);
return;
}
println!("Using model at: {:?}", model_path);
println!("Using model at: {:?}", model_path);
let device = Device::Cpu;
let tensors =
candle_core::safetensors::load(model_path, &device).expect("Failed to load safetensors");
println!("Loaded {} tensors", tensors.len());
let layer_prefix = "model.layers.0.mlp.gate_proj";
let packed_key = format!("{}.weight_packed", layer_prefix);
let scales_key = format!("{}.scales", layer_prefix);
let packed = tensors
.get(&packed_key)
.unwrap_or_else(|| panic!("Missing {}", packed_key));
let scales = tensors
.get(&scales_key)
.unwrap_or_else(|| panic!("Missing {}", scales_key));
println!(
"weight_packed shape: {:?}, dtype: {:?}",
packed.dims(),
packed.dtype()
);
println!(
"scales shape: {:?}, dtype: {:?}",
scales.dims(),
scales.dtype()
);
let dims = packed.dims();
let (out_dim, in_dim) = match dims.len() {
2 => (dims[0], dims[1] * 4),
3 => (dims[0], dims[1] * 4),
_ => panic!("Unexpected tensor shape: {:?}", dims),
};
println!("Layer: out_dim={}, in_dim={}", out_dim, in_dim);
let layer = BitLinear::from_packed_tensors(packed, scales, &device)
.expect("Failed to from_packed_tensors");
println!("BitLinear created successfully!");
println!(" in_features: {}", in_dim);
println!(" out_features: {}", out_dim);
let x = Tensor::randn(0.0f32, 1.0, (1, in_dim), &device).expect("Failed to create input");
let output = layer.forward(&x).expect("Forward pass failed");
println!("Output shape: {:?}", output.dims());
let output_vec = output
.flatten_all()
.expect("Flatten failed")
.to_vec1::<f32>()
.expect("to_vec1 failed");
let has_nan = output_vec.iter().any(|&v| v.is_nan());
let has_inf = output_vec.iter().any(|&v| v.is_infinite());
assert!(!has_nan, "Output contains NaN!");
assert!(!has_inf, "Output contains Inf!");
let sum: f32 = output_vec.iter().map(|v| v.abs()).sum();
assert!(sum > 1e-6, "Output is all zeros!");
println!("✅ Output valid: no NaN/Inf, sum={:.4}", sum);
}