weirflow 0.1.0

GPU-first dataflow analysis primitives for Vyre and Santh compiler pipelines.
Documentation
//! Parity test: GPU range propagate matches reference oracle.

#![cfg(test)]

use vyre::DispatchConfig;
use vyre_driver_cuda::CudaBackend;
use weir::oracle::summary::range_propagate as range_propagate_cpu;
use weir::range::range_propagate_borrowed_via;

fn run_dispatch(
    backend: &CudaBackend,
) -> impl Fn(&vyre::ir::Program, &[&[u8]], Option<[u32; 3]>) -> Result<Vec<Vec<u8>>, String> + '_ {
    move |program, inputs, grid_override| {
        let mut config = DispatchConfig::default();
        config.grid_override = grid_override;
        backend
            .dispatch_borrowed(program, inputs, &config)
            .map_err(|err| err.to_string())
    }
}

fn live_dispatcher() -> CudaBackend {
    CudaBackend::acquire()
        .expect("CudaBackend::acquire failed on a host that must have an NVIDIA GPU.")
}

#[test]
fn cuda_range_propagate_basic_shift() {
    let backend = live_dispatcher();
    let dispatch = run_dispatch(&backend);
    // Vars: [(0..10), (5..15), (100..200)]; transfer (1, 2) per var.
    let defs = vec![0u32, 10, 5, 15, 100, 200];
    let edges = vec![1u32, 2, 3, 4, 5, 6];
    let cpu = range_propagate_cpu(&defs, &edges, 3);
    let gpu = range_propagate_borrowed_via(&dispatch, &defs, &edges, 3).expect("dispatch");
    assert_eq!(gpu, cpu);
    assert_eq!(gpu, vec![1u32, 12, 8, 19, 105, 206]);
}

#[test]
fn cuda_range_propagate_zero_transfer() {
    let backend = live_dispatcher();
    let dispatch = run_dispatch(&backend);
    let defs = vec![10u32, 20];
    let edges = vec![0u32, 0];
    let cpu = range_propagate_cpu(&defs, &edges, 1);
    let gpu = range_propagate_borrowed_via(&dispatch, &defs, &edges, 1).expect("dispatch");
    assert_eq!(gpu, cpu);
    assert_eq!(gpu, vec![10u32, 20]);
}

#[test]
fn cuda_range_propagate_wrapping_add_overflow() {
    let backend = live_dispatcher();
    let dispatch = run_dispatch(&backend);
    let defs = vec![u32::MAX, 0];
    let edges = vec![1u32, u32::MAX];
    let cpu = range_propagate_cpu(&defs, &edges, 1);
    let gpu = range_propagate_borrowed_via(&dispatch, &defs, &edges, 1).expect("dispatch");
    assert_eq!(gpu, cpu);
    assert_eq!(gpu, vec![0u32, u32::MAX]);
}

#[test]
fn cuda_range_propagate_many_vars() {
    let backend = live_dispatcher();
    let dispatch = run_dispatch(&backend);
    let n: u32 = 64;
    let defs: Vec<u32> = (0..(n * 2)).collect();
    let edges: Vec<u32> = (0..(n * 2)).map(|i| i * 7 % 13).collect();
    let cpu = range_propagate_cpu(&defs, &edges, n);
    let gpu = range_propagate_borrowed_via(&dispatch, &defs, &edges, n).expect("dispatch");
    assert_eq!(gpu, cpu);
}