#[test]
fn test_q4_1_matmul_integration() {
use trueno::{Matrix as TruenoMatrix, Vector as TruenoVector};
let in_dim = 32;
let out_dim = 2;
let mut data = vec![0u8; 40];
data[0..2].copy_from_slice(&half::f16::from_f32(1.0).to_le_bytes());
data[2..4].copy_from_slice(&half::f16::from_f32(0.0).to_le_bytes());
data[4] = 0x10;
data[20..22].copy_from_slice(&half::f16::from_f32(1.0).to_le_bytes());
data[22..24].copy_from_slice(&half::f16::from_f32(0.0).to_le_bytes());
for i in 24..40 {
data[i] = 0x11;
}
let weights_f32 = dequantize_q4_1(&data).expect("dequantization failed");
assert_eq!(weights_f32.len(), out_dim * in_dim);
eprintln!("Row 0 (first 20): {:?}", &weights_f32[0..20]);
eprintln!("Row 0 positions 16-20: {:?}", &weights_f32[16..20]);
eprintln!("Row 1 (first 20): {:?}", &weights_f32[32..52]);
let weight_matrix = TruenoMatrix::from_vec(out_dim, in_dim, weights_f32.clone())
.expect("matrix creation failed");
let activations = vec![1.0f32; in_dim];
let x_vec = TruenoVector::from_slice(&activations);
let result = weight_matrix.matvec(&x_vec).expect("matvec failed");
eprintln!("Matmul result: {:?}", result.as_slice());
let expected_row0: f32 = weights_f32[0..32].iter().sum();
let expected_row1: f32 = weights_f32[32..64].iter().sum();
eprintln!("Expected row 0 sum (manual): {}", expected_row0);
eprintln!("Expected row 1 sum (manual): {}", expected_row1);
let row0_sum = result.as_slice()[0];
let row1_sum = result.as_slice()[1];
assert!(
(row0_sum - expected_row0).abs() < 0.1,
"Row 0 sum should be {}, got {}",
expected_row0,
row0_sum
);
assert!(
(row1_sum - expected_row1).abs() < 0.1,
"Row 1 sum should be {}, got {}",
expected_row1,
row1_sum
);
}
#[test]
fn test_q4_1_matmul_large_dimensions() {
use trueno::{Matrix as TruenoMatrix, Vector as TruenoVector};
let in_dim = 896;
let out_dim = 896;
let blocks_per_row = in_dim / 32;
let bytes_per_row = blocks_per_row * 20;
let total_bytes = out_dim * bytes_per_row;
let mut data = vec![0u8; total_bytes];
data[0..2].copy_from_slice(&half::f16::from_f32(1.0).to_le_bytes());
data[2..4].copy_from_slice(&half::f16::from_f32(0.0).to_le_bytes());
for i in 4..bytes_per_row {
if i >= 4 && (i - 4) % 20 < 16 {
data[i] = 0x11;
}
}
let weights_f32 = dequantize_q4_1(&data).expect("dequantization failed");
assert_eq!(
weights_f32.len(),
out_dim * in_dim,
"Dequantized size mismatch: {} vs {}",
weights_f32.len(),
out_dim * in_dim
);
let weight_matrix =
TruenoMatrix::from_vec(out_dim, in_dim, weights_f32).expect("matrix creation failed");
let activations = vec![1.0f32; in_dim];
let x_vec = TruenoVector::from_slice(&activations);
let result = weight_matrix.matvec(&x_vec).expect("matvec failed");
assert_eq!(result.len(), out_dim);
let row0_sum = result.as_slice()[0];
assert!(
row0_sum.abs() > 0.1,
"Row 0 should have non-zero output, got {}",
row0_sum
);
for (i, &v) in result.as_slice().iter().enumerate() {
assert!(v.is_finite(), "Output at {} is not finite: {}", i, v);
}
}
#[test]
fn test_q4_1_not_interleaved_layout() {
let mut block = vec![0u8; 20];
block[0..2].copy_from_slice(&half::f16::from_f32(1.0).to_le_bytes());
block[2..4].copy_from_slice(&half::f16::from_f32(0.0).to_le_bytes());
block[4] = 0x10;
let result = dequantize_q4_1(&block).expect("dequantization failed");
assert!(
(result[1] - 0.0).abs() < 1e-5,
"INTERLEAVED LAYOUT DETECTED! pos 1 should be 0.0 (candle), got {} (interleaved would give 1.0)",
result[1]
);
assert!(
(result[16] - 1.0).abs() < 1e-5,
"CANDLE LAYOUT BROKEN! pos 16 should be 1.0, got {}",
result[16]
);
}
#[test]
fn test_q4_0_fused_vs_dequantize_matmul() {
use trueno::{Matrix as TruenoMatrix, Vector as TruenoVector};
let in_dim = 32;
let out_dim = 2;
let bytes_per_row = 18;
let total_bytes = out_dim * bytes_per_row;
let mut data = vec![0u8; total_bytes];
data[0..2].copy_from_slice(&half::f16::from_f32(1.0).to_le_bytes());
for i in 0..16 {
data[2 + i] = (8 << 4) | (i as u8);
}
data[18..20].copy_from_slice(&half::f16::from_f32(2.0).to_le_bytes());
for i in 0..16 {
data[20 + i] = 0x99;
}
let activations = vec![1.0f32; in_dim];
let fused_result = fused_q4_0_q8_0_parallel_matvec(&data, &activations, in_dim, out_dim)
.expect("fused matmul failed");
let weights_f32 = dequantize_q4_0(&data).expect("dequantize failed");
let weight_matrix = TruenoMatrix::from_vec(out_dim, in_dim, weights_f32.clone())
.expect("matrix creation failed");
let x_vec = TruenoVector::from_slice(&activations);
let reference_result = weight_matrix.matvec(&x_vec).expect("matvec failed");
eprintln!("Q4_0 Fused result: {:?}", fused_result);
eprintln!("Q4_0 Reference result: {:?}", reference_result.as_slice());
eprintln!("Q4_0 Row 0 weights (first 20): {:?}", &weights_f32[0..20]);
eprintln!("Q4_0 Row 0 weights (pos 16-20): {:?}", &weights_f32[16..20]);
for i in 0..out_dim {
let fused_val = fused_result[i];
let ref_val = reference_result.as_slice()[i];
let diff = (fused_val - ref_val).abs();
assert!(
diff < 1.0,
"Q4_0 MISMATCH at row {}: fused={}, reference={}, diff={}",
i,
fused_val,
ref_val,
diff
);
}
}
#[test]
fn test_q4_0_fused_matmul_qwen_dimensions() {
use trueno::{Matrix as TruenoMatrix, Vector as TruenoVector};
let in_dim: usize = 896;
let out_dim: usize = 128;
let blocks_per_row = in_dim.div_ceil(32);
let bytes_per_row = blocks_per_row * 18;
let total_bytes = out_dim * bytes_per_row;
let mut data = vec![0u8; total_bytes];
for row in 0..out_dim {
let row_start = row * bytes_per_row;
for block in 0..blocks_per_row {
let block_start = row_start + block * 18;
let scale = 0.1 + (row as f32) * 0.01;
data[block_start..block_start + 2]
.copy_from_slice(&half::f16::from_f32(scale).to_le_bytes());
for i in 0..16 {
data[block_start + 2 + i] =
(((row + block + i) % 16) << 4 | ((row + i) % 16)) as u8;
}
}
}
let activations: Vec<f32> = (0..in_dim).map(|i| (i as f32 * 0.01).sin()).collect();
let fused_result = fused_q4_0_q8_0_parallel_matvec(&data, &activations, in_dim, out_dim)
.expect("fused matmul failed");
let weights_f32 = dequantize_q4_0(&data).expect("dequantize failed");
let weight_matrix =
TruenoMatrix::from_vec(out_dim, in_dim, weights_f32).expect("matrix creation failed");
let x_vec = TruenoVector::from_slice(&activations);
let reference_result = weight_matrix.matvec(&x_vec).expect("matvec failed");
let mut max_diff = 0.0f32;
let mut max_diff_idx = 0;
for i in 0..out_dim {
let diff = (fused_result[i] - reference_result.as_slice()[i]).abs();
if diff > max_diff {
max_diff = diff;
max_diff_idx = i;
}
}
eprintln!(
"Q4_0 Qwen dims: max diff = {} at row {}",
max_diff, max_diff_idx
);
eprintln!("Fused[{}] = {}", max_diff_idx, fused_result[max_diff_idx]);
eprintln!(
"Reference[{}] = {}",
max_diff_idx,
reference_result.as_slice()[max_diff_idx]
);
assert!(
max_diff < 50.0,
"Q4_0 fused vs reference max diff {} is too large (indicates bug)",
max_diff
);
}