//! 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::>(); 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::>(); 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 = 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"); } }