open-standards/wai/wai-rs/tests/jpegai_lsbs_calibration.rs
Transaction Science 8386f0f45a jpegai gate 7 (WIP, committed before running): the direct path leaves production; the duplicates go
The duplicate ports neural/jpegai_hyper.rs and neural/jpegai_mans.rs, which the float
decode path ran its front half with, are deleted (O10): that path runs the shared
driver since the switch. The direct pieces of the exact decoder leave production,
test-only (legacy_int): the crate-root mANS port (jpegai_mans), the hyper-scale network
(jpegai_synthesis::decode_hyper_scale and its convolution) and the pipeline's
skip_mask, rvs_additive, rvs_likely and sigma_index. The calibration tests that read
them require legacy_int.

jpegai_mans_golden runs on E8 and the scale graph alone; jpegai_e2e (the float chain
against the reference PNG) takes its front half from the driver, still checking the
dumped RVS additions, masks and residuals; the byte-equality crate drops the neural
port and keeps E8 and the direct port.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 04:28:31 -04:00

73 lines
3.6 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Calibration for [`wai::jpegai_pipeline::lsbs_refine`] — the least-significant-bit
//! scale refinement (`yhat → y_lsbs`, the synthesis input), on the REAL `test256.bin`
//! data for BOTH planes, against the reference's own dumps.
//!
//! ```text
//! means = yhat − resi
//! y_lsbs = yhat + (t0[likely]·means + t1[likely]·resi) / 2^13
//! ```
//!
//! Inputs are the reference's `pp{0,1}_{x,residual,likely,out}` dumps, so this is an
//! exact check of the formula in isolation, independent of upstream PTQ error. The
//! refinement is float arithmetic (IEEE-754 deterministic), so a machine-precision
//! match is required.
//!
//! `likely` is the shared per-8×8-block scale statistic ([`wai::jpegai_pipeline::rvs_likely`]),
//! passed in rather than recomputed here. It is the same value the dequant indexes —
//! verified identical against the reference — and LSBS indexes a 4352-entry table with
//! it *directly*, so an error in that statistic reads the wrong coefficients rather
//! than being absorbed by bucketing. `jpegai_e2e_frontend` asserts the derived
//! statistic drives this stage correctly; here it is supplied so the formula is tested
//! on its own.
//!
//! env: WAI_JPEGAI_LSBS_FIXTURE = lsbs_fixture.json
//! { t0:[i32], t1:[i32], y|uv: { c, h, w, yhat:[f32], resi:[f32], likely:[i64], y_lsbs:[f32] } }
#![cfg(all(feature = "neural_int", feature = "legacy_int"))]
use wai::jpegai_pipeline::lsbs_refine;
#[test]
fn lsbs_refine_matches_reference() {
let path = match std::env::var("WAI_JPEGAI_LSBS_FIXTURE") {
Ok(p) if std::path::Path::new(&p).exists() => p,
_ => { eprintln!("skip: set WAI_JPEGAI_LSBS_FIXTURE"); return; }
};
let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap();
let i32v = |o: &serde_json::Value, k: &str| o[k].as_array().unwrap().iter()
.map(|x| x.as_i64().unwrap() as i32).collect::<Vec<i32>>();
let (t0, t1) = (i32v(&v, "t0"), i32v(&v, "t1"));
for plane in ["y", "uv"] {
let o = &v[plane];
let f32v = |k: &str| o[k].as_array().unwrap().iter()
.map(|x| x.as_f64().unwrap() as f32).collect::<Vec<f32>>();
let (c, h, w) = (
o["c"].as_u64().unwrap() as usize,
o["h"].as_u64().unwrap() as usize,
o["w"].as_u64().unwrap() as usize,
);
let yhat = f32v("yhat");
let resi = f32v("resi");
let likely: Vec<i64> = o["likely"].as_array().unwrap().iter()
.map(|x| x.as_i64().unwrap()).collect();
let reference = f32v("y_lsbs");
let got = lsbs_refine(&yhat, &resi, &likely, &t0, &t1, c, h, w);
assert_eq!(got.len(), reference.len(), "{plane}: y_lsbs size");
let exact = got.iter().zip(&reference).filter(|(a, b)| a == b).count();
let maxd = got.iter().zip(&reference).fold(0f32, |m, (a, b)| m.max((a - b).abs()));
// The identity baseline. LSBS is a small correction, so "close to the reference"
// is not by itself evidence that the refinement happened — passing yhat through
// unchanged must score materially worse than the real thing, or this test is
// measuring nothing.
let id_maxd = yhat.iter().zip(&reference).fold(0f32, |m, (a, b)| m.max((a - b).abs()));
eprintln!("[{plane}] lsbs_refine: {exact}/{} exact, max|Δ| = {maxd:.3e} \
(identity baseline max|Δ| = {id_maxd:.3e})", got.len());
assert!(maxd <= 1e-6, "{plane}: lsbs_refine max|Δ| {maxd:.3e}");
assert!(id_maxd > maxd * 100.0,
"{plane}: identity scores as well as the refinement — test is not discriminating");
}
}