//! `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()); } } }