//! Byte-exact calibration for the fully-integer `hyper_scale_decoder` //! (`decode_hyper_scale`) against the REFERENCE DECODER on real test256.bin data: //! run the real hyper-latent `z` through the net and match the reference scale-index //! output `i_s` exactly. The per-channel ÷2^n is an arithmetic right shift (floor); //! the exported ONNX's `Div` truncates, which is ~1-LSB wrong on negatives — this //! test pins the *reference-decoder* semantics, not the ONNX. No ort/onnx needed. //! //! The same network runs through the integer operator set, as the decoder runs it: the //! plane's scale graph (`jpegai-int/1`, integer-operators §13.6.1) loaded under `acc32`, //! whose output is `I_s` plus the plane's gains. Both must give the reference's `I_s` at //! every position (max|Δ| = 0). //! //! env: WAI_JPEGAI_HYPERSCALE_IO = hyperscale_io_fixture.json //! { z:[i64], i_s:[i64], z_shape:[1,C,h,w] } (dumped from the reference decoder) //! WAI_JPEGAI_HYPERSCALE_WEIGHTS = hyperscale_y_weights.json (int weights) //! WAI_JPEGAI_NORM = norm.json (optional: the plane's gains; without it the graph is //! lowered with gains of 0, and its output is `I_s` itself) #![cfg(all(feature = "neural_int", feature = "legacy_int"))] use wai::jpegai_synthesis::{decode_hyper_scale, IntNet}; use wai_ops::Tensor; #[test] fn hyper_scale_byte_exact_vs_reference() { let io = match std::env::var("WAI_JPEGAI_HYPERSCALE_IO") { Ok(p) if std::path::Path::new(&p).exists() => p, _ => { eprintln!("skip: set WAI_JPEGAI_HYPERSCALE_IO to the z→i_s fixture"); return; } }; let wj = match std::env::var("WAI_JPEGAI_HYPERSCALE_WEIGHTS") { Ok(p) if std::path::Path::new(&p).exists() => p, _ => { eprintln!("skip: set WAI_JPEGAI_HYPERSCALE_WEIGHTS to the weights JSON"); return; } }; let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&io).unwrap()).unwrap(); let z: Vec = v["z"].as_array().unwrap().iter().map(|x| x.as_i64().unwrap()).collect(); let i_s: Vec = v["i_s"].as_array().unwrap().iter().map(|x| x.as_i64().unwrap()).collect(); let zs: Vec = v["z_shape"].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as usize).collect(); let (c, h, w) = (zs[1], zs[2], zs[3]); let net = IntNet::from_json(&serde_json::from_slice(&std::fs::read(&wj).unwrap()).unwrap()).unwrap(); let (mine, co, ho, wo) = decode_hyper_scale(&z, c, h, w, &net); eprintln!("decode_hyper_scale(real z[{c},{h},{w}]) -> [{co},{ho},{wo}] = {} vals", mine.len()); assert_eq!(mine.len(), i_s.len(), "output size mismatch"); let mism = mine.iter().zip(&i_s).filter(|(a, b)| a != b).count(); if let Some((i, (a, b))) = mine.iter().zip(&i_s).enumerate().find(|(_, (a, b))| a != b) { eprintln!("first mismatch @ {i}: mine={a} ref={b}"); } eprintln!("hyper_scale vs reference i_s: {}/{} exact, {} mismatched", mine.len() - mism, mine.len(), mism); assert_eq!(mism, 0, "hyper_scale must be BYTE-EXACT vs the reference decoder; {mism} mismatches"); // Through the integer operator set: the plane's scale graph, loaded under acc32. let gains: Vec = match std::env::var("WAI_JPEGAI_NORM") { Ok(p) if std::path::Path::new(&p).exists() => { let n: serde_json::Value = serde_json::from_slice(&std::fs::read(&p).unwrap()).unwrap(); let k = if c == 160 { "gain_y" } else { "gain_uv" }; n[k].as_array().unwrap().iter().map(|x| x.as_i64().unwrap()).collect() } _ => vec![0; c], }; let g = wai::jpegai_ops::load_scale(wai::jpegai_ops::scale_net(&net).unwrap(), c, &gains).expect("the plane's scale graph loads under acc32"); let v = wai::int_ops::run1(&g, Tensor::new(c as u32, h as u32, w as u32, z.clone()), &[]).expect("z is in the graph's input range"); let plane = v.data.len() / c; let ops: Vec = v.data.iter().enumerate().map(|(i, &x)| x - gains[i / plane]).collect(); let max = ops.iter().zip(&i_s).map(|(a, b)| (a - b).abs()).max().unwrap_or(0); eprintln!("scale graph (wai-ops, acc32) vs reference i_s: {}/{} exact, max|Δ| = {max}", ops.iter().zip(&i_s).filter(|(a, b)| a == b).count(), i_s.len()); assert_eq!(max, 0, "the scale graph must be BYTE-EXACT vs the reference decoder"); }