open-standards/wai/wai-rs/tests/int_hyper_ops.rs
Transaction Science e0285b049b
Some checks failed
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 26s
wai-app and Create / wai-app · does this change touch it (push) Successful in 18s
wai-audit collector and player integration / does this change touch it (push) Successful in 26s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 26s
WAI operation catalogue / does this change touch it (push) Successful in 13s
wai-fleet service / does this change touch it (push) Successful in 23s
wai-int-module WAISM module of record / does this change touch it (push) Successful in 21s
wai-ledger service / does this change touch it (push) Successful in 12s
wai-ops integer operators / does this change touch it (push) Successful in 18s
wai media golden suite on RISC-V (emulated) / does this change touch it (push) Successful in 17s
wai-quantum for JavaScript / does this change touch it (push) Successful in 16s
wai-quantum studio and desktop / does this change touch it (push) Successful in 13s
wai-sink-android native sink library / does this change touch it (push) Successful in 13s
wai-sink-swift native sink package / does this change touch it (push) Successful in 13s
WAI Studio / does this change touch it (push) Successful in 12s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 3m13s
wai cross-architecture byte-equality / does this change touch it (push) Successful in 3m35s
wai formal verification (integer core) / does this change touch it (push) Successful in 3m17s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 8s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 7m22s
wai-ops integer operators / linux-aarch64 (push) Successful in 2m53s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Successful in 2m1s
wai cross-architecture byte-equality / linux-aarch64 (push) Successful in 59s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 34s
wai-int-module WAISM module of record / linux-arm64 · both checkers, wasmtime (Cranelift, Winch), Wasmi and Node (push) Successful in 7m34s
wai-int-module WAISM module of record / the module of record in Chromium (push) Successful in 9s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 7m58s
wai-audit collector and player integration / collector · linux (push) Successful in 4m24s
wai-fleet service / service · linux (push) Successful in 3m49s
wai-ops integer operators / independent checker (Python) (push) Successful in 21s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (push) Successful in 47s
wai-ops integer operators / wasm32 under Node (push) Successful in 50s
wai-ops integer operators / linux-x86_64 (push) Successful in 1m41s
wai media golden suite on RISC-V (emulated) / golden suite · riscv64 (emulated) (push) Successful in 1m3s
wai-ledger service / service · linux (push) Successful in 2m32s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m13s
wai-int-module WAISM module of record / linux · both checkers, wasmtime (Cranelift, Winch), Wasmi and Node (push) Successful in 6m0s
wai-fleet service / service · macos (push) Successful in 41s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 2m0s
wai formal verification (integer core) / every harness in one shard (push) Successful in 21s
wai cross-architecture byte-equality / linux-x86_64 (push) Successful in 49s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 8m50s
wai-ledger service / service · macos (push) Successful in 54s
wai-quantum for JavaScript / javascript · linux (push) Successful in 5m10s
wai-ops integer operators / macos-arm64 (push) Successful in 1m18s
joule-moq-room room service / joule-moq-room, every target (push) Successful in 18m19s
wai-quantum studio and desktop / studio · browser (push) Successful in 5m59s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Failing after 2m1s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 6m31s
wai formal verification (integer core) / kani (stage) (push) Successful in 4m6s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 3m30s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 8m56s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 9m48s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 5m9s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 9m1s
wai formal verification (integer core) / kani (integer-core) (push) Successful in 9m41s
WAI Studio / Studio in WebKit · linux (push) Successful in 15m29s
wai formal verification (integer core) / kani (plan) (push) Successful in 13m48s
wai formal verification (integer core) / kani (arith) (push) Successful in 14m52s
wai formal verification (integer core) / kani (isqrt512) (push) Successful in 30m57s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 8m36s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 12m14s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 50s
wai cross-architecture byte-equality / windows-x86_64 (push) Successful in 1m4s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 22m42s
wai cross-architecture byte-equality / macos-arm64 (reference) (push) Successful in 25s
wai formal verification (integer core) / kani (sound) (push) Successful in 22m37s
wai formal verification (integer core) / kani (stage-long) (push) Successful in 27m23s
wai formal verification (integer core) / kani (rans64-t2) (push) Successful in 15m3s
wai.neural.int_hyper: leaves, a parameter set of WAI's own, trained on generated pictures and held to one decode natively and in WebAssembly
The set: tools/wai_int_hyper_train.py at 40db6ee57 (the commit that brought it) trained a
mean-scale hyperprior, 48 synthesis and 64 latent channels, from seed 20261110 on the
dead-leaves pictures tools/wai_int_synth_real.py generates from that seed, streams 1 to 4096:
30,000 steps of 16, Adam at 1e-3 then 1e-4 for the last quarter, lambda 0.0483, on the CPU at 8
threads with deterministic algorithms (Python 3.11.17, torch 2.14.0+cpu, numpy 1.26.4,
compressai 1.2.8; the Framework build host, Linux x86_64). Exported by export_model and coded on
stream 0 (128 x 128). Listing digest (the set's identity):
ab796bb19cb202115400ea2ce16724617c3da035a2f4429d6266d419ab705ac0. Its record,
wai-rs/tests/vectors/int_hyper/leaves_set.json, reads Own: Apache-2.0, a start from a seed, and
training and coded pictures generated by a tool below wai/ with no third-party source; the
tools' blob ids are their blobs at 40db6ee57.

Reproducibility: two runs from the same seeds, side by side on that host, wrote the same bytes
in every file (float model 2ce350db..., all three members, the bitstream, the decode and the
record), and logged the same loss at every logged step. 300-step runs at 8 and at 4 threads
from the same seeds agree at step 0 and differ by step 299 (float models 1820d9ec... and
699bfbea...): the thread count is part of the recipe, and the record states it.

Where its decode is held, each to the one digest in int_hyper/sha256.json
(3ea9b4c3026e7c81683f3845f8256b1f0e1e8268284d81f3f16f290a5dde1374):
- int-payload-conformance gains `leaves`, a WIH1 payload (SHA-256 048c7c0d...), decoded natively
  by wai_int_payload_vectors verify; int_payload_verify.py parses and converts it independently.
- wai-int-module/corpus.json, 121 cases: both modules of record gave every case its outcome on
  wasmtime 50.0.1 (Cranelift, Winch) and Wasmi 2.0.0, run digest f245b5f0... (Framework). The
  browser crate's Node check names the payload too (CI).
- byte-exact-conformance: wih1_trained_set_is_golden, by the sink's decode and through the
  lowering under the reference and the fast kernels, on every leg of the matrix.
- ops-conformance certifies it (index and two lowered graphs): acc64, first acc32 failure at
  h_s's input range, 43 bits; int_hyper_ops holds the set and the vector to them.

verifiers/int-hyper-set.sh runs `check --own` and `self-test`: the unchanged record and a copy
started from a set that reads Own read Own, and 11 planted faults are caught (one weight moved
by one; a third-party source in the training record, beside generated pictures, or in the
start's record; a start from a checkpoint that is not WAI's; each of three seeds removed; the
coded picture among the training pictures; a decode digest changed; the decode of another
picture with its digest restated). The trainer's check of a start from a set now reads a start
that does not read Own as `not own`, rather than failing.

Run through rb on the Framework (Linux x86_64), each passed: wai_int_payload_vectors verify
(release and debug), int_payload_verify.py, check --own, self-test, corpus.py --check, wai-verify
vectors verify, wai_ops_check.py, byte-exact-conformance (release), int_payload (debug),
int_hyper_ops (debug and release), corpus_provenance, the module host on all 121 cases. Decode-side
plants, each caught, with the committed case passing first: a WebAssembly decode of the set with
one g_s weight moved (0 of 1 cases the corpus's), and the same drift in the committed file under
the native corpus verify, the record check and the byte-exact golden.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-10 13:41:55 -05:00

627 lines
38 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.

// wai-conformance: int-kernels int-kernels-amd
//! `wai.neural.int_hyper` and the keyframe of `wai.video.int_hyper` through the integer
//! operator set: their lowering `whm1/1` (`extensions/integer-operators.md` §13.2; `h_s`,
//! then `g_s` with the RGB8 step of §13.0) and the certificate of every committed set
//! (§8.5), as this crate loads them (`int_ops`, `int_hyper_synth::ops`).
//!
//! The lowered graphs and certificates are committed under `ops-conformance/certificates/`,
//! where `wai-verify` and the independent checker (`tools/wai_ops_check.py`) each
//! reproduce them byte for byte (`wai-ops.yml`). Here the lowering this crate runs, from
//! the models it parses (`int_ops::whm1_net`), must write those same bytes, and the load a
//! sink makes must give the verdict the certificate records.
use std::path::PathBuf;
use serde_json::Value;
use wai::int_hyper_synth::{self as hyper, IntModel};
use wai_ops::Profile;
const CAPS: [&str; 2] = ["wai.neural.int_hyper", "wai.video.int_hyper"];
fn wai() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}
fn read(rel: &str) -> Vec<u8> {
std::fs::read(wai().join(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
}
fn json(rel: &str) -> Value {
serde_json::from_slice(&read(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
}
fn sha256(b: &[u8]) -> String {
wai_ops::sha256::sha256(b).iter().map(|x| format!("{x:02x}")).collect()
}
/// A committed set of one of the two capabilities, as `ops-conformance/certificates/index.json`
/// lists it: its name, capability, members (name, path below `wai/`), digest and lowered
/// graphs (`h_s`, then `g_s`).
struct Indexed {
name: String,
cap: String,
members: Vec<(String, String)>,
digest: String,
roles: [String; 2],
}
fn indexed() -> Vec<Indexed> {
json("ops-conformance/certificates/index.json")["sets"]
.as_array()
.unwrap()
.iter()
.filter(|s| CAPS.contains(&s["capability"].as_str().unwrap()))
.map(|s| {
assert_eq!(s["lowering"], "whm1/1");
let roles = s["roles"].as_array().unwrap();
assert_eq!(roles.len(), 2, "whm1/1 lowers a conditional codec's set to two graphs, h_s and g_s");
let members = s["members"].as_object().unwrap().iter().map(|(k, v)| (k.clone(), v.as_str().unwrap().to_string())).collect();
Indexed {
name: s["name"].as_str().unwrap().to_string(),
cap: s["capability"].as_str().unwrap().to_string(),
members,
digest: s["set_sha256"].as_str().unwrap().to_string(),
roles: [roles[0].as_str().unwrap().to_string(), roles[1].as_str().unwrap().to_string()],
}
})
.collect()
}
impl Indexed {
fn member(&self, name: &str) -> Vec<u8> {
read(&self.members.iter().find(|(k, _)| k == name).unwrap_or_else(|| panic!("{}: no {name}", self.name)).1)
}
}
/// The two graphs this crate lowers from the models it parses (`int_hyper_synth::ops::lower`),
/// whose conversion (`int_ops::whm1_net`) must give the networks `wai-ops` parses from the
/// bytes.
fn lowered_from_the_parsed_models(g_s: &[u8], h_s: &[u8]) -> (wai_ops::Graph, wai_ops::Graph) {
let (g, h) = (IntModel::from_bytes(g_s).unwrap(), IntModel::from_bytes(h_s).unwrap());
for (m, b) in [(&g, g_s), (&h, h_s)] {
let net = wai::int_ops::whm1_net(m).expect("a model parsed from bytes converts");
assert!(net == wai_ops::lower::parse_whm1(b).unwrap(), "the converted model is the one wai-ops parses from the bytes");
}
hyper::ops::lower(&g, &h).expect("the set lowers")
}
/// Gate 1 of the migration: every committed set of `wai.neural.int_hyper` and
/// `wai.video.int_hyper` lowers to its committed graphs, from its members' bytes
/// (`lower::int_hyper`) and from the models this crate parses; the certificate beside them
/// is those graphs'; and loading each graph under the capability's profile gives the
/// certificate's verdict. The sets carry `check` ranges (§13.2), so they meet `acc64` by
/// construction and not `acc32`; the first `acc32` failure is `h_s`'s input range, at 53
/// bits for the conformance set `tiny` (Appendix C's prediction), 43 for `leaves`, the
/// set trained on generated pictures (`int_hyper/leaves_set.json`), and 52 for the synthetic
/// one. The tiny set's JSON models, the form the tools write beside the binary one,
/// convert to the same networks and lower to the same graphs.
#[test]
fn every_committed_set_lowers_to_its_committed_graphs_and_verdict() {
let sets = indexed();
let names: Vec<(&str, &str)> = sets.iter().map(|s| (s.cap.as_str(), s.name.as_str())).collect();
assert_eq!(names, [(CAPS[0], "tiny"), (CAPS[1], "tiny"), (CAPS[0], "leaves"), (CAPS[0], "hyper")], "the committed int_hyper sets");
for s in &sets {
let (name, cap) = (&s.name, &s.cap);
let (g_s, h_s, ent) = (s.member("g_s.whm"), s.member("h_s.whm"), s.member("entropy.json"));
let members = vec![("entropy.json", ent.clone()), ("g_s.whm", g_s.clone()), ("h_s.whm", h_s.clone())];
assert_eq!(wai_ops::generate::sets::set_digest(&members), s.digest, "{name}: the set's digest");
// The entropy tables are the stage operators' data, not lowered; the set's must load.
hyper::CondEntropy::read(&ent).unwrap_or_else(|e| panic!("{name}: entropy.json: {e}"));
let lowered = wai_ops::lower::int_hyper(&h_s, &g_s).unwrap_or_else(|r| panic!("{name}: does not lower: {r:?}"));
let roles: Vec<&str> = lowered.roles.iter().map(|(r, _)| *r).collect();
assert_eq!(roles, ["h_s", "g_s"], "{name}");
let (h, g) = lowered_from_the_parsed_models(&g_s, &h_s);
let cert = json(&format!("ops-conformance/certificates/{cap}/{}.json", s.digest));
assert_eq!(cert["set_sha256"].as_str(), Some(s.digest.as_str()), "{name}");
assert_eq!(cert["capability"].as_str(), Some(cap.as_str()), "{name}");
assert_eq!(cert["lowering"], "whm1/1", "{name}");
for (k, (role, ours)) in [("h_s", &h), ("g_s", &g)].into_iter().enumerate() {
let from_bytes = lowered.get(role).unwrap();
// The verdict first: the load a sink makes.
let loaded = wai::int_ops::load(from_bytes).unwrap_or_else(|r| panic!("{name} {role}: refused under acc64: {r:?}"));
assert!(!loaded.meets(Profile::Acc32), "{name} {role}: a graph with check ranges inside it does not meet acc32");
// Then the committed bytes: the graph, both ways, and the certificate's record of it.
let graph = from_bytes.to_bytes();
assert!(graph == read(&s.roles[k]), "{name}: the lowering of the bytes differs from the committed {}", s.roles[k]);
assert!(ours.to_bytes() == graph, "{name}: the lowering of the parsed models differs from the committed {role}");
let c = &cert["graphs"][k];
assert_eq!(c["name"].as_str(), Some(role), "{name}");
assert_eq!(c["graph_sha256"].as_str(), Some(sha256(&graph).as_str()), "{name} {role}: the certificate is the graph's");
// The input's check range is the lowering's X_0 for the network's first layer (§13.2).
let x0 = &c["inputs"][0];
let t = &from_bytes.tensors[0];
assert_eq!((x0["policy"].as_str(), x0["lo"].as_str(), x0["hi"].as_str()), (Some("check"), Some(t.lo.to_string().as_str()), Some(t.hi.to_string().as_str())), "{name} {role}");
assert!(t.hi > 0 && t.lo == -t.hi, "{name} {role}: a symmetric check range");
}
let v = &cert["verdict"];
assert_eq!((v["acc64"].as_bool(), v["acc32"].as_bool()), (Some(true), Some(false)), "{name}: the certificate's verdict");
let bits = match name.as_str() {
"tiny" => "53",
"leaves" => "43",
_ => "52",
};
let first = &v["acc32_first_failure"];
assert_eq!(
(first["graph"].as_str(), first["where"].as_str(), first["index"].as_str(), first["key"].as_str(), first["bits"].as_str()),
(Some("h_s"), Some("input"), Some("0"), Some("range"), Some(bits)),
"{name}: the first acc32 failure"
);
// The decode's own load: both networks, h_s first.
let (gm, hm) = (IntModel::from_bytes(&g_s).unwrap(), IntModel::from_bytes(&h_s).unwrap());
let nets = hyper::ops::load(&gm, &hm).unwrap_or_else(|r| panic!("{name}: {r}"));
assert!(nets.h_s.graph() == lowered.get("h_s").unwrap() && nets.g_s.graph() == lowered.get("g_s").unwrap(), "{name}: the decode loads the committed graphs");
}
// The tiny set's JSON models, which the byte-exact keyframe golden and the browser's
// debug decode read, convert to the networks of its binary models.
let dir = "wai-rs/tests/vectors/int_hyper";
let from_json = |f: &str| IntModel::try_from_json(&json(&format!("{dir}/{f}"))).unwrap();
let (g, h) = hyper::ops::lower(&from_json("tiny_g_s.json"), &from_json("tiny_h_s.json")).unwrap();
let (gb, hb) = lowered_from_the_parsed_models(&read(&format!("{dir}/tiny_g_s.bin")), &read(&format!("{dir}/tiny_h_s.bin")));
assert!(g == gb && h == hb, "the tiny set's JSON and binary models lower alike");
}
/// The set of the pretrained model (`mbt2018_mean`, exported to integers) is too large to
/// commit, so its certificate is committed by the set's digest and checked against the
/// regenerated set in `wai-sota-vectors.yml`, where `tests/int_hyper_synth.rs` also holds
/// this crate's lowering of it to the graphs the certificate records. Its verdict is
/// Appendix C's: `acc64`, first failing `acc32` at `h_s`'s input range, 41 bits.
#[test]
fn the_pretrained_sets_certificate_is_the_one_appendix_c_predicts() {
let ext = json("ops-conformance/certificates/external.json");
let s = ext["sets"].as_array().unwrap().iter().find(|s| s["capability"] == CAPS[0]).expect("the pretrained set is listed");
assert_eq!((s["lowering"].as_str(), s["profile"].as_str()), (Some("whm1/1"), Some("acc64")));
let digest = s["set_sha256"].as_str().unwrap();
let cert = json(&format!("ops-conformance/certificates/{}/{digest}.json", CAPS[0]));
let names: Vec<&str> = cert["graphs"].as_array().unwrap().iter().map(|g| g["name"].as_str().unwrap()).collect();
assert_eq!(names, ["h_s", "g_s"]);
let v = &cert["verdict"];
assert_eq!((v["acc64"].as_bool(), v["acc32"].as_bool()), (Some(true), Some(false)));
let first = &v["acc32_first_failure"];
assert_eq!(
(first["graph"].as_str(), first["where"].as_str(), first["key"].as_str(), first["bits"].as_str()),
(Some("h_s"), Some("input"), Some("range"), Some("41"))
);
}
/// The typed form of a parsed `WIH1` payload.
fn stream<'a>(k: &'a wai::int_wire::Wih1<'a>) -> hyper::CondStream<'a> {
hyper::CondStream {
m: k.m as usize, sh: k.sh as usize, sw: k.sw as usize, n_z: k.n_z as usize, zh: k.zh as usize, zw: k.zw as usize,
z_rans: k.z_rans, rans: k.rans,
}
}
/// A committed set's three members, parsed: `g_s`, `h_s` and the entropy tables.
fn set_of(v: &Value) -> (IntModel, IntModel, hyper::CondEntropy) {
let m = |k: &str| read(v["set"][k].as_str().unwrap());
let ent = hyper::CondEntropy::read(&m("entropy.json")).unwrap();
(IntModel::from_bytes(&m("g_s.whm")).unwrap(), IntModel::from_bytes(&m("h_s.whm")).unwrap(), ent)
}
fn hex(b: &[u8]) -> String {
b.iter().map(|x| format!("{x:02x}")).collect()
}
/// Every frame's SHA-256 and the clip's, against the sidecar entry `key` of
/// `int_video/sha256.json`; every frame's FNV-1a and the clip's, against `conf`.
fn assert_clip(frames: &[Vec<u8>], key: &str, conf: &Value) {
use sha2::Digest;
let side = json("wai-rs/tests/vectors/int_video/sha256.json");
let (want, fnv) = (side[key]["frames_sha256"].as_array().unwrap(), conf["frame_hashes"].as_array().unwrap());
assert_eq!((want.len(), fnv.len()), (frames.len(), frames.len()), "{key}: frame count");
let (mut all, mut all_fnv) = (Vec::new(), Vec::new());
for (i, f) in frames.iter().enumerate() {
let d = sha2::Sha256::digest(f);
assert_eq!(hex(&d), want[i].as_str().unwrap(), "{key}: frame {i}");
let h = format!("{:016x}", wai::int_video::fnv1a(f));
assert_eq!(h, fnv[i].as_str().unwrap(), "{key}: frame {i}'s FNV-1a");
all.extend_from_slice(&d);
all_fnv.extend((0..8).map(|j| u8::from_str_radix(&h[2 * j..2 * j + 2], 16).unwrap()));
}
assert_eq!(hex(&sha2::Sha256::digest(&all)), side[key]["clip_sha256"].as_str().unwrap(), "{key}: the clip's SHA-256");
assert_eq!(format!("{:016x}", wai::int_video::fnv1a(&all_fnv)), conf["clip_hash"].as_str().unwrap(), "{key}: the clip's FNV-1a");
}
/// Gate 2 of the migration: golden equality. Every committed vector of
/// `wai.neural.int_hyper` and `wai.video.int_hyper` (`int-payload-conformance/vectors.json`)
/// decodes through the lowering (`int_hyper_synth::ops`) to the image the direct decode
/// gives (`int_hyper_synth::legacy`), and to every digest the corpus commits for it:
/// - `tiny` (`WIH1`): the SHA-256 sidecar and the export's FNV-1a, from the payload, from
/// the JSON form it is converted from, and with the set's JSON models, the form the
/// byte-exact keyframe golden reads;
/// - `video_nk` (`WIV1`, keyframe 1): its nested `WIH1` keyframe, then the clip's integer
/// P-frames on it, every frame's and the clip's SHA-256 and FNV-1a;
/// - `leaves` (`WIH1`, against the set trained on generated pictures): the SHA-256 sidecar
/// and the export's FNV-1a, from the payload and from the JSON form it is converted from.
#[test]
fn every_committed_vector_decodes_through_the_lowering_to_its_golden() {
let index = json("int-payload-conformance/vectors.json");
let vs: Vec<&Value> = index["vectors"].as_array().unwrap().iter().filter(|v| CAPS.contains(&v["capability"].as_str().unwrap())).collect();
let names: Vec<&str> = vs.iter().map(|v| v["name"].as_str().unwrap()).collect();
assert_eq!(names, ["tiny", "video_nk", "leaves"], "the committed int_hyper vectors");
let dir = "wai-rs/tests/vectors";
// tiny: WIH1, its JSON form, and the JSON models.
let v = vs[0];
let (g_s, h_s, ent) = set_of(v);
let p = read(v["payload"].as_str().unwrap());
assert_eq!(sha256(&p), v["payload_sha256"].as_str().unwrap());
let k = wai::int_wire::parse_wih1(&p).unwrap();
let bs = hyper::CondBitstream::try_from_value(&json(v["converted_from"]["json"].as_str().unwrap())).unwrap();
let from_json = |f: &str| IntModel::try_from_json(&json(&format!("{dir}/int_hyper/{f}"))).unwrap();
let (gj, hj) = (from_json("tiny_g_s.json"), from_json("tiny_h_s.json"));
let want_sha = json(v["sidecar"].as_str().unwrap())["tiny"]["sha256"].as_str().unwrap().to_string();
let conf = json(&format!("{dir}/int_hyper/tiny.json"));
for (form, g, h, st) in [("WIH1", &g_s, &h_s, stream(&k)), ("JSON", &g_s, &h_s, bs.stream()), ("JSON models", &gj, &hj, stream(&k))] {
let ops = hyper::ops::decode(g, h, &ent, &st).unwrap_or_else(|r| panic!("tiny {form}: {r}"));
let direct = hyper::legacy::decode_conditional_checked(g, h, &ent, &st).unwrap_or_else(|r| panic!("tiny {form}: {r}"));
assert!(ops == direct, "tiny {form}: the decode through the lowering differs from the direct decode");
assert_eq!((ops.1, ops.2), (16, 16), "tiny {form}");
assert_eq!(sha256(&ops.0), want_sha, "tiny {form}: the SHA-256 sidecar");
assert_eq!(format!("{:016x}", hyper::fnv1a(&ops.0)), conf["rgb_hash"].as_str().unwrap(), "tiny {form}: the export's FNV-1a");
}
// video_nk: WIV1 with keyframe 1.
let v = vs[1];
let (g_s, h_s, ent) = set_of(v);
let p = read(v["payload"].as_str().unwrap());
assert_eq!(sha256(&p), v["payload_sha256"].as_str().unwrap());
let w = wai::int_wire::parse_wiv1(&p, Some(1)).unwrap();
let k = wai::int_wire::parse_wih1(w.wih1.expect("keyframe 1 nests a WIH1")).unwrap();
let (frame0, h, wd) = hyper::ops::decode(&g_s, &h_s, &ent, &stream(&k)).unwrap();
assert!(hyper::legacy::decode_conditional_checked(&g_s, &h_s, &ent, &stream(&k)).unwrap() == (frame0.clone(), h, wd), "video_nk: the keyframe differs from the direct decode's");
assert_eq!((h, wd), (w.h as usize, w.w as usize), "video_nk: the keyframe is the clip's size");
let s = wai::int_video::VideoStream {
n_frames: w.n_frames as usize, h: w.h as usize, w: w.w as usize, block: w.block as usize,
q: w.q as i64, offset: w.offset, mv_precision: w.mv_precision, cdf: &w.cdf, mvs: &w.mvs, rans: w.rans,
};
let clip = wai::int_video::decode_pframes_typed(&frame0, &s).unwrap();
assert_clip(&clip.frames, "video_nk", &json(&format!("{dir}/int_video/video_nk.json")));
// leaves: WIH1 and its JSON form, against the trained set.
let v = vs[2];
let (g_s, h_s, ent) = set_of(v);
let p = read(v["payload"].as_str().unwrap());
assert_eq!(sha256(&p), v["payload_sha256"].as_str().unwrap());
let k = wai::int_wire::parse_wih1(&p).unwrap();
let bs = hyper::CondBitstream::try_from_value(&json(v["converted_from"]["json"].as_str().unwrap())).unwrap();
let want_sha = json(v["sidecar"].as_str().unwrap())["leaves"]["sha256"].as_str().unwrap().to_string();
let conf = json(&format!("{dir}/int_hyper/leaves.json"));
for (form, st) in [("WIH1", stream(&k)), ("JSON", bs.stream())] {
let ops = hyper::ops::decode(&g_s, &h_s, &ent, &st).unwrap_or_else(|r| panic!("leaves {form}: {r}"));
let direct = hyper::legacy::decode_conditional_checked(&g_s, &h_s, &ent, &st).unwrap_or_else(|r| panic!("leaves {form}: {r}"));
assert!(ops == direct, "leaves {form}: the decode through the lowering differs from the direct decode");
assert_eq!((ops.1, ops.2), (128, 128), "leaves {form}");
assert_eq!(sha256(&ops.0), want_sha, "leaves {form}: the SHA-256 sidecar");
assert_eq!(format!("{:016x}", hyper::fnv1a(&ops.0)), conf["rgb_hash"].as_str().unwrap(), "leaves {form}: the export's FNV-1a");
}
}
/// The code integer-payloads §8 gives a refusal of the conditional decode.
fn code_of(r: hyper::Refused) -> &'static str {
wai::int_payload::IntPayloadError::from(r).code()
}
/// The committed conformance set and payload (`int-payload-conformance`'s `tiny`).
const DIR: &str = "wai-rs/tests/vectors/int_hyper";
/// A typed `WIH1` payload that owns its streams, so a fixture can change any field.
#[derive(Clone)]
struct Owned {
m: usize,
sh: usize,
sw: usize,
n_z: usize,
zh: usize,
zw: usize,
z_rans: Vec<u8>,
rans: Vec<u8>,
}
impl Owned {
fn committed() -> Owned {
let p = read(&format!("{DIR}/tiny_bitstream.wih1"));
let k = wai::int_wire::parse_wih1(&p).unwrap();
Owned {
m: k.m as usize, sh: k.sh as usize, sw: k.sw as usize, n_z: k.n_z as usize, zh: k.zh as usize, zw: k.zw as usize,
z_rans: k.z_rans.to_vec(), rans: k.rans.to_vec(),
}
}
fn st(&self) -> hyper::CondStream<'_> {
hyper::CondStream { m: self.m, sh: self.sh, sw: self.sw, n_z: self.n_z, zh: self.zh, zw: self.zw, z_rans: &self.z_rans, rans: &self.rans }
}
}
/// The committed set, parsed, changed by `f`: `(g_s, h_s, entropy tables)`.
fn tiny(f: impl FnOnce(&mut IntModel, &mut IntModel, &mut hyper::CondEntropy)) -> (IntModel, IntModel, hyper::CondEntropy) {
let mut g = IntModel::from_bytes(&read(&format!("{DIR}/tiny_g_s.bin"))).unwrap();
let mut h = IntModel::from_bytes(&read(&format!("{DIR}/tiny_h_s.bin"))).unwrap();
let mut e = hyper::CondEntropy::read(&read(&format!("{DIR}/tiny_entropy.json"))).unwrap();
f(&mut g, &mut h, &mut e);
(g, h, e)
}
/// The committed payload, changed by `f`.
fn payload(f: impl FnOnce(&mut Owned)) -> Owned {
let mut o = Owned::committed();
f(&mut o);
o
}
/// Both decodes of a typed payload against a set: through the lowering, then directly.
fn both(set: &(IntModel, IntModel, hyper::CondEntropy), o: &Owned) -> (Result<Vec<u8>, &'static str>, Result<Vec<u8>, &'static str>) {
let (g, h, e) = set;
(
hyper::ops::decode(g, h, e, &o.st()).map(|d| d.0).map_err(code_of),
hyper::legacy::decode_conditional_checked(g, h, e, &o.st()).map(|d| d.0).map_err(code_of),
)
}
/// Gate 3 of the migration: refusal parity, on the committed fixtures. Each fixture of
/// `int-payload-conformance` for `wai.neural.int_hyper` and `wai.video.int_hyper` is
/// refused by a sink with its code. For one that parses (`decode`), its `WIH1` (the
/// payload, or a `WIV1`'s keyframe) decodes through the lowering and directly to the same
/// image, or is refused by both with the same code: the fixture's, where the keyframe is
/// what it refuses.
#[test]
fn every_committed_refusal_fixture_keeps_its_code() {
use std::collections::BTreeMap;
let (mut n, mut keyframes) = (0, 0);
for f in json("int-payload-conformance/vectors.json")["refusals"].as_array().unwrap().iter().filter(|f| CAPS.contains(&f["capability"].as_str().unwrap())) {
let (name, cap, want) = (f["name"].as_str().unwrap(), f["capability"].as_str().unwrap(), f["code"].as_str().unwrap());
let p = read(f["payload"].as_str().unwrap());
let set: BTreeMap<String, Vec<u8>> = f["set"].as_object().unwrap().iter().map(|(k, v)| (k.clone(), read(v.as_str().unwrap()))).collect();
let view: BTreeMap<String, &[u8]> = set.iter().map(|(k, v)| (k.clone(), v.as_slice())).collect();
let params = wai::int_payload::resolve(cap, None, &[wai::pin::HeldBytes::Set { listing: b"", files: &view }], None).expect("an unpinned set resolves");
let sink = wai::int_payload::decode_int(cap, &p, &params).map(|_| ()).map_err(|e| e.code());
assert_eq!(sink, Err(want), "{name}: the sink's code");
if f["layer"] == "decode" {
let nested = if cap == CAPS[0] { p.clone() } else { wai::int_wire::parse_wiv1(&p, Some(1)).unwrap().wih1.unwrap().to_vec() };
let k = wai::int_wire::parse_wih1(&nested).unwrap_or_else(|e| panic!("{name}: a decode fixture's keyframe parses: {e:?}"));
let g = IntModel::from_bytes(&set["g_s.whm"]).unwrap();
let h = IntModel::from_bytes(&set["h_s.whm"]).unwrap();
let e = hyper::CondEntropy::read(&set["entropy.json"]).unwrap();
let ops = hyper::ops::decode(&g, &h, &e, &stream(&k)).map(|d| d.0).map_err(code_of);
let direct = hyper::legacy::decode_conditional_checked(&g, &h, &e, &stream(&k)).map(|d| d.0).map_err(code_of);
assert!(ops == direct, "{name}: the two decodes of the keyframe differ: {:?} / {:?}", ops.as_ref().err(), direct.as_ref().err());
if cap == CAPS[0] {
assert_eq!(ops, Err(want), "{name}: the WIH1 fixture's code, both ways");
}
keyframes += 1;
}
n += 1;
}
assert!(n >= 33 && keyframes >= 15, "the committed int_hyper fixtures: {n}, {keyframes} decoded");
}
/// Gate 3, beside the committed fixtures: a fixture for each refusal the direct decode
/// makes (integer-payloads §7, in its order: the set against the payload, the networks
/// planned, the shapes, then each stream and each network as it runs), each made from the
/// committed set and payload by one change. Each is refused by both decodes with the same
/// code, the one integer-payloads §8 gives that rule. The committed set and payload decode.
#[test]
fn every_refusal_of_the_direct_decode_is_refused_alike_through_the_lowering() {
use hyper::IntLayer;
let base = tiny(|_, _, _| {});
let (ops, direct) = both(&base, &Owned::committed());
assert!(ops.is_ok() && ops == direct, "the fixtures' base decodes alike");
let same = || tiny(|_, _, _| {});
let as_is = || payload(|_| {});
// A hyper-latent stream that runs out: two symbols of frequency 1 in 65536 each cost
// 16 bits, so the 8 symbols need more than the stream's 64-bit start, cut short.
let costly_z = |e: &mut hyper::CondEntropy| {
for k in 0..2 {
e.z_cdfs[k] = vec![0, 1, 2, 1 << 16];
e.z_cdf_lengths[k] = 4;
}
};
let costly_z_stream = || {
let mut enc = wai::rans::RansEncoder::new();
for _ in 0..8 {
assert!(enc.encode(-8, &[0, 1, 2, 1 << 16], 4, -8));
}
let mut s = enc.flush();
s.truncate(s.len() - 4);
s
};
let h_bias = |f: fn(&mut Vec<i64>, usize)| tiny(move |_, h, _| {
if let IntLayer::Conv { bias, .. } = &mut h.layers[2] { f(bias, 4) }
});
let fixtures: Vec<(&str, &str, (IntModel, IntModel, hyper::CondEntropy), Owned)> = vec![
("h_s's afrac not g_s's", "model_mismatch", tiny(|_, h, _| h.afrac = 11), as_is()),
("the set's afrac of 0", "model_mismatch", tiny(|g, h, _| (g.afrac, h.afrac) = (0, 0)), as_is()),
("the set's afrac of 31", "model_mismatch", tiny(|g, h, _| (g.afrac, h.afrac) = (31, 31)), as_is()),
("no scale edge", "model_mismatch", tiny(|_, _, e| { e.edges.clear(); e.cdfs.clear(); e.cdf_lengths.clear(); e.offsets.clear(); }), as_is()),
("a latent table short", "model_mismatch", tiny(|_, _, e| { e.cdfs.pop(); }), as_is()),
("a hyper-latent median short", "model_mismatch", tiny(|_, _, e| { e.z_median_q.pop(); }), as_is()),
("a table that does not end at 2^16", "model_mismatch", tiny(|_, _, e| { let n = e.cdf_lengths[1]; e.cdfs[1][n - 1] = 65535; }), as_is()),
("a hyper-latent table's length past its row", "model_mismatch", tiny(|_, _, e| e.z_cdf_lengths[0] = e.z_cdfs[0].len() + 1), as_is()),
("a latent dimension of 0", "field_range", same(), payload(|o| o.m = 0)),
("more hyper-latent channels than tables", "model_mismatch", same(), payload(|o| o.n_z = 3)),
("a hyper-latent past 2^26", "too_large", same(), payload(|o| (o.zh, o.zw) = (1 << 13, 1 << 13))),
("a latent past 2^26", "too_large", same(), payload(|o| (o.sh, o.sw) = (1 << 12, 1 << 12))),
("an uncropped plane of h_s past 2^26", "too_large", same(), payload(|o| (o.zh, o.zw) = (1 << 11, 1 << 11))),
("an h_s layer's bias short", "model_mismatch", h_bias(|b, _| { b.pop(); }), as_is()),
("padding that leaves g_s no output", "model_mismatch", tiny(|g, _, _| if let IntLayer::ConvT { pad, .. } = &mut g.layers[2] { *pad = 1000 }), as_is()),
("an h_s output that is not the declared latent's shape", "geometry_mismatch", same(), payload(|o| o.sh = 5)),
("a g_s that gives four channels", "model_mismatch", tiny(|g, _, _| if let IntLayer::ConvT { out_ch, weight, mult, bias, .. } = &mut g.layers[2] {
*out_ch = 4;
*weight = vec![1; 4 * 4 * 9];
mult.push(mult[0]);
bias.push(0);
}), as_is()),
("a hyper-latent stream too short to be one", "field_range", same(), payload(|o| o.z_rans.truncate(4))),
("a hyper-latent stream that runs out", "stream_exhausted", tiny(|_, _, e| costly_z(e)), payload(|o| o.z_rans = costly_z_stream())),
("a word left unread in the hyper-latent stream", "stream_noncanonical", same(), payload(|o| o.z_rans.extend([0, 0, 0, 0]))),
("a hyper-latent median at i64's end", "field_range", tiny(|_, _, e| e.z_median_q[0] = i64::MAX), as_is()),
("hyper-latents past h_s's range", "field_range", tiny(|_, _, e| e.z_median_q = vec![1 << 60; 2]), as_is()),
("a latent stream too short to be one", "field_range", same(), payload(|o| o.rans.truncate(4))),
("a latent stream that runs out", "stream_exhausted", same(), payload(|o| { let n = o.rans.len() / 2; o.rans.truncate(n - n % 4); })),
("a word left unread in the latent stream", "stream_noncanonical", same(), payload(|o| o.rans.extend([0, 0, 0, 0]))),
("means past g_s's range", "field_range", h_bias(|b, m| b[m..].iter_mut().for_each(|v| *v = 1 << 55)), as_is()),
("means near i64's end", "field_range", h_bias(|b, m| b[m..].iter_mut().for_each(|v| *v = i64::MAX - (1 << 20))), as_is()),
];
for (what, want, set, o) in &fixtures {
let (ops, direct) = both(set, o);
assert_eq!((ops.err(), direct.err()), (Some(*want), Some(*want)), "{what}: through the lowering, then directly");
}
}
/// Gate 3, at the edge of every `check` range: for each layer of the committed `h_s` and
/// `g_s`, a network of that layer alone (with the set's header; a leaky ReLU followed by a
/// zero 1×1 transposed convolution, since a network with no layer of tag 0, 1 or 2 does
/// not lower) is lowered, and its input's `check` range is `[−X_ℓ, X_ℓ]`, the range the
/// full graph gives tensor `ℓ` (§13.2). An input whose largest magnitude is `X_ℓ` runs,
/// through the lowering and directly, to the same output; one at `X_ℓ + 1` is refused by
/// both: by the graph (`field_range`, at input 0) and by the direct decode's check of that
/// layer (`run_net_checked`, a value out of range at layer 0). So the ranges refuse exactly
/// what integer-payloads §7 *Exactness* refuses, at the same layer.
#[test]
fn every_check_range_refuses_exactly_what_the_direct_decode_refuses() {
use hyper::{legacy::run_net_checked, IntLayer};
use wai_ops::{Code, Site, Tensor};
let mut seen = 0;
for (net, rgb8) in [("tiny_h_s.bin", false), ("tiny_g_s.bin", true)] {
let set = read(&format!("{DIR}/{net}"));
let full = wai_ops::lower::whm1(&set, rgb8).unwrap();
let n = wai_ops::lower::parse_whm1(&set).unwrap().layers.len();
for l in 0..n {
let mut one = IntModel::from_bytes(&set).unwrap();
let layer = one.layers.swap_remove(l);
let leaky = matches!(layer, IntLayer::Leaky { .. });
one.layers = vec![layer];
let c = full.tensors[l].channels;
if leaky {
one.layers.push(IntLayer::ConvT { out_ch: 1, k: 1, stride: 1, pad: 0, opad: 0, weight: vec![0; c as usize], mult: vec![1], bias: vec![0] });
}
let g = wai_ops::lower::whm1_net(&wai::int_ops::whm1_net(&one).unwrap(), false).unwrap();
let (lo, hi) = (g.tensors[0].lo, g.tensors[0].hi);
assert_eq!((g.tensors[0].channels, lo, hi), (c, full.tensors[l].lo, full.tensors[l].hi), "{net} layer {l}: the range of tensor {l}");
assert!(hi > 0 && lo == -hi, "{net} layer {l}: a symmetric check range [{lo}, {hi}]");
let loaded = wai::int_ops::load(&g).unwrap();
let x = |v: i64| {
let mut d = vec![0i64; c as usize * 4];
d[c as usize * 2 + 1] = v;
d
};
for v in [hi, -hi] {
let ops = wai::int_ops::run1(&loaded, Tensor::new(c, 2, 2, x(v)), &[]).unwrap_or_else(|r| panic!("{net} layer {l}: {v} runs: {r:?}"));
let (direct, ..) = run_net_checked(&one, &x(v), c as usize, 2, 2).unwrap_or_else(|r| panic!("{net} layer {l}: {v} runs directly: {r}"));
assert!(ops.data == direct, "{net} layer {l}: at {v} the two differ");
}
for v in [hi + 1, -hi - 1] {
let r = wai::int_ops::run1(&loaded, Tensor::new(c, 2, 2, x(v)), &[]).expect_err("one past the range");
assert_eq!((r.code, r.at), (Code::FieldRange, Site::Input(0)), "{net} layer {l}: {v}");
let d = run_net_checked(&one, &x(v), c as usize, 2, 2).expect_err("one past the range, directly");
assert!(d.out_of_range && d.layer == 0, "{net} layer {l}: {v}: {d}");
}
seen += 1;
}
}
assert_eq!(seen, 6, "every layer of the committed h_s and g_s");
}
/// Gate 5 of the migration, the whole-decoder half: the decode through the lowering under
/// the reference kernels (the interpreter computes every operator) and under each fast
/// policy (the convolutions, the transposed convolutions and the inverse GDN on this
/// crate's fast kernels, serial and threaded) gives the same image, and the same
/// refusals, on the committed vector (as `WIH1`, as its JSON form, and with the set's JSON
/// models), and on sets whose hyper-latent channel 0 lies about the edge of `h_s`'s input
/// check range (its median at `±X_0` and one past it). The per-operator half is `int_ops`' equivalence
/// tests, one of which counts the fast kernels' runs on this set.
#[test]
fn every_kernel_policy_decodes_through_the_lowering_alike() {
use wai::int_kernels::{with_policy, Policy};
static POLICIES: std::sync::LazyLock<Vec<Policy>> = std::sync::LazyLock::new(wai::int_kernels::equivalence_policies);
let x0 = wai_ops::lower::whm1(&read(&format!("{DIR}/tiny_h_s.bin")), false).unwrap().tensors[0].hi;
let base = Owned::committed();
let bs = hyper::CondBitstream::try_from_value(&json(&format!("{DIR}/tiny_bitstream.json"))).unwrap();
let from_json = |f: &str| IntModel::try_from_json(&json(&format!("{DIR}/{f}"))).unwrap();
let json_models = (from_json("tiny_g_s.json"), from_json("tiny_h_s.json"), tiny(|_, _, _| {}).2);
let json_form = Owned { m: bs.m, sh: bs.sh, sw: bs.sw, n_z: bs.n_z, zh: bs.zh, zw: bs.zw, z_rans: bs.z_rans.clone(), rans: bs.rans.clone() };
let mut cases: Vec<(String, (IntModel, IntModel, hyper::CondEntropy), Owned)> =
vec![("WIH1".into(), tiny(|_, _, _| {}), base.clone()), ("JSON".into(), tiny(|_, _, _| {}), json_form), ("JSON models".into(), json_models, base.clone())];
// Channel 0's median moved to ±X_0 or one past it: its elements, the median plus each
// symbol at 2^12, lie about the edge of h_s's input check range.
for (what, t) in [("channel 0 at X_0", x0), ("at X_0 + 1", x0 + 1), ("at -X_0", -x0), ("at -X_0 - 1", -x0 - 1)] {
cases.push((what.into(), tiny(move |_, _, e| e.z_median_q[0] = t), base.clone()));
}
for (k, (what, set, o)) in cases.iter().enumerate() {
let (g, h, e) = set;
let want = with_policy(POLICIES[0], || hyper::ops::decode(g, h, e, &o.st())).map(|d| d.0).map_err(code_of);
assert!(k >= 3 || want.is_ok(), "{what}: the committed form decodes");
for pol in &POLICIES[1..] {
let got = with_policy(*pol, || hyper::ops::decode(g, h, e, &o.st())).map(|d| d.0).map_err(code_of);
assert!(got == want, "{what}: {pol:?} differs from the interpreter alone");
}
}
}
/// Every committed `WIH1` payload, alone or inside another file (a `WIV1`'s keyframe, an
/// envelope, a staged base, a counting fixture): each occurrence of the magic in the
/// corpora that hold integer payloads whose bytes from there parse as a `WIH1` of exactly
/// the length its header and stream lengths give. Returns `(where, payload)` pairs.
fn committed_wih1_payloads() -> Vec<(String, Vec<u8>)> {
fn files(d: &std::path::Path, out: &mut Vec<PathBuf>) {
let mut es: Vec<_> = std::fs::read_dir(d).unwrap().filter_map(|e| e.ok()).map(|e| e.path()).collect();
es.sort();
for p in es {
if p.is_dir() { files(&p, out) } else { out.push(p) }
}
}
let mut all = Vec::new();
for d in ["int-payload-conformance", "staged-conformance", "staged-measure-conformance", "http-conformance/objects", "wai-rs/tests/vectors"] {
files(&wai().join(d), &mut all);
}
let u32_at = |b: &[u8], i: usize| b.get(i..i + 4).map(|s| u32::from_le_bytes(s.try_into().unwrap()) as usize);
let mut v = Vec::new();
for f in all {
let b = std::fs::read(&f).unwrap();
for i in (0..b.len().saturating_sub(3)).filter(|&i| &b[i..i + 4] == b"WIH1") {
let Some(lz) = u32_at(&b, i + 32) else { continue };
let Some(ly) = i.checked_add(36 + lz).and_then(|j| u32_at(&b, j)) else { continue };
let end = i + 40 + lz + ly;
if let Some(p) = b.get(i..end).filter(|p| wai::int_wire::parse_wih1(p).is_ok()) {
v.push((format!("{}@{i}", f.strip_prefix(wai()).unwrap().display()), p.to_vec()));
}
}
}
v
}
/// The scan for the load rules the switch brings (integer-operators §15.3 item 3): no
/// committed set or payload is affected. Every committed set of either capability has a
/// layer of tag 0, 1 or 2 in each network, header shifts under 128, no bias of magnitude
/// `2^63 − 1` or more, and its two networks lower and load under `acc64`; every committed
/// `WIH1` payload, wherever it is carried, decodes through the lowering to the bytes the
/// direct decode gives, or is refused by both with the same code, against the set every
/// committed one is decoded with (`tiny`). (The other files that hold the magic are code:
/// the browser crate's recorded build, its demo page and its scripts.)
#[test]
fn the_new_load_rules_affect_no_committed_set_or_payload() {
use wai_ops::lower::NetLayer as N;
for s in indexed() {
for (role, rgb8) in [("h_s.whm", false), ("g_s.whm", true)] {
let b = s.member(role);
let net = wai_ops::lower::parse_whm1(&b).unwrap();
assert!(net.layers.iter().any(|l| matches!(l, N::ConvT { .. } | N::Conv { .. } | N::Igdn { .. })), "{} {role}: no layer of tag 0, 1 or 2", s.name);
assert!(net.shift < 128 && net.gf < 128, "{} {role}: a header shift of 128 or more", s.name);
for l in &net.layers {
if let N::ConvT { bias, .. } | N::Conv { bias, .. } = l {
assert!(bias.iter().all(|b| b.unsigned_abs() < i64::MAX as u64), "{} {role}: a bias of magnitude 2^63 - 1 or more", s.name);
}
}
let g = wai_ops::lower::whm1(&b, rgb8).unwrap_or_else(|r| panic!("{} {role}: does not lower: {r:?}", s.name));
assert!(wai::int_ops::load(&g).is_ok(), "{} {role}: does not load under acc64", s.name);
}
}
let set = tiny(|_, _, _| {});
let (mut decoded, mut refused) = (0, 0);
let payloads = committed_wih1_payloads();
for (at, p) in &payloads {
let k = wai::int_wire::parse_wih1(p).unwrap();
let o = Owned { m: k.m as usize, sh: k.sh as usize, sw: k.sw as usize, n_z: k.n_z as usize, zh: k.zh as usize, zw: k.zw as usize, z_rans: k.z_rans.to_vec(), rans: k.rans.to_vec() };
let (ops, direct) = both(&set, &o);
assert!(ops == direct, "{at}: the decode through the lowering differs from the direct decode");
if ops.is_ok() { decoded += 1 } else { refused += 1 }
}
let staged = payloads.iter().filter(|(at, _)| at.starts_with("staged-conformance")).count();
assert!(decoded >= 10 && refused >= 5 && staged >= 5, "the committed WIH1 payloads, at least those of this revision: {decoded} decoded, {refused} refused, {staged} staged");
}