weirflow 0.1.0

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

#[test]
fn fixed_point_resident_batch_reaching_into_reuses_result_buffer() {
    let backend = FakeResidentBackend::new();
    let graph = graph_fixture();
    let pipeline = Arc::new(FakeResidentPipeline::new());
    let mut batch = FixedPointResidentBatch::new();
    let mut result = Vec::with_capacity(1);
    let result_ptr = result.as_ptr();
    let result_capacity = result.capacity();

    batch
        .reaching_into(
            &backend,
            pipeline.clone(),
            &graph,
            &[0b01],
            1,
            &DispatchConfig::default(),
            &mut result,
        )
        .expect("first resident batch solve must fill caller-owned result");
    assert_eq!(result, vec![0b01]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);

    result.clear();
    batch
        .reaching_into(
            &backend,
            pipeline,
            &graph,
            &[0b01],
            1,
            &DispatchConfig::default(),
            &mut result,
        )
        .expect("second resident batch solve must reuse caller-owned result");

    assert_eq!(result, vec![0b01]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);
    assert_eq!(batch.stats().frontier_allocations, 1);
    assert_eq!(batch.stats().frontier_reuses, 1);
    assert_eq!(batch.graph_cache_stats().hits, 1);
    assert_eq!(batch.stats().resident_graph_cold_uploads, 1);
    assert_eq!(batch.stats().resident_graph_warm_reuses, 1);
    assert_eq!(
        batch.stats().resident_graph_avoided_upload_bytes,
        batch.stats().resident_graph_upload_bytes,
        "second solve over the same resident graph must feed warm-residency avoided-upload accounting"
    );
    assert_eq!(
        batch.stats().resident_graph_reuse_telemetry(),
        vyre::ResidentGraphReuseTelemetry::from_counters(
            1,
            1,
            batch.stats().resident_graph_upload_bytes,
            batch.stats().resident_graph_avoided_upload_bytes
        ),
        "resident batch graph reuse telemetry must use the backend-neutral Vyre vocabulary"
    );
    assert_eq!(batch.execution_plan_cache_stats().misses, 1);
    assert_eq!(batch.execution_plan_cache_stats().hits, 1);
}

#[test]
fn fixed_point_resident_batch_live_points_to_and_slice_into_reuse_result_buffer() {
    let backend = FakeResidentBackend::new();
    let live_graph = graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::Live);
    let points_to_graph =
        graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::PointsToSubset);
    let slice_graph =
        graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::Slice);
    let pipeline = Arc::new(FakeResidentPipeline::new());
    let mut batch = FixedPointResidentBatch::new();
    let mut result = Vec::with_capacity(1);
    let result_ptr = result.as_ptr();
    let result_capacity = result.capacity();

    batch
        .live_into(
            &backend,
            pipeline.clone(),
            &live_graph,
            &[0b01],
            1,
            &DispatchConfig::default(),
            &mut result,
        )
        .expect("live resident batch solve must fill caller-owned result");
    assert_eq!(result, vec![0b01]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);

    result.clear();
    batch
        .points_to_subset_into(
            &backend,
            pipeline.clone(),
            &points_to_graph,
            &[0b01],
            1,
            &DispatchConfig::default(),
            &mut result,
        )
        .expect("points-to resident batch solve must reuse caller-owned result");

    assert_eq!(result, vec![0b01]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);

    result.clear();
    batch
        .slice_into(
            &backend,
            pipeline,
            &slice_graph,
            &[0b01],
            1,
            &DispatchConfig::default(),
            &mut result,
        )
        .expect("slice resident batch solve must reuse caller-owned result");

    assert_eq!(result, vec![0b01]);
    assert_eq!(result.as_ptr(), result_ptr);
    assert_eq!(result.capacity(), result_capacity);
    assert_eq!(batch.stats().frontier_allocations, 1);
    assert_eq!(batch.stats().frontier_reuses, 2);
    assert_eq!(
            batch.graph_cache_stats().hits,
            0,
            "Fix: resident graph cache must not reuse one analysis family's graph handles for another family."
        );
    assert_eq!(batch.execution_plan_cache_stats().misses, 3);
    assert_eq!(batch.execution_plan_cache_stats().hits, 0);
    assert_eq!(
            backend.uploads.lock().unwrap().len(),
            18,
            "live plus points-to plus slice resident batch solves must upload four graph buffers per analysis family plus frontier_in and frontier_out seed buffers per solve"
        );
}