vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
#[cfg(loom)]
use loom::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(loom))]
use std::sync::atomic::{AtomicUsize, Ordering};
use crate::pipeline::backend::{ConformDispatchConfig, ExecutionModel, VyreBackend};

#[cfg(test)]
mod tests {
    use super::*;

    struct MockBackend {
        output: Vec<u8>,
    }

    impl VyreBackend for MockBackend {
        fn name(&self) -> &str {
            "mock"
        }

        fn dispatch(
            &self,
            _wgsl: &str,
            _input: &[u8],
            _output_size: usize,
            _config: ConformDispatchConfig,
        ) -> Result<Vec<u8>, String> {
            Ok(self.output.clone())
        }

        fn dispatch_program(
            &self,
            _program: &[u8],
            _input: &[u8],
            _output_size: usize,
            _config: ConformDispatchConfig,
        ) -> Result<Vec<u8>, String> {
            Ok(self.output.clone())
        }
    }

    #[test]
    fn fault_backend_succeeds_before_threshold() {
        let inner = MockBackend {
            output: vec![0xAB, 0xCD],
        };
        let fault = FaultInjectingBackend::new(&inner, 2);

        assert!(fault
            .dispatch("", &[], 2, ConformDispatchConfig::default())
            .is_ok());
        assert!(fault
            .dispatch("", &[], 2, ConformDispatchConfig::default())
            .is_ok());
    }

    #[test]
    fn fault_backend_fails_at_threshold_without_panic() {
        let inner = MockBackend {
            output: vec![0xAB, 0xCD],
        };
        let fault = FaultInjectingBackend::new(&inner, 1);

        // First dispatch succeeds.
        assert!(fault
            .dispatch("", &[], 2, ConformDispatchConfig::default())
            .is_ok());
        // Second dispatch (index 1) fails.
        let result = fault.dispatch("", &[], 2, ConformDispatchConfig::default());
        assert!(
            result.is_err(),
            "expected structured error at fail_after threshold, got: {:?}",
            result
        );
        let msg = result.unwrap_err();
        assert!(
            msg.contains("Fault injection"),
            "error must mention fault injection, got: {msg}"
        );
    }

    #[test]
    fn with_fault_at_dispatch_detects_failure() {
        let inner = MockBackend {
            output: vec![0x00; 4],
        };
        let program = vyre::ir::Program::new(vec![], [1, 1, 1], vec![vyre::ir::Node::Return]);

        // fail_after = 0 means the very first dispatch fails.
        let result = with_fault_at_dispatch(&inner, &program, &[], 4, ConformDispatchConfig::default(), 0);
        assert!(
            result.is_err(),
            "expected failure when fail_after=0, got: {:?}",
            result
        );
    }

    #[test]
    fn with_fault_at_dispatch_allows_success() {
        let inner = MockBackend {
            output: vec![0x00; 4],
        };
        let program = vyre::ir::Program::new(vec![], [1, 1, 1], vec![vyre::ir::Node::Return]);

        // fail_after = 5 means the first dispatch succeeds.
        let result = with_fault_at_dispatch(&inner, &program, &[], 4, ConformDispatchConfig::default(), 5);
        assert!(
            result.is_ok(),
            "expected success when fail_after is high, got: {:?}",
            result
        );
    }
}