vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
// Unit tests for the CPU reference of `workgroup.string_interner`.

use crate::ops::workgroup::primitives::string_interner::{
    InternError, InternedSymbol, WorkgroupStringInterner,
};

#[test]
pub fn intern_is_deterministic_and_idempotent() {
    let mut interner = WorkgroupStringInterner::new(8, 64);
    let a = interner.intern(b"foo").unwrap();
    let b = interner.intern(b"foo").unwrap();
    assert_eq!(a, b, "interning the same bytes must reuse the symbol");
    assert_eq!(interner.len(), 1);
}

#[test]
pub fn distinct_bytes_produce_distinct_symbols() {
    let mut interner = WorkgroupStringInterner::new(8, 64);
    let a = interner.intern(b"foo").unwrap();
    let b = interner.intern(b"bar").unwrap();
    assert_ne!(a, b);
    assert_eq!(interner.len(), 2);
}

#[test]
pub fn lookup_round_trips_the_original_payload() {
    let mut interner = WorkgroupStringInterner::new(8, 64);
    let sym = interner.intern(b"vyre").unwrap();
    assert_eq!(interner.lookup(sym).unwrap(), b"vyre");
}

#[test]
pub fn slot_exhaustion_reports_out_of_slots() {
    let mut interner = WorkgroupStringInterner::new(2, 64);
    interner.intern(b"a").unwrap();
    interner.intern(b"b").unwrap();
    assert_eq!(interner.intern(b"c"), Err(InternError::OutOfSlots));
    assert!(interner.intern(b"a").is_ok());
}

#[test]
pub fn byte_exhaustion_reports_out_of_bytes() {
    let mut interner = WorkgroupStringInterner::new(8, 4);
    interner.intern(b"abcd").unwrap();
    assert_eq!(interner.intern(b"e"), Err(InternError::OutOfBytes));
}

#[test]
pub fn lookup_unknown_symbol_errors() {
    let interner = WorkgroupStringInterner::new(4, 16);
    assert_eq!(
        interner.lookup(InternedSymbol(0)),
        Err(InternError::UnknownSymbol)
    );
}

#[test]
pub fn symbols_are_allocated_in_interning_order() {
    let mut interner = WorkgroupStringInterner::new(4, 64);
    let a = interner.intern(b"alpha").unwrap();
    let b = interner.intern(b"beta").unwrap();
    let c = interner.intern(b"gamma").unwrap();
    assert_eq!(a, InternedSymbol(0));
    assert_eq!(b, InternedSymbol(1));
    assert_eq!(c, InternedSymbol(2));
}

#[test]
pub fn wgsl_kernel_source_exposes_the_expected_entry_point() {
    let wgsl = crate::ops::workgroup::primitives::string_interner::lowering::WGSL;
    assert!(wgsl.contains("workgroup_string_interner_intern"));
    assert!(wgsl.contains("FNV_OFFSET_BASIS"));
}

#[test]
pub fn wgsl_byte_pool_updates_are_atomic() {
    let wgsl = crate::ops::workgroup::primitives::string_interner::lowering::WGSL;
    assert!(wgsl.contains("interner_bytes: array<atomic<u32>"));
    assert!(wgsl.contains("atomicOr(&interner_bytes[word_idx]"));
    assert!(!wgsl.contains("let cleared = interner_bytes[word_idx]"));
}