vyre-driver-cuda 0.7.0

CUDA/PTX backend for vyre through the CUDA driver API.
Documentation
use super::*;

#[test]
fn structural_equivalence_plan_emits_unique_exact_eclass_merges() {
    let snapshot = GpuEGraphSnapshot::build([
        (10u32, "lit", &[][..]),
        (20u32, "lit", &[][..]),
        (30u32, "add", &[10u32, 20u32][..]),
        (40u32, "add", &[10u32, 20u32][..]),
        (50u32, "add", &[20u32, 10u32][..]),
        (30u32, "add", &[10u32, 20u32][..]),
    ]);
    let image = snapshot
        .try_pack_device_image()
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - valid egraph image must pack");

    let plan = plan_cuda_egraph_structural_equivalences(
        &image,
        view_for_image(&image),
        CudaEGraphKernelLaunchConfig {
            threads_per_block: 8,
            max_blocks_per_launch: 1,
        },
    )
    .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - structural equivalence plan must build");

    assert_eq!(
        plan.equivalences,
        vec![
            Equivalence {
                left: 10,
                right: 20,
            },
            Equivalence {
                left: 30,
                right: 40,
            },
        ]
    );
    assert_eq!(plan.exact_pair_count, 4);
    assert_eq!(plan.redundant_pair_count, 1);
    assert_eq!(plan.rejected_candidate_pair_count, 0);
    assert_eq!(plan.equivalence_output_words, 4);
}

#[test]
fn structural_equivalence_collection_filters_signature_collision_bucket() {
    let snapshot = GpuEGraphSnapshot::build([(0u32, "lit", &[][..]), (1u32, "add", &[0u32][..])]);
    let image = snapshot
        .try_pack_device_image()
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - valid egraph image must pack");
    let signature_plan = CudaEGraphSignatureBucketPlan {
        view: view_for_image(&image),
        buckets: vec![CudaEGraphSignatureBucket {
            signature: image.row_signatures()[0],
            first_bucket_row: 0,
            row_count: 2,
            candidate_pair_count: 1,
        }],
        bucket_rows: vec![0, 1],
        pair_waves: vec![CudaEGraphSignaturePairWave {
            bucket_index: 0,
            first_pair: 0,
            pair_count: 1,
            blocks: 1,
            threads_per_block: 1,
        }],
        candidate_pair_count: 1,
        total_blocks: 1,
    };

    let plan = collect_cuda_egraph_structural_equivalences(&image, signature_plan)
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - collision-safe structural collection must complete");

    assert!(plan.equivalences.is_empty());
    assert_eq!(plan.exact_pair_count, 0);
    assert_eq!(plan.redundant_pair_count, 0);
    assert_eq!(plan.rejected_candidate_pair_count, 1);
    assert_eq!(plan.equivalence_output_words, 0);
}

#[test]
fn signature_bucket_device_image_packs_fixed_width_records() {
    let snapshot = GpuEGraphSnapshot::build([
        (0u32, "lit", &[][..]),
        (1u32, "lit", &[][..]),
        (2u32, "lit", &[][..]),
    ]);
    let image = snapshot
        .try_pack_device_image()
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - valid egraph image must pack");
    let signature_plan = plan_cuda_egraph_signature_buckets(
        &image,
        view_for_image(&image),
        CudaEGraphKernelLaunchConfig {
            threads_per_block: 2,
            max_blocks_per_launch: 1,
        },
    )
    .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - signature bucket plan must build");

    let device_image = pack_cuda_egraph_signature_bucket_device_image(&signature_plan)
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - signature bucket device image must pack");

    assert_eq!(device_image.bucket_count, 1);
    assert_eq!(device_image.bucket_record_words, 5);
    assert_eq!(device_image.bucket_rows, vec![0, 1, 2]);
    assert_eq!(
        device_image.bucket_words,
        vec![image.row_signatures()[0], 0, 3, 3, 0,]
    );
    assert_eq!(device_image.candidate_pair_count, 3);
}

#[test]
fn structural_equivalence_launch_artifact_sizes_worst_case_output() {
    let snapshot = GpuEGraphSnapshot::build([
        (0u32, "lit", &[][..]),
        (1u32, "lit", &[][..]),
        (2u32, "lit", &[][..]),
        (3u32, "lit", &[][..]),
    ]);
    let image = snapshot
        .try_pack_device_image()
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - valid egraph image must pack");
    let signature_plan = plan_cuda_egraph_signature_buckets(
        &image,
        view_for_image(&image),
        CudaEGraphKernelLaunchConfig {
            threads_per_block: 4,
            max_blocks_per_launch: 1,
        },
    )
    .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - signature bucket plan must build");

    let artifact = plan_cuda_egraph_structural_equivalence_launch_artifact(&signature_plan)
        .expect("Fix: replace expect with fallible API or document caller precondition; panic only on programmer error - structural equivalence launch artifact must build");

    assert_eq!(artifact.bucket_image.bucket_count, 1);
    assert_eq!(artifact.output.max_equivalences, 6);
    assert_eq!(artifact.output.output_pair_words, 12);
    assert_eq!(artifact.output.output_pair_bytes, 48);
    assert_eq!(artifact.output.output_counter_words, 2);
    assert_eq!(artifact.output.output_counter_bytes, 8);
    assert_eq!(artifact.pair_waves.len(), 2);
}