#[cfg(test)]
mod tests_falsification_bb {
use super::*;
#[test]
fn test_bb1_q4_0_roundtrip_error_under_5_percent() {
let data: Vec<f32> = (0..1024)
.map(|i| {
let x = (i as f32 - 512.0) / 512.0; x * 0.1 })
.collect();
let shape = vec![1024];
let quantized = quantize(&data, &shape, QuantType::Q4_0).expect("quantize failed");
let dequantized = dequantize(&quantized).expect("dequantize failed");
let mut total_sq_error = 0.0_f64;
let mut total_sq_orig = 0.0_f64;
for (orig, deq) in data.iter().zip(dequantized.iter()) {
total_sq_error += ((*orig - *deq) as f64).powi(2);
total_sq_orig += (*orig as f64).powi(2);
}
let relative_error = if total_sq_orig > 0.0 {
(total_sq_error / total_sq_orig).sqrt()
} else {
0.0
};
assert!(
relative_error < 0.05,
"BB1 FALSIFIED: Q4_0 relative error {:.2}% exceeds 5% threshold",
relative_error * 100.0
);
}
#[test]
fn test_bb3_quantization_deterministic() {
let data: Vec<f32> = (0..128).map(|i| (i as f32 - 64.0) * 0.01).collect();
let shape = vec![128];
let mut results: Vec<Vec<u8>> = Vec::new();
for _ in 0..10 {
let quantized = quantize(&data, &shape, QuantType::Q8_0).expect("quantize");
results.push(quantized.blocks.clone());
}
let first = &results[0];
for (i, result) in results.iter().enumerate().skip(1) {
assert_eq!(
first, result,
"BB3 FALSIFIED: Quantization run {} differs from run 0",
i
);
}
}
#[test]
fn test_bb3_q4_0_deterministic() {
let data: Vec<f32> = (0..128).map(|i| (i as f32 - 64.0) * 0.01).collect();
let shape = vec![128];
let q1 = quantize(&data, &shape, QuantType::Q4_0).expect("quantize 1");
let q2 = quantize(&data, &shape, QuantType::Q4_0).expect("quantize 2");
assert_eq!(
q1.blocks, q2.blocks,
"BB3 FALSIFIED: Q4_0 quantization is non-deterministic"
);
}
#[test]
fn test_bb4_block_size_is_32() {
assert_eq!(
BLOCK_SIZE, 32,
"BB4 FALSIFIED: Block size is {} instead of 32",
BLOCK_SIZE
);
}
#[test]
fn test_bb4_quantized_block_size_correct() {
let data: Vec<f32> = vec![1.0; 64]; let shape = vec![64];
let quantized = quantize(&data, &shape, QuantType::Q8_0).expect("quantize");
assert_eq!(
quantized.block_size, 32,
"BB4 FALSIFIED: QuantizedBlock has wrong block_size: {}",
quantized.block_size
);
}
#[test]
fn test_bb5_scale_factors_correct() {
let data: Vec<f32> = vec![127.0; 32]; let shape = vec![32];
let quantized = quantize(&data, &shape, QuantType::Q8_0).expect("quantize");
let scale_bytes = [quantized.blocks[0], quantized.blocks[1]];
let scale = f16::from_le_bytes(scale_bytes).to_f32();
assert!(
(scale - 1.0).abs() < 0.01,
"BB5 FALSIFIED: Scale {:.4} != expected 1.0",
scale
);
let dequantized = dequantize(&quantized).expect("dequantize");
for (i, (orig, deq)) in data.iter().zip(dequantized.iter()).enumerate() {
assert!(
(orig - deq).abs() < 0.5,
"BB5 FALSIFIED: Element {} differs: {} vs {}",
i,
orig,
deq
);
}
}
#[test]
fn test_bb6_mixed_quantization_no_corruption() {
let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
let shape = vec![64];
let q8 = quantize(&data, &shape, QuantType::Q8_0).expect("Q8_0");
let q4 = quantize(&data, &shape, QuantType::Q4_0).expect("Q4_0");
let d8 = dequantize(&q8).expect("dequantize Q8_0");
let d4 = dequantize(&q4).expect("dequantize Q4_0");
assert_eq!(d8.len(), data.len(), "BB6 FALSIFIED: Q8_0 length mismatch");
assert_eq!(d4.len(), data.len(), "BB6 FALSIFIED: Q4_0 length mismatch");
let mse8 = quantization_mse(&data, &d8);
let mse4 = quantization_mse(&data, &d4);
assert!(
mse8 < mse4,
"BB6 FALSIFIED: Q8_0 MSE ({}) should be less than Q4_0 MSE ({})",
mse8,
mse4
);
}
}
#[cfg(test)]
mod tests_proptest_bb {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn prop_bb3_quantization_deterministic(
weights in prop::collection::vec(-1.0f32..1.0, 32..256),
) {
let shape = vec![weights.len()];
let q1 = quantize(&weights, &shape, QuantType::Q8_0).expect("quantize 1");
let q2 = quantize(&weights, &shape, QuantType::Q8_0).expect("quantize 2");
prop_assert_eq!(
q1.blocks, q2.blocks,
"BB3-PROP FALSIFIED: Non-deterministic quantization"
);
}
#[test]
fn prop_bb1_q8_roundtrip_bounded(
weights in prop::collection::vec(-10.0f32..10.0, 32..256),
) {
let shape = vec![weights.len()];
let quantized = quantize(&weights, &shape, QuantType::Q8_0).expect("quantize");
let dequantized = dequantize(&quantized).expect("dequantize");
let mse: f64 = weights.iter()
.zip(dequantized.iter())
.map(|(o, d)| ((*o - *d) as f64).powi(2))
.sum::<f64>() / weights.len() as f64;
prop_assert!(
mse < 0.1,
"BB1-PROP FALSIFIED: Q8_0 MSE {} exceeds 0.1",
mse
);
}
#[test]
fn prop_bb5_scale_positive(
weights in prop::collection::vec(0.1f32..1.0, 32..64),
) {
let shape = vec![weights.len()];
let quantized = quantize(&weights, &shape, QuantType::Q8_0).expect("quantize");
if quantized.blocks.len() >= 2 {
let scale_bytes = [quantized.blocks[0], quantized.blocks[1]];
let scale = f16::from_le_bytes(scale_bytes).to_f32();
prop_assert!(
scale > 0.0,
"BB5-PROP FALSIFIED: Scale {} is not positive",
scale
);
}
}
#[test]
fn prop_bb6_q8_more_accurate_than_q4(
weights in prop::collection::vec(-1.0f32..1.0, 64..128),
) {
let shape = vec![weights.len()];
let q8 = quantize(&weights, &shape, QuantType::Q8_0).expect("Q8_0");
let q4 = quantize(&weights, &shape, QuantType::Q4_0).expect("Q4_0");
let d8 = dequantize(&q8).expect("dequantize Q8");
let d4 = dequantize(&q4).expect("dequantize Q4");
let mse8: f64 = weights.iter()
.zip(d8.iter())
.map(|(o, d)| ((*o - *d) as f64).powi(2))
.sum::<f64>() / weights.len() as f64;
let mse4: f64 = weights.iter()
.zip(d4.iter())
.map(|(o, d)| ((*o - *d) as f64).powi(2))
.sum::<f64>() / weights.len() as f64;
prop_assert!(
mse8 <= mse4,
"BB6-PROP FALSIFIED: Q8_0 MSE {} > Q4_0 MSE {}",
mse8, mse4
);
}
#[test]
fn prop_bb4_block_size_always_32(
len in 32usize..512,
) {
let weights: Vec<f32> = (0..len).map(|i| i as f32 * 0.01).collect();
let shape = vec![weights.len()];
let quantized = quantize(&weights, &shape, QuantType::Q8_0).expect("quantize");
prop_assert_eq!(
quantized.block_size, 32,
"BB4-PROP FALSIFIED: block_size is {} instead of 32",
quantized.block_size
);
}
}
}