tinyquant-core 0.0.0

CPU-only vector quantization codec — core types, codec, corpus, and backend trait (no_std).
Documentation
//! Byte-parity tests for the FP16 residual correction path.
//!
//! Compares `compute_residual` and `apply_residual_into` against Python-
//! generated golden fixtures under `tests/fixtures/residual/`.

use std::{fs, path::Path};
use tinyquant_core::codec::residual::{apply_residual_into, compute_residual};

fn fixture(name: &str) -> Vec<u8> {
    let p = Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("tests/fixtures/residual")
        .join(name);
    fs::read(&p).unwrap_or_else(|_| {
        panic!(
            "fixture missing: {}; run `cargo xtask fixtures refresh-residual`",
            p.display()
        )
    })
}

fn as_f32(bytes: &[u8]) -> Vec<f32> {
    bytes
        .chunks_exact(4)
        .map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]]))
        .collect()
}

#[test]
fn compute_and_apply_residual_round_trip_is_bounded() {
    let original = [0.12_f32, -0.34, 0.56, -0.78];
    let reconstructed = [0.10_f32, -0.30, 0.60, -0.80];
    let residual = compute_residual(&original, &reconstructed);
    assert_eq!(residual.len(), original.len() * 2); // 2 bytes per element (f16)

    let mut out = reconstructed;
    apply_residual_into(&mut out, &residual).unwrap();
    for (r, o) in out.iter().zip(original.iter()) {
        assert!((r - o).abs() < 1e-2, "r={r} o={o}");
    }
}

#[test]
fn apply_residual_rejects_mismatched_length() {
    let mut values = [0.0_f32; 4];
    let residual = [0_u8; 6]; // should be 8 (4 * 2)
    let err = apply_residual_into(&mut values, &residual).unwrap_err();
    assert!(matches!(
        err,
        tinyquant_core::errors::CodecError::LengthMismatch { left: 6, right: 8 }
    ));
}

#[test]
fn compute_residual_matches_python_fp16_bytes() {
    let original = as_f32(&fixture("original_n1000_d64_seed19.f32.bin"));
    let reconstructed = as_f32(&fixture("reconstructed_n1000_d64_seed19.f32.bin"));
    let expected = fixture("expected_residual_seed19.bin");

    let actual = compute_residual(&original, &reconstructed);
    assert_eq!(actual.len(), expected.len(), "residual byte count mismatch");
    assert_eq!(actual, expected, "byte parity vs numpy np.float16");
}