open-standards/wai/wai-rs/tests/splat_exact_gpu.rs
Transaction Science df87dcde39 splat_exact: the renderer's compositing on a GPU, equal to the CPU on every view
wai-ops-gpu gains the kernel wgsl/splat.wgsl, one invocation a pixel and
one workgroup a 16 x 16 tile, over the operator set's probed 64-bit
products; the host projects, culls and orders. wai-rs's splat_exact::gpu
(features splat_exact, ops_gpu) composes on every adapter found, and
tests/splat_exact_gpu.rs holds every canonical and own-pose view of the
splat corpus to the CPU's frame byte for byte and requires three edited
kernels to be caught. The macos job of wai-ops-gpu.yml runs it under
WAI_OPS_GPU_REQUIRE; the linux job builds it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 03:31:34 -04:00

85 lines
4.1 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-splat-render:i1` with its compositing on a GPU (`splat_exact::gpu`,
//! extensions/splat-exact.md §5.6–§5.7, §11): every canonical view and every own-pose view of
//! every scene of `live-conformance/splat/` composes, on every adapter this process finds, to
//! the frame the CPU gives, byte for byte; and the corpus's views catch each of three edited
//! kernels (a contribution rounded down, no alpha ceiling, the cut-off dropped).
//!
//! **A skip is not a pass.** With no adapter the test prints `splat-exact gpu: SKIPPED` and
//! fails when `WAI_OPS_GPU_REQUIRE` is set; when `WAI_OPS_GPU_EXPECT` names an adapter key,
//! an adapter of that key must be among those found. Each adapter's result is one line,
//! `splat-exact gpu: key=… views=… differ=… mutants_survived=… (adapter)`, appended to
//! `WAI_OPS_GPU_REPORT` when it is set.
#![cfg(all(feature = "splat_exact", feature = "ops_gpu"))]
use std::io::Write;
use wai::splat_exact::gpu::{render, render_with, wai_ops_gpu};
use wai::splat_exact::{corpus, gaussians, render as cpu_render};
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();
}
}
/// Edits of the kernel, each a rule of §5.6 changed.
fn mutants() -> Vec<(&'static str, String)> {
let src = wai_ops_gpu::splat::source();
let edit = |from: &str, to: &str| {
assert_eq!(src.matches(from).count(), 1, "{from}");
src.replace(from, to)
};
vec![
("contribution rounded down", edit("let c = (alpha * t + 32768u) >> 16u;", "let c = (alpha * t) >> 16u;")),
("no alpha ceiling", edit("(w & 0xFFFFu)) >> 16u), 64880u);", "(w & 0xFFFFu)) >> 16u), 65536u);")),
("no cut-off", edit("if (d2 > CUTOFF) {", "if (d2 > CUTOFF * 2) {")),
]
}
#[test]
fn every_view_composes_on_the_gpu_to_the_cpu_frame() {
let found = wai_ops_gpu::blocking::discover();
for (a, why) in &found.refused {
println!("adapter refused: {} ({why})", a.describe());
}
if let Ok(want) = std::env::var("WAI_OPS_GPU_EXPECT") {
assert!(found.found.iter().any(|g| g.adapter().key() == want), "WAI_OPS_GPU_EXPECT is {want}, and no adapter of that key was found");
}
if found.found.is_empty() {
report("splat-exact gpu: SKIPPED (no adapter)");
assert!(std::env::var_os("WAI_OPS_GPU_REQUIRE").is_none(), "WAI_OPS_GPU_REQUIRE is set and no adapter was found");
return;
}
let scenes: Vec<_> = corpus::scenes().into_iter().map(|(n, p, poses)| (n, gaussians(&p).unwrap(), poses)).collect();
let muts = mutants();
for g in &found.found {
let (mut views, mut equal) = (0, 0);
let mut caught = vec![false; muts.len()];
for (name, gs, poses) in &scenes {
for (i, p) in poses.iter().enumerate() {
let cpu = cpu_render(gs, p).expect("a frame");
let gpu = render(g, gs, p).expect("the device ran").expect("a frame");
views += 1;
if gpu == cpu {
equal += 1;
} else {
let n = cpu.iter().zip(&gpu).filter(|(a, b)| a != b).count();
println!("{name} view {i}: {n} bytes differ on {}", g.adapter().key());
}
for (m, (_, text)) in muts.iter().enumerate() {
if !caught[m] && render_with(g, Some(text), gs, p).expect("the device ran").expect("a frame") != cpu {
caught[m] = true;
}
}
}
}
let n_caught = caught.iter().filter(|c| **c).count();
report(&format!("splat-exact gpu: key={} views={views} differ={} mutants_survived={} ({})", g.adapter().key(), views - equal, muts.len() - n_caught, g.adapter().describe()));
assert_eq!(equal, views, "every view composes to the CPU's frame on {}", g.adapter().key());
for (m, c) in caught.iter().enumerate() {
assert!(c, "the mutant '{}' was not caught on {}", muts[m].0, g.adapter().key());
}
}
}