vyre_reference/
flat_cpu.rs1use vyre::ir::{BufferAccess, DataType, Program};
9
10use crate::reference_eval;
11use crate::value::Value;
12pub fn run_flat(program: &Program, input: &[u8], output: &mut Vec<u8>) -> Result<(), vyre::Error> {
32 let mut offset = 0usize;
33 let mut values = Vec::new();
34 for buffer in program.buffers() {
35 match buffer.access() {
36 BufferAccess::ReadOnly | BufferAccess::Uniform => {
37 let width = buffer_flat_width(buffer.name(), buffer.element(), buffer.count())?;
38 let remaining = input.len().saturating_sub(offset);
39 if remaining < width {
40 return Err(vyre::Error::interp(format!(
41 "flat CPU input for buffer `{}` is truncated: expected {width} byte(s), got {remaining}. Fix: provide the declared fixed-width element count for every ReadOnly/Uniform buffer before invoking the reference backend.",
42 buffer.name()
43 )));
44 }
45 let mut bytes = vec![0; width];
46 bytes.copy_from_slice(&input[offset..offset + width]);
47 offset += width;
48 values.push(Value::from(bytes));
49 }
50 BufferAccess::ReadWrite => {
51 values.push(Value::from(vec![
52 0;
53 buffer_flat_width(
54 buffer.name(),
55 buffer.element(),
56 buffer.count()
57 )?
58 ]));
59 }
60 BufferAccess::Workgroup => {}
61 _ => {}
62 }
63 }
64 if offset != input.len() {
65 let trailing = input.len() - offset;
66 return Err(vyre::Error::interp(format!(
67 "flat CPU input has {trailing} trailing byte(s) after consuming declared ReadOnly/Uniform buffers. Fix: provide exactly one fixed-width element per flat input buffer or split multi-case payloads before invoking the reference backend."
68 )));
69 }
70 let values = reference_eval(program, &values)?;
71 output.clear();
72 for value in values {
73 value.extend_bytes_width(0, output)?;
74 }
75 Ok(())
76}
77
78fn output_width(buffer_name: &str, data_type: DataType) -> Result<usize, vyre::Error> {
79 let min_bytes = data_type.min_bytes();
80 if min_bytes == 0 {
81 return Err(vyre::Error::interp(format!(
82 "flat CPU buffer `{buffer_name}` uses variable-width element type {data_type:?}. Fix: use a fixed-width element type or route dynamic buffers through the structured reference evaluator."
83 )));
84 }
85 Ok(min_bytes.max(4))
86}
87
88fn buffer_flat_width(
89 buffer_name: &str,
90 data_type: DataType,
91 count: u32,
92) -> Result<usize, vyre::Error> {
93 output_width(buffer_name, data_type)?
94 .checked_mul(count.max(1) as usize)
95 .ok_or_else(|| {
96 vyre::Error::interp(
97 "flat CPU buffer byte width overflows usize. Fix: split the flat conformance case or reduce the declared buffer count.",
98 )
99 })
100}