//! `wai.avatar.face` (extensions/avatars.md §6 to §13): the committed corpus //! `live-conformance/avatar-face/` regenerates byte for byte from its fixed seeds and its pinned //! inputs, holds no other file, every vector in it gets what it states, the extension's §10 lists //! exactly the reasons the reference reports and the codes its files are refused with, and §7.9's //! measurement is the training tool's report. The generator itself asserts that the corpus gives //! every one of the reasons. #![cfg(feature = "avatar_face")] use std::collections::BTreeMap; use std::path::PathBuf; use wai::avatar_face::{self, corpus, FormError, Reason}; fn wai_dir() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") } fn committed() -> BTreeMap> { let dir = wai_dir().join("live-conformance/avatar-face"); let mut files = BTreeMap::new(); for sub in ["", "identities", "tracks"] { for e in std::fs::read_dir(dir.join(sub)).expect("the committed corpus").flatten() { let name = e.file_name().to_string_lossy().into_owned(); if e.path().is_dir() || (sub.is_empty() && name == "README.md") { continue; } let key = if sub.is_empty() { name } else { format!("{sub}/{name}") }; files.insert(key, std::fs::read(e.path()).expect("a file")); } } files } fn inputs(files: &BTreeMap>) -> BTreeMap> { corpus::INPUTS.iter().filter_map(|(n, _)| files.get(*n).map(|b| (n.to_string(), b.clone()))).collect() } fn section<'a>(text: &'a str, heading: &str) -> &'a str { let at = text.find(heading).unwrap_or_else(|| panic!("{heading}")); let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e); &text[at..end] } fn extension() -> String { std::fs::read_to_string(wai_dir().join("extensions/avatars.md")).expect("the extension") } #[test] fn the_inputs_are_the_pinned_ones() { assert_eq!(corpus::check_inputs(&inputs(&committed())), Vec::::new()); } #[test] fn the_committed_corpus_regenerates_from_its_seeds() { let files = committed(); let mut generated: BTreeMap> = corpus::generate(&inputs(&files)).into_iter().collect(); generated.extend(inputs(&files)); let extra: Vec<&String> = files.keys().filter(|k| !generated.contains_key(*k)).collect(); let missing: Vec<&String> = generated.keys().filter(|k| !files.contains_key(*k)).collect(); let differ: Vec<&String> = generated.iter().filter(|(k, v)| files.get(*k).is_some_and(|f| f != *v)).map(|(k, _)| k).collect(); assert!(extra.is_empty() && missing.is_empty() && differ.is_empty(), "extra {extra:?}, missing {missing:?}, differ {differ:?}: run `wai_avatar_face_vectors gen`"); } #[test] fn every_vector_gets_what_it_states() { let fails = corpus::verify(&committed()); assert!(fails.is_empty(), "{}", fails.join("\n")); } /// §10 lists, in its first table, exactly the codes `Reason::ALL` has, in order, and in its /// second exactly the codes the files are refused with. #[test] fn the_extension_lists_the_reasons() { let text = extension(); let s = section(&text, "\n## 10. Reasons"); let tables: Vec> = s .split("\n\n") .filter(|b| b.lines().any(|l| l.starts_with("| `"))) .map(|b| b.lines().filter(|l| l.starts_with("| `")).filter_map(|l| l.split('`').nth(1).map(String::from)).collect()) .collect(); assert_eq!(tables.len(), 2, "§10 has two tables of codes"); let want: Vec = Reason::ALL.iter().map(|r| r.code().to_string()).collect(); assert_eq!(tables[0], want, "§10's first table and Reason::ALL differ"); let forms: Vec = FormError::ALL.iter().map(|r| r.code().to_string()).collect(); assert_eq!(tables[1], forms, "§10's second table and FormError::ALL differ"); } /// §7.9's tables state the training tool's report, `training.json`, figure for figure. #[test] fn the_measurement_is_the_reports() { let text = extension(); let s = section(&text, "\n### 7.9 "); let files = committed(); let report: serde_json::Value = serde_json::from_slice(&files["training.json"]).expect("training.json"); let m = &report["measurement"]; let f = |v: &serde_json::Value| match v.as_f64() { Some(x) if x.fract() == 0.0 => format!("{x:.1}"), _ => v.to_string(), }; for (key, what) in [("int_float", "integer, float"), ("int_truth", "integer, rendered"), ("float_truth", "float, rendered"), ("warp_truth", "warp alone, rendered")] { let p = &m["psnr_db"][key]; let q = &m["ssim"][key]; let row = format!("| {what} | {} | {} | {} | {} |", f(&p["mean"]), f(&p["min"]), f(&q["mean"]), f(&q["min"])); assert!(s.contains(&row), "§7.9 lacks the row `{row}`"); } for (key, what) in [("truth", "the rendered faces"), ("float", "the float network's"), ("int", "the integer generator's")] { let row = format!("| {what} | {} | {} |", f(&m["keypoint_rms_px"][key]), f(&m["mouth_keypoint_rms_px"][key])); assert!(s.contains(&row), "§7.9 lacks the row `{row}`"); } for (key, what) in [("truth_step4", "rendered, step 4"), ("truth_step1", "rendered, step 1"), ("detected_step4", "detected, step 4"), ("detected_step1", "detected, step 1")] { let row = format!("| {what} | {} |", f(&m["track_kbit_s"][key])); assert!(s.contains(&row), "§7.9 lacks the row `{row}`"); } let g = &report["generator"]; assert_eq!(g["sha256"].as_str(), Some(corpus::INPUTS[0].1), "the report's generator is the corpus's"); } /// The registered generator's graph meets `acc64` and not `acc32` (§7.6), and its frames are /// §7.6's arithmetic written out loop by loop. #[test] fn the_registered_generator_meets_acc64_only() { let files = committed(); let g = &files["generator.wfg"]; assert!(avatar_face::load(g).is_ok()); assert!(!avatar_face::meets_acc32(g), "a 16-bit activation times a 16-bit weight over hundreds of terms passes i32"); }