weirflow 0.1.0

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

#[test]
fn fixed_point_batch_empty_ifds_seeds_return_empty_without_solve_dispatch() {
    let dispatch = |_: &vyre::ir::Program,
                    inputs: &[&[u8]],
                    grid: Option<[u32; 3]>,
                    outputs: &mut Vec<Vec<u8>>| {
        if inputs.len() < 6 {
            return crate::fixed_point_closure::fallback_bitset_equal_dispatch(inputs, outputs);
        }
        match inputs.len() {
            17 => {
                assert_eq!(grid, Some([1, 1, 1]));
                outputs.clear();
                outputs.resize_with(4, Vec::new);
                for word in [0u32, 1, 1] {
                    outputs[0].extend_from_slice(&word.to_le_bytes());
                }
                for word in [0u32, 0] {
                    outputs[1].extend_from_slice(&word.to_le_bytes());
                }
                outputs[2].extend_from_slice(&1u32.to_le_bytes());
                outputs[3].extend_from_slice(&1u32.to_le_bytes());
            }
            7 => {
                panic!("empty seed IFDS solve path should not dispatch solve");
            }
            len => panic!("unexpected IFDS dispatch input count {len}"),
        }
        Ok(())
    };
    let mut batch = FixedPointBatch::new(&dispatch);
    let prepared = batch
        .prepare_ifds(1, 2, 1, &[(0, 0, 1)], &[], &[], &[])
        .expect("batch must prepare IFDS CSR once");
    let empty_a: &[(u32, u32, u32)] = &[];
    let empty_b: &[(u32, u32, u32)] = &[];
    let empty_c: &[(u32, u32, u32)] = &[];
    let empty_d: &[(u32, u32, u32)] = &[];
    let mut single_result = Vec::new();
    batch
        .ifds_prepared_into(&prepared, empty_a, 4, &mut single_result)
        .expect("empty-seed prepared IFDS solve must succeed");
    assert_eq!(single_result, Vec::<u32>::new());

    let direct = batch
        .ifds(1, 2, 1, &[(0, 0, 1)], &[], &[], &[], empty_b, 4)
        .expect("empty-seed direct IFDS solve must succeed");
    assert_eq!(direct, Vec::<u32>::new());

    let mut direct_into = vec![0xCC, 0xDD];
    batch
        .ifds_into(
            1,
            2,
            1,
            &[(0, 0, 1)],
            &[],
            &[],
            &[],
            empty_b,
            4,
            &mut direct_into,
        )
        .expect("empty-seed direct IFDS solve-into must succeed");
    assert_eq!(direct_into, Vec::<u32>::new());

    let mut many_results = vec![vec![0xAA], vec![0xBB], vec![0xCC]];
    batch
        .ifds_many_into(
            1,
            2,
            1,
            &[(0, 0, 1)],
            &[],
            &[],
            &[],
            &[empty_a, empty_b, empty_c],
            4,
            &mut many_results,
        )
        .expect("empty batch IFDS solve must succeed");
    assert_eq!(
        many_results,
        vec![Vec::<u32>::new(), Vec::<u32>::new(), Vec::<u32>::new()]
    );

    let mut prepared_many_results =
        vec![vec![0xAA], vec![0xBB], vec![0xCC], vec![0xDD], vec![0xEE]];
    batch
        .ifds_prepared_many_into(
            &prepared,
            &[empty_b, empty_c, empty_d],
            4,
            &mut prepared_many_results,
        )
        .expect("empty prepared many IFDS solve-into must succeed");
    assert_eq!(
        prepared_many_results,
        vec![Vec::<u32>::new(), Vec::<u32>::new(), Vec::<u32>::new()]
    );

    let many = batch
        .ifds_many(
            1,
            2,
            1,
            &[(0, 0, 1)],
            &[],
            &[],
            &[],
            &[empty_c, empty_a, empty_b, empty_d],
            4,
        )
        .expect("empty batch many IFDS solve must succeed");
    assert_eq!(
        many,
        vec![
            Vec::<u32>::new(),
            Vec::<u32>::new(),
            Vec::<u32>::new(),
            Vec::<u32>::new()
        ]
    );

    let many_prepared = batch
        .ifds_prepared_many(&prepared, &[empty_b, empty_c, empty_d], 4)
        .expect("empty prepared many IFDS solve must succeed");
    assert_eq!(
        many_prepared,
        vec![Vec::<u32>::new(), Vec::<u32>::new(), Vec::<u32>::new()]
    );

    let empty_query_batch: &[&[(u32, u32, u32)]] = &[];
    let mut many_empty_results = vec![vec![0xAA], vec![0xBB]];
    batch
        .ifds_many_into(
            1,
            2,
            1,
            &[(0, 0, 1)],
            &[],
            &[],
            &[],
            empty_query_batch,
            4,
            &mut many_empty_results,
        )
        .expect("empty-query batch IFDS solve-into must succeed");
    assert_eq!(many_empty_results, Vec::<Vec<u32>>::new());

    let empty_many = batch
        .ifds_many(1, 2, 1, &[(0, 0, 1)], &[], &[], &[], empty_query_batch, 4)
        .expect("empty-query batch IFDS solve must succeed");
    assert_eq!(empty_many, Vec::<Vec<u32>>::new());
}