One squashed history of three stacked PRs, onto main atb16816671: - #426 (wai/pack-efficiency): a title's whole AV1 ladder in one package over one integer base; several floor rungs (packaging §7.1), a re-pack from a parent (§11.5), a floor that is the ladder's own CMAF (§7.7), a floor-only profile (§7.8), a streaming pack (§11.4), and the independent verifier at scale (§9.4). - #438 (wai/cross-fabric): each pack and verify step on the fabric with the least measured energy (§11.6); the `fabrics` member of measurement claims (jwp-receipts §2.4.8, energy-measurement §6.3); the wai-pack-gpu crate; `wai-pack fabric`; `wai-pack floor-decode`. - #452 (wai/gpu-int-tier), its GPU-tier part only: claiming decode-equivalence on a GPU (determinism-tiers §5), the WGSL integer semantics suite, the rules check on naga's IR, and the kernels' shift masks and min(max()) clamps. Left out, by the review's split (EN-C takes it over): #452's platform decode in dispatch, its commits6ad92e2e8,8695bc75fandfed8694f4and its CHANGELOG entry: extensions/platform-decode.md, platform-decode-conformance/, wai::platform_decode, wai-web's platform_decode bundle and demo, and its two SPEC.md sentences. #438's research note is not carried as written: it is rewritten as wai/research/cross-fabric.md, with hardware named by architecture, PCI id and OS version, and every table marked as one run. floor_decode.rs and a wai_pack.rs comment name the platform's media engine and a full-length film the same way. wai/CHANGELOG.md is the union of both sides' entries, the stack's first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
86 lines
4.1 KiB
Rust
86 lines
4.1 KiB
Rust
//! An edited kernel is caught: each mutant below changes one expression of a shipped
|
|
//! kernel (a tie rule, a rounding addend, a clamp bound, a square, a rotation, a flag),
|
|
//! and the cases of `kernels.rs` must find a result that differs from the reference on
|
|
//! every adapter. A mutant they did not catch would be a part of a kernel the tests do
|
|
//! not hold.
|
|
|
|
mod support;
|
|
|
|
use support::*;
|
|
use wai_pack_gpu::Sources;
|
|
|
|
struct Mutant {
|
|
name: &'static str,
|
|
kernel: &'static str,
|
|
from: &'static str,
|
|
to: &'static str,
|
|
}
|
|
|
|
const MUTANTS: &[Mutant] = &[
|
|
Mutant { name: "the earlier vector loses a tie", kernel: "motion", from: "return i < bi;", to: "return i > bi;" },
|
|
Mutant { name: "the longer vector wins a tie", kernel: "motion", from: "return l < bl;", to: "return l > bl;" },
|
|
Mutant { name: "a horizontal half-pel truncates", kernel: "motion", from: "return (px(iy, ix, c) + px(iy, ix + 1, c) + 1) >> 1u;", to: "return (px(iy, ix, c) + px(iy, ix + 1, c)) >> 1u;" },
|
|
Mutant { name: "a diagonal half-pel rounds by 1", kernel: "motion", from: "px(iy + 1, ix + 1, c) + 2) >> 2u;", to: "px(iy + 1, ix + 1, c) + 1) >> 2u;" },
|
|
Mutant { name: "a column past the frame is read", kernel: "motion", from: "clamp(xx, 0, i32(P.w) - 1)", to: "clamp(xx, 0, i32(P.w))" },
|
|
Mutant { name: "the reduction skips a lane", kernel: "motion", from: "for (var s = WG / 2u; s > 0u; s = s >> 1u)", to: "for (var s = WG / 2u; s > 1u; s = s >> 1u)" },
|
|
Mutant { name: "the absolute difference, not its square", kernel: "sse", from: "acc = acc + u32(d * d);", to: "acc = acc + u32(abs(d));" },
|
|
Mutant { name: "a rotation by 11", kernel: "blake3", from: "v[b] = rotr(v[b] ^ v[c], 12u);", to: "v[b] = rotr(v[b] ^ v[c], 11u);" },
|
|
Mutant { name: "a permutation entry swapped", kernel: "blake3", from: "m[0] = o[2];\n m[1] = o[6];", to: "m[0] = o[6];\n m[1] = o[2];" },
|
|
Mutant { name: "the root flag of a parent's value", kernel: "blake3", from: "const ROOT: u32 = 8u;", to: "const ROOT: u32 = 4u;" },
|
|
Mutant { name: "every chunk counted as the first", kernel: "blake3", from: "v[12] = job.counter_lo;", to: "v[12] = 0u;" },
|
|
Mutant { name: "a short last block counted whole", kernel: "blake3", from: "v[14] = block_len;", to: "v[14] = 64u;" },
|
|
];
|
|
|
|
fn edited(m: &Mutant) -> Sources {
|
|
let mut s = Sources::shipped();
|
|
let k = match m.kernel {
|
|
"motion" => &mut s.motion,
|
|
"sse" => &mut s.sse,
|
|
_ => &mut s.blake3,
|
|
};
|
|
assert_eq!(k.matches(m.from).count(), 1, "{}: the expression is in the kernel once", m.name);
|
|
*k = k.replacen(m.from, m.to, 1);
|
|
s
|
|
}
|
|
|
|
/// Whether the kernel cases find a difference from the reference on `g`.
|
|
fn caught(g: &wai_pack_gpu::Gpu, kernel: &str) -> bool {
|
|
match kernel {
|
|
"motion" => {
|
|
let mut rng = Rng(0x5eed_0001);
|
|
MOTION_CASES.iter().any(|&(h, w, block, range, prec)| {
|
|
frame_pairs(&mut rng, h, w).into_iter().any(|(_, src, rf)| g.motion_frame(&src, &rf, h, w, block, range, prec).ok() != Some(search(&src, &rf, h, w, block, range, prec)))
|
|
})
|
|
}
|
|
"sse" => {
|
|
let mut rng = Rng(0x5eed_0002);
|
|
[1usize, 4097, 65_537].iter().any(|&n| {
|
|
let (a, b) = (rng.bytes(n), rng.bytes(n));
|
|
g.sse(&a, &b).ok() != Some(sse(&a, &b))
|
|
})
|
|
}
|
|
_ => {
|
|
let inputs: Vec<Vec<u8>> = BLAKE3_LENGTHS.iter().map(|&n| blake3_input(n)).collect();
|
|
let refs: Vec<&[u8]> = inputs.iter().map(|v| v.as_slice()).collect();
|
|
match g.blake3_many(&refs) {
|
|
Ok(hs) => refs.iter().zip(hs).any(|(m, h)| &h != blake3::hash(m).as_bytes()),
|
|
Err(_) => true,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn every_mutant_is_caught() {
|
|
if gpus().is_empty() {
|
|
return;
|
|
}
|
|
for m in MUTANTS {
|
|
let found = gpus_with(&edited(m), m.name);
|
|
assert!(!found.is_empty(), "{}: the mutant did not compile, so it proves nothing", m.name);
|
|
for g in &found {
|
|
assert!(caught(g, m.kernel), "{}: {} not caught", g.adapter().label(), m.name);
|
|
}
|
|
eprintln!("caught: {} ({})", m.name, m.kernel);
|
|
}
|
|
}
|