open-standards/wai/wai-rs/tests/avatar_face_gpu.rs
Transaction Science 46e081ab8f wai.avatar.face: an integer talking-head generator, its records and its verification (avatar_face)
Registers wai.avatar.face (GenerativeDeterministic, ops face-int/1, one-file parameter set):
the WFG1 generator, WFI1 identity prior and WFK1 keypoint segment readers and writers; the
driver's integer warp and keypoint maps; the lowering face-int/1 to one wai-ops/1-i32 graph,
with the same arithmetic written out loop by loop for the tests; the identity and track
records; verification over them and synthesis's claims, log and label policy; the corpus
generator (bin wai_avatar_face_vectors) and the corpus and GPU tests. Registry export
regenerated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 10:57:20 -04:00

90 lines
3.9 KiB
Rust

//! `face-int/1` on a GPU (extensions/avatars.md §7.8): every frame the corpus names, generated
//! with the generator's graph on each adapter this process finds, through `wai-ops/1-i32` in WGSL
//! (`int_ops::gpu`), is the frame the CPU generates, byte for byte, and the digest the corpus
//! states. Every graph the device runs is also run on the interpreter and the two compared
//! (`gpu::with_gpu_compared`), so the equality is shown graph by graph.
//!
//! **A skip is not a pass:** with no adapter the test prints `face-gpu: SKIPPED` and fails when
//! `WAI_OPS_GPU_REQUIRE` is set. Each adapter's result is one line, `face-gpu: key=…`, appended
//! to `WAI_OPS_GPU_REPORT` when it is set, with the time each path took.
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;
use serde_json::Value;
use sha2::{Digest, Sha256};
use wai::avatar_face::{frame, load, parse_identity};
use wai::int_ops::gpu::{self, wai_ops_gpu};
fn report(line: &str) {
println!("{line}");
if let Ok(p) = std::env::var("WAI_OPS_GPU_REPORT") {
let mut f = std::fs::OpenOptions::new().create(true).append(true).open(&p).unwrap();
writeln!(f, "{line}").unwrap();
}
}
fn hex(b: &[u8]) -> String {
b.iter().map(|x| format!("{x:02x}")).collect()
}
#[test]
fn every_frame_on_every_adapter_is_the_cpus() {
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../live-conformance/avatar-face");
let doc: Value = serde_json::from_slice(&std::fs::read(dir.join("vectors.json")).unwrap()).unwrap();
let vectors: Vec<&Value> = doc["frames"].as_array().unwrap().iter().collect();
let generate_all = || -> Vec<Vec<u8>> {
vectors
.iter()
.map(|v| {
let (g, l) = load(&std::fs::read(dir.join(v["generator"].as_str().unwrap())).unwrap()).unwrap();
let id = parse_identity(&std::fs::read(dir.join(v["identity"].as_str().unwrap())).unwrap()).unwrap();
let kp: Vec<(i32, i32)> = v["keypoints"].as_array().unwrap().iter().map(|p| (p[0].as_i64().unwrap() as i32, p[1].as_i64().unwrap() as i32)).collect();
frame(&g, &l, &id, &kp).unwrap()
})
.collect()
};
let t = Instant::now();
let cpu = generate_all();
let cpu_ms = t.elapsed().as_secs_f64() * 1e3;
for (v, f) in vectors.iter().zip(&cpu) {
assert_eq!(hex(&Sha256::digest(f)), v["frame_sha256"].as_str().unwrap(), "{}: the CPU's frame is the corpus's", v["name"]);
}
let found = wai_ops_gpu::blocking::discover();
let adapters = found.found;
if adapters.is_empty() {
report("face-gpu: SKIPPED (no adapter)");
assert!(std::env::var("WAI_OPS_GPU_REQUIRE").is_err(), "WAI_OPS_GPU_REQUIRE is set and no adapter was found");
return;
}
for g in adapters {
let g = Arc::new(g);
let t = Instant::now();
let (got, stats) = gpu::with_gpu_compared(&g, generate_all);
let compared_ms = t.elapsed().as_secs_f64() * 1e3;
let t = Instant::now();
let (again, _) = gpu::with_gpu(&g, generate_all);
let gpu_ms = t.elapsed().as_secs_f64() * 1e3;
let same = got == cpu && again == cpu;
report(&format!(
"face-gpu: key={} frames={} same={} graphs_on_gpu={} (acc32 {}, acc64 {}) on_cpu={} compared={} differed={} errors={:?} cpu_ms={cpu_ms:.0} gpu_ms={gpu_ms:.0} compared_ms={compared_ms:.0}",
g.adapter().key(),
cpu.len(),
same,
stats.on_gpu(),
stats.acc32,
stats.acc64,
stats.on_cpu(),
stats.compared,
stats.differed,
stats.errors
));
assert!(same, "the frames on the device are the CPU's");
assert!(stats.on_gpu() > 0 && stats.on_cpu() == 0, "every graph ran on the device");
assert_eq!(stats.differed, 0);
assert!(stats.errors.is_empty());
}
}