use crate::quantize::{
dequantize_q8_blocks, fused_q4_0_q8_0_parallel_matvec, fused_q4_0_q8_0_parallel_matvec_into,
fused_q8_0_q8_0_parallel_matvec, fused_q8_0_q8_0_parallel_matvec_into,
quantize_activations_q8k_into, quantize_to_q8_blocks, InterleavedQ4K,
};
#[test]
fn test_interleaved_q4k_from_q4k_invalid_length() {
let invalid_data = vec![0u8; 143]; let result = InterleavedQ4K::from_q4k(&invalid_data);
assert!(
result.is_err(),
"Should fail with 143 bytes (not multiple of 144)"
);
let err_msg = format!("{:?}", result.unwrap_err());
assert!(
err_msg.contains("multiple") || err_msg.contains("144"),
"Error should mention super-block size: {}",
err_msg
);
}
#[test]
fn test_interleaved_q4k_from_q4k_partial_superblock() {
let invalid_data = vec![0u8; 145];
let result = InterleavedQ4K::from_q4k(&invalid_data);
assert!(result.is_err());
}
#[test]
fn test_interleaved_q4k_from_q4k_empty() {
let empty_data: Vec<u8> = vec![];
let result = InterleavedQ4K::from_q4k(&empty_data);
assert!(result.is_ok());
let interleaved = result.expect("test value should be present");
assert_eq!(interleaved.num_values(), 0);
}
#[test]
fn test_interleaved_q4k_dot_dimension_mismatch() {
let data = vec![0u8; 144];
let interleaved = InterleavedQ4K::from_q4k(&data).expect("test value should be present");
assert_eq!(interleaved.num_values(), 256);
let activations = vec![1.0f32; 128]; let result = interleaved.dot(&activations);
assert!(result.is_err());
let err_msg = format!("{:?}", result.unwrap_err());
assert!(
err_msg.contains("128") || err_msg.contains("256"),
"Error should mention dimension mismatch: {}",
err_msg
);
}
#[test]
fn test_interleaved_q4k_dot_extra_activations() {
let data = vec![0u8; 144];
let interleaved = InterleavedQ4K::from_q4k(&data).expect("test value should be present");
let activations = vec![1.0f32; 512]; let result = interleaved.dot(&activations);
assert!(result.is_err());
}
#[test]
fn test_fused_q4_0_q8_0_parallel_matvec_weight_too_small() {
let in_dim = 64;
let out_dim = 4;
let bytes_per_row = (in_dim / 32) * 18;
let weight_data = vec![0u8; out_dim * bytes_per_row - 1];
let activations = vec![1.0f32; in_dim];
let result = fused_q4_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_err());
}
#[test]
fn test_fused_q4_0_q8_0_parallel_matvec_activation_mismatch() {
let in_dim = 64;
let out_dim = 4;
let bytes_per_row = (in_dim / 32) * 18;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim + 1];
let result = fused_q4_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_err());
}
#[test]
fn test_fused_q4_0_q8_0_parallel_matvec_large_matrix() {
let in_dim = 64;
let out_dim = 1024;
let bytes_per_row = (in_dim / 32) * 18;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim];
let result = fused_q4_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_ok());
assert_eq!(result.expect("test value should be present").len(), out_dim);
}
#[test]
fn test_fused_q4_0_q8_0_parallel_matvec_into_activation_mismatch() {
let in_dim = 64;
let out_dim = 8;
let bytes_per_row = (in_dim / 32) * 18;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim + 1]; let mut output = vec![0.0f32; out_dim];
let result =
fused_q4_0_q8_0_parallel_matvec_into(&weight_data, &activations, in_dim, &mut output);
assert!(result.is_err());
}
#[test]
fn test_fused_q4_0_q8_0_parallel_matvec_into_success() {
let in_dim = 64;
let out_dim = 8;
let bytes_per_row = (in_dim / 32) * 18;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim];
let mut output = vec![0.0f32; out_dim];
let result =
fused_q4_0_q8_0_parallel_matvec_into(&weight_data, &activations, in_dim, &mut output);
assert!(result.is_ok());
}
#[test]
fn test_fused_q8_0_q8_0_parallel_matvec_weight_too_small() {
let in_dim = 64;
let out_dim = 4;
let bytes_per_row = (in_dim / 32) * 34;
let weight_data = vec![0u8; out_dim * bytes_per_row - 1];
let activations = vec![1.0f32; in_dim];
let result = fused_q8_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_err());
}
#[test]
fn test_fused_q8_0_q8_0_parallel_matvec_activation_mismatch() {
let in_dim = 64;
let out_dim = 4;
let bytes_per_row = (in_dim / 32) * 34;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim - 1];
let result = fused_q8_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_err());
}
#[test]
fn test_fused_q8_0_q8_0_parallel_matvec_large() {
let in_dim = 64;
let out_dim = 1024;
let bytes_per_row = (in_dim / 32) * 34;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim];
let result = fused_q8_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_ok());
assert_eq!(result.expect("test value should be present").len(), out_dim);
}
#[test]
fn test_fused_q8_0_q8_0_parallel_matvec_into_output_small() {
let in_dim = 64;
let out_dim = 8;
let bytes_per_row = (in_dim / 32) * 34;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim];
let mut output = vec![0.0f32; out_dim - 1];
let result = fused_q8_0_q8_0_parallel_matvec_into(
&weight_data,
&activations,
in_dim,
out_dim,
&mut output,
);
assert!(result.is_err());
}
#[test]
fn test_fused_q8_0_q8_0_parallel_matvec_into_success() {
let in_dim = 64;
let out_dim = 8;
let bytes_per_row = (in_dim / 32) * 34;
let weight_data = vec![0u8; out_dim * bytes_per_row];
let activations = vec![1.0f32; in_dim];
let mut output = vec![0.0f32; out_dim];
let result = fused_q8_0_q8_0_parallel_matvec_into(
&weight_data,
&activations,
in_dim,
out_dim,
&mut output,
);
assert!(result.is_ok());
}
#[test]
fn test_quantize_activations_q8k_into_buffers_small() {
let activations = vec![1.0f32; 512]; let mut scales = vec![0.0f32; 1]; let mut quants = vec![0i8; 512];
let result = quantize_activations_q8k_into(&activations, &mut scales, &mut quants);
assert!(result.is_err());
}
#[test]
fn test_quantize_activations_q8k_into_quants_small() {
let activations = vec![1.0f32; 512];
let mut scales = vec![0.0f32; 2];
let mut quants = vec![0i8; 256];
let result = quantize_activations_q8k_into(&activations, &mut scales, &mut quants);
assert!(result.is_err());
}
#[test]
fn test_quantize_activations_q8k_into_non_aligned() {
let activations = vec![1.0f32; 300]; let mut scales = vec![0.0f32; 2];
let mut quants = vec![0i8; 512];
let result = quantize_activations_q8k_into(&activations, &mut scales, &mut quants);
assert!(result.is_err());
}
#[test]
fn test_quantize_activations_q8k_into_success() {
let activations = vec![1.0f32; 512];
let mut scales = vec![0.0f32; 2];
let mut quants = vec![0i8; 512];
let result = quantize_activations_q8k_into(&activations, &mut scales, &mut quants);
assert!(result.is_ok());
}
#[test]
fn test_quantize_to_q8_blocks_empty() {
let values: Vec<f32> = vec![];
let result = quantize_to_q8_blocks(&values);
assert!(result.is_ok());
assert!(result.expect("test value should be present").is_empty());
}
#[test]
fn test_quantize_to_q8_blocks_non_aligned() {
let values = vec![1.0f32; 50]; let result = quantize_to_q8_blocks(&values);
assert!(result.is_err());
}
#[test]
fn test_quantize_to_q8_blocks_special_values() {
let mut values = vec![0.0f32; 32];
values[0] = f32::INFINITY;
values[1] = f32::NEG_INFINITY;
values[2] = f32::NAN;
let result = quantize_to_q8_blocks(&values);
let _ = result;
}
#[test]
fn test_q8_block_round_trip() {
let original: Vec<f32> = (0..64).map(|i| (i as f32 - 32.0) / 10.0).collect();
let blocks = quantize_to_q8_blocks(&original).expect("test value should be present");
assert_eq!(blocks.len(), 2);
let reconstructed = dequantize_q8_blocks(&blocks);
assert_eq!(reconstructed.len(), original.len());
for (orig, recon) in original.iter().zip(reconstructed.iter()) {
let diff = (orig - recon).abs();
assert!(
diff < 0.5,
"Round-trip error too large: {} -> {}",
orig,
recon
);
}
}
#[test]
fn test_interleaved_q4k_dot_zero_weights() {
let data = vec![0u8; 144];
let interleaved = InterleavedQ4K::from_q4k(&data).expect("test value should be present");
let activations = vec![1.0f32; 256];
let result = interleaved.dot(&activations).expect("test value should be present");
assert!(result.abs() < 1e-6);
}
#[test]
fn test_interleaved_q4k_dot_large_values() {
let mut data = vec![0u8; 144];
data[0] = 0x00;
data[1] = 0x3C;
let interleaved = InterleavedQ4K::from_q4k(&data).expect("test value should be present");
let activations = vec![1000.0f32; 256];
let result = interleaved.dot(&activations).expect("test value should be present");
assert!(result.is_finite());
}
#[test]
fn test_interleaved_q4k_dot_multiple_superblocks() {
let num_superblocks = 8;
let mut data = vec![0u8; num_superblocks * 144];
for sb in 0..num_superblocks {
let offset = sb * 144;
data[offset] = 0x00;
data[offset + 1] = 0x3C;
}
let interleaved = InterleavedQ4K::from_q4k(&data).expect("test value should be present");
assert_eq!(interleaved.num_values(), num_superblocks * 256);
let activations = vec![1.0f32; interleaved.num_values()];
let result = interleaved.dot(&activations).expect("test value should be present");
assert!(result.is_finite());
}
#[test]
fn test_minimum_q4_0_matvec() {
let in_dim = 32;
let out_dim = 1;
let weight_data = vec![0u8; 18];
let activations = vec![1.0f32; in_dim];
let result = fused_q4_0_q8_0_parallel_matvec(&weight_data, &activations, in_dim, out_dim);
assert!(result.is_ok());
}
include!("minimum_exactly.rs");