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]>
47 lines
2.4 KiB
Rust
47 lines
2.4 KiB
Rust
//! One device shared by many threads, as a pack that codes many pieces at once shares
|
|
//! it: every call of every thread completes on the device (none is handed back to the
|
|
//! CPU) and gives the reference's result. A call whose buffer map is completed by another
|
|
//! thread's poll is the case this holds: the wait is for the map, not only for the
|
|
//! submission.
|
|
|
|
mod support;
|
|
|
|
use support::*;
|
|
|
|
#[test]
|
|
fn every_call_completes_under_many_threads() {
|
|
for g in gpus() {
|
|
let (h, w, block, range, prec) = (24usize, 40usize, 8usize, 3i64, 2i64);
|
|
let mut rng = Rng(0x5eed_0004);
|
|
let pairs: Vec<(Vec<u8>, Vec<u8>)> = (0..8).map(|_| (rng.bytes(h * w * 3), rng.bytes(h * w * 3))).collect();
|
|
let want: Vec<Vec<(i16, i16)>> = pairs.iter().map(|(s, r)| search(s, r, h, w, block, range, prec)).collect();
|
|
let msgs: Vec<Vec<u8>> = (0..8).map(|i| rng.bytes(1000 + 997 * i)).collect();
|
|
let failures = std::sync::atomic::AtomicU64::new(0);
|
|
std::thread::scope(|s| {
|
|
for t in 0..16 {
|
|
let (g, pairs, want, msgs, failures) = (&g, &pairs, &want, &msgs, &failures);
|
|
s.spawn(move || {
|
|
for i in 0..600 {
|
|
let k = (t + i) % pairs.len();
|
|
let ok = if i % 3 == 0 {
|
|
let m: Vec<&[u8]> = vec![msgs[k].as_slice()];
|
|
g.blake3_many(&m).map(|h| &h[0] == blake3::hash(&msgs[k]).as_bytes())
|
|
} else {
|
|
g.motion_frame(&pairs[k].0, &pairs[k].1, h, w, block, range, prec).map(|v| v == want[k])
|
|
};
|
|
match ok {
|
|
Ok(true) => {}
|
|
Ok(false) => panic!("{}: thread {t} call {i}: a result other than the reference's", g.adapter().label()),
|
|
Err(_) => {
|
|
failures.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
let n = failures.load(std::sync::atomic::Ordering::Relaxed);
|
|
assert_eq!(n, 0, "{}: {n} of 9,600 calls did not complete on the device", g.adapter().label());
|
|
eprintln!("{}: 16 threads, 9,600 calls, every one completed with the reference's result", g.adapter().label());
|
|
}
|
|
}
|