Skip to main content

vyre_reference/
flat_cpu.rs

1//! Flat byte adapter that turns every CPU reference into a uniform byte-in,
2//! byte-out contract.
3//!
4//! The parity engine compares raw bytes, not structured values. This module
5//! exists so primitive ops can be tested with the same binary-diff harness
6//! regardless of their internal Value representation.
7
8use vyre::ir::{BufferAccess, DataType, Program};
9
10use crate::reference_eval;
11use crate::value::Value;
12/// Execute a program from a concatenated single-case byte payload.
13///
14/// Fixed-width input buffers consume one element each from `input`. Read-write
15/// output buffers are initialized to one zero element and appended to `output`
16/// after interpretation.
17///
18/// # Errors
19///
20/// Returns [`vyre::error::Error`] if the program is invalid or execution fails.
21///
22/// # Examples
23///
24/// ```rust,ignore
25/// let mut out = Vec::new();
26/// vyre::reference::flat_cpu::run_flat(&program, &input_bytes, &mut out)?;
27/// ```
28pub fn run_flat(program: &Program, input: &[u8], output: &mut Vec<u8>) -> Result<(), vyre::Error> {
29    let mut offset = 0usize;
30    let mut values = Vec::new();
31    for buffer in program.buffers() {
32        match buffer.access() {
33            BufferAccess::ReadOnly | BufferAccess::Uniform => {
34                let width = buffer.element().min_bytes();
35                let mut bytes = vec![0; width];
36                let available = input.len().saturating_sub(offset).min(width);
37                bytes[..available].copy_from_slice(&input[offset..offset + available]);
38                offset = offset.saturating_add(width).min(input.len());
39                values.push(Value::from(bytes));
40            }
41            BufferAccess::ReadWrite => {
42                values.push(Value::from(vec![0; output_width(buffer.element())]));
43            }
44            BufferAccess::Workgroup => {}
45            _ => {}
46        }
47    }
48    let values = reference_eval(program, &values)?;
49    output.clear();
50    for value in values {
51        output.extend_from_slice(&value.to_bytes());
52    }
53    Ok(())
54}
55
56fn output_width(data_type: DataType) -> usize {
57    data_type.min_bytes().max(4)
58}