open-standards/wai/wai-pack/tests/pack_alloc.rs
Transaction Science 836d0255df wai packaging stack: #426, #438 and #452's GPU tier, squashed onto main
One squashed history of three stacked PRs, onto main at b16816671:

- #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 commits 6ad92e2e8, 8695bc75f and fed8694f4 and 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]>
2026-10-24 20:31:28 -04:00

95 lines
4.9 KiB
Rust

//! What the packer holds does not grow with the source (packaging §11.4): a source eight
//! times as long, read from a file and packed into a directory, allocates at its peak what
//! the short one does, give or take the records of its pieces, though it is millions of
//! bytes longer. Its own binary: it installs a counting global allocator.
use std::alloc::{GlobalAlloc, Layout, System};
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
struct Peak;
static LIVE: AtomicUsize = AtomicUsize::new(0);
static PEAK: AtomicUsize = AtomicUsize::new(0);
unsafe impl GlobalAlloc for Peak {
unsafe fn alloc(&self, l: Layout) -> *mut u8 {
let p = unsafe { System.alloc(l) };
if !p.is_null() {
let now = LIVE.fetch_add(l.size(), Ordering::SeqCst) + l.size();
PEAK.fetch_max(now, Ordering::SeqCst);
}
p
}
unsafe fn dealloc(&self, p: *mut u8, l: Layout) {
unsafe { System.dealloc(p, l) };
LIVE.fetch_sub(l.size(), Ordering::SeqCst);
}
}
#[global_allocator]
static A: Peak = Peak;
fn corpus() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../pack-conformance")
}
/// The golden `video-base-01`'s fixture and supplied floor played `k` times over, written
/// below `dir`: the source as one Y4M, and the floor as one stream of the golden's units
/// repeated, so its key frames fall on the repeated plan; the golden's policy pinned to
/// that floor. Returns the policy, the source's path and the floor's directory.
fn repeated(dir: &Path, k: usize) -> (Vec<u8>, PathBuf, PathBuf) {
let y = wai_pack::fixture::generate("video-base-01").unwrap();
let head = y.iter().position(|&c| c == b'\n').unwrap() + 1;
let mut src = y[..head].to_vec();
for _ in 0..k {
src.extend_from_slice(&y[head..]);
}
let units: Vec<Vec<u8>> = wai_pack::av1::temporal_units(&std::fs::read(corpus().join("packs/video-base-01/floor/v.obu")).unwrap()).unwrap().iter().map(|t| t.bytes()).collect();
let floor_dir = dir.join(format!("floor-{k}"));
std::fs::create_dir_all(&floor_dir).unwrap();
std::fs::write(floor_dir.join("v.obu"), units.iter().cycle().take(k * units.len()).flatten().copied().collect::<Vec<u8>>()).unwrap();
let src_path = dir.join(format!("v-{k}.y4m"));
std::fs::write(&src_path, &src).unwrap();
let listing = wai_pack::floor::listing_sha256(&wai::pin::read_dir_set(&floor_dir).unwrap()).unwrap();
let p = String::from_utf8(std::fs::read(corpus().join("packs/video-base-01/policy.toml")).unwrap()).unwrap();
let at = p.find("supplied_listing = \"").unwrap() + "supplied_listing = \"".len();
(format!("{}{listing}{}", &p[..at], &p[at + 64..]).into_bytes(), src_path, floor_dir)
}
/// Pack into `out` from files, and give the peak allocated beyond what was live before.
fn pack_peak(policy: &[u8], src: &Path, floor: &Path, out: &Path) -> (wai::package::PackageReceiptV2, usize) {
let mut o = wai_pack::pack::PackOpts::with_floor(ed25519_dalek::SigningKey::from_bytes(&[0x5a; 32]), "did:key:test", wai_pack::files::FileSet::Dir(floor.to_path_buf()));
let mut sources = BTreeMap::new();
sources.insert("v".to_string(), wai_pack::files::Input::Path(src.to_path_buf()));
let base = LIVE.load(Ordering::SeqCst);
PEAK.store(base, Ordering::SeqCst);
let mut sink = wai_pack::files::DirSink::new(out).unwrap();
let r = wai_pack::pack::pack_into(policy, &sources, &mut o, &mut sink).unwrap();
sink.keep();
(r, PEAK.load(Ordering::SeqCst) - base)
}
#[test]
fn a_longer_source_takes_no_more_memory() {
let dir = std::env::temp_dir().join(format!("wai-pack-alloc-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let (p1, s1, f1) = repeated(&dir, 1);
let (p8, s8, f8) = repeated(&dir, 8);
let (r1, peak1) = pack_peak(&p1, &s1, &f1, &dir.join("out-1"));
let (r8, peak8) = pack_peak(&p8, &s8, &f8, &dir.join("out-8"));
// The long pack is the short one eight times: eight times the entries, its repeated
// pieces stored once.
assert_eq!(r8.total_entries, 8 * r1.total_entries);
assert_eq!(r8.unique_objects, r1.unique_objects, "every repetition's pieces are the first's objects");
wai_pack::verify::verify_dir(&dir.join("out-8")).unwrap();
let grown = std::fs::metadata(&s8).unwrap().len() - std::fs::metadata(&s1).unwrap().len();
assert!(grown > 4_000_000, "the long source is {grown} bytes longer");
// Its records grow with its pieces (a few hundred bytes each); nothing grows with its
// frames.
eprintln!("peak allocated: {} entries {peak1} B; {} entries {peak8} B", r1.total_entries, r8.total_entries);
let slack = 256 * 1024;
assert!(peak8 < peak1 + slack, "the long pack's peak {peak8} B is past the short one's {peak1} B by more than {slack} B");
let _ = std::fs::remove_dir_all(&dir);
}