weirflow 0.1.0

GPU-first dataflow analysis primitives for Vyre and Santh compiler pipelines.
Documentation
use super::*;

#[test]
fn direct_ifds_bounded_cache_evicts_least_recently_used_entry() {
    let mut batch = super::DirectResidentIfdsBatch::<u64>::with_max_entries(2);
    let dispatch = FreeOnlyDispatch {
        freed: RefCell::new(Vec::new()),
    };
    let cold = key(1);
    let hot = key(2);

    batch.entries.insert(
        cold.clone(),
        DirectIfdsEntry {
            retained_bytes: 24,
            last_seen: 0,
            graph: resident(10),
        },
    );
    batch.entries.insert(
        hot.clone(),
        DirectIfdsEntry {
            retained_bytes: 24,
            last_seen: 0,
            graph: resident(20),
        },
    );
    batch.retained_bytes = 48;
    batch.touch_key(&cold).expect("cold touch should record");
    batch.touch_key(&hot).expect("hot touch should record");
    batch
        .touch_key(&cold)
        .expect("second cold touch should record");

    batch
        .evict_until_room(&dispatch, 24)
        .expect("bounded direct IFDS cache must evict one resident entry");

    assert!(
        batch.entries.contains_key(&cold),
        "recently touched direct IFDS graph must remain resident"
    );
    assert!(
        !batch.entries.contains_key(&hot),
        "least recently used direct IFDS graph must be evicted"
    );
    assert_eq!(
        dispatch.freed.borrow().as_slice(),
        &[20, 21, 22, 23, 24],
        "direct IFDS eviction must free every resident CSR buffer for the LRU graph"
    );
    assert_eq!(batch.evictions, 1);
    assert_eq!(batch.stats().retained_bytes, 24);
    assert_eq!(batch.stats().direct_prepare_bytes, 0);
}

#[test]
fn direct_ifds_lru_heap_compacts_hot_touches() {
    let mut batch = super::DirectResidentIfdsBatch::<u64>::with_max_entries(2);
    let dispatch = FreeOnlyDispatch {
        freed: RefCell::new(Vec::new()),
    };
    let cached = key(7);

    batch.entries.insert(
        cached.clone(),
        DirectIfdsEntry {
            retained_bytes: 24,
            last_seen: 0,
            graph: resident(70),
        },
    );
    batch.retained_bytes = 24;
    for _ in 0..160 {
        batch
            .touch_key(&cached)
            .expect("cached touch should record and compact");
    }

    assert_eq!(batch.entries.len(), 1);
    let stale_limit = batch
        .entries
        .len()
        .checked_mul(4)
        .and_then(|value| value.checked_add(32))
        .expect("test direct IFDS stale LRU limit must fit usize");
    assert!(
            batch.lru_len_for_tests() <= stale_limit,
            "Fix: direct resident IFDS LRU metadata must compact stale hot-hit records instead of growing with every access."
        );
    batch
        .free_all(&dispatch)
        .expect("direct resident IFDS cache must free retained CSR resources");
    assert_eq!(batch.lru_len_for_tests(), 0);
}

#[test]
fn direct_ifds_cache_accounting_uses_checked_arithmetic() {
    let source = include_str!("../cache.rs");

    for forbidden in [
        "retained_bytes.saturating_add",
        "retained_bytes.saturating_sub",
        "direct_prepare_bytes\n            .saturating_add",
        "self.lru.len() <= self.entries.len().saturating_mul(4).saturating_add(32)",
        "BinaryHeap::with_capacity(self.entries.len())",
    ] {
        assert!(
                !source.contains(forbidden),
                "Fix: direct resident IFDS cache accounting must use checked arithmetic, not saturating math that hides budget/accounting corruption: {forbidden}"
            );
    }
}