weirflow 0.1.0

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

#[test]
fn resident_ifds_batch_many_into_reuses_result_slots() {
    let prepared = prepared_fixture();
    let dispatch = FakeResidentDispatch::new();
    let mut batch = ResidentIfdsBatch::new();
    let seed_a = [(0, 0, 0)];
    let seed_b = [(0, 1, 0)];
    let mut results = vec![Vec::with_capacity(1), Vec::with_capacity(1)];
    let outer_ptr = results.as_ptr();
    let first_ptr = results[0].as_ptr();
    let second_ptr = results[1].as_ptr();
    let outer_capacity = results.capacity();

    batch
        .solve_prepared_many_into(
            &dispatch,
            &prepared,
            &[&seed_a[..], &seed_b[..]],
            4,
            &mut results,
        )
        .expect("first resident IFDS batch solve must fill caller-owned results");
    assert_eq!(results, vec![vec![0], vec![1024]]);
    assert_eq!(results.as_ptr(), outer_ptr);
    assert_eq!(results.capacity(), outer_capacity);
    assert_eq!(results[0].as_ptr(), first_ptr);
    assert_eq!(results[1].as_ptr(), second_ptr);

    results[0].clear();
    results[1].clear();
    batch
        .solve_prepared_many_into(
            &dispatch,
            &prepared,
            &[&seed_a[..], &seed_b[..]],
            4,
            &mut results,
        )
        .expect("second resident IFDS batch solve must reuse caller-owned results");

    assert_eq!(results, vec![vec![0], vec![1024]]);
    assert_eq!(results.as_ptr(), outer_ptr);
    assert_eq!(results.capacity(), outer_capacity);
    assert_eq!(results[0].as_ptr(), first_ptr);
    assert_eq!(results[1].as_ptr(), second_ptr);
    assert_eq!(batch.csr_cache_stats().hits, 1);
    assert_eq!(batch.stats().scratch_allocations, 1);
    assert_eq!(batch.stats().scratch_reuses, 1);
}

#[test]
fn resident_ifds_batch_single_into_reuses_result_and_internal_row_slots() {
    let prepared = prepared_fixture();
    let dispatch = FakeResidentDispatch::new();
    let mut batch = ResidentIfdsBatch::new();
    let seed_a = [(0, 0, 0)];
    let seed_b = [(0, 1, 0)];
    let mut result = Vec::with_capacity(1);
    let result_ptr = result.as_ptr();
    let result_capacity = result.capacity();

    batch
        .solve_prepared_into(&dispatch, &prepared, &seed_a, 4, &mut result)
        .expect("first single-seed resident IFDS batch solve must fill caller result");
    assert_eq!(result, vec![0]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);
    assert_eq!(batch.single_result_scratch.len(), 1);
    let scratch_row_ptr = batch.single_result_scratch[0].as_ptr();
    let scratch_row_capacity = batch.single_result_scratch[0].capacity();

    result.clear();
    batch
        .solve_prepared_into(&dispatch, &prepared, &seed_b, 4, &mut result)
        .expect("second single-seed resident IFDS batch solve must reuse caller result");

    assert_eq!(result, vec![1024]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);
    assert_eq!(batch.single_result_scratch[0].as_ptr(), scratch_row_ptr);
    assert_eq!(
        batch.single_result_scratch[0].capacity(),
        scratch_row_capacity
    );
    assert_eq!(batch.csr_cache_stats().hits, 1);
    assert_eq!(batch.stats().scratch_allocations, 1);
    assert_eq!(batch.stats().scratch_reuses, 1);
}