#![allow(unused_imports)]
#![allow(dead_code)]
pub(crate) use vyre_primitives::wire::pack_u32_slice as u32_bytes;
pub(crate) fn fixed_mul(a: u32, b: u32) -> u32 {
((i64::from(a as i32) * i64::from(b as i32)) >> 16) as i32 as u32
}
pub(crate) fn fixed_sdiv_by_positive(numerator: u32, denominator: u32) -> u32 {
((numerator as i32) / (denominator as i32)) as u32
}
use vyre_foundation::ir::{BufferAccess, Program};
use vyre_reference::value::Value;
use vyre_self_substrate::optimizer::dispatcher::{DispatchError, OptimizerDispatcher};
pub(crate) struct ReferenceEvalDispatcher;
impl OptimizerDispatcher for ReferenceEvalDispatcher {
fn dispatch(
&self,
program: &Program,
inputs: &[Vec<u8>],
_grid_override: Option<[u32; 3]>,
) -> Result<Vec<Vec<u8>>, DispatchError> {
let mut values: Vec<Value> = Vec::new();
let mut next_input = inputs.iter();
for buffer in program.buffers() {
if buffer.access() == BufferAccess::Workgroup {
continue;
}
if buffer.is_backend_allocated_output() {
continue;
}
let bytes = next_input.next().ok_or_else(|| {
DispatchError::BadInputs(format!(
"ReferenceEvalDispatcher: program declares more input-consuming buffers than the \
{} dispatch inputs provided (at buffer `{}`). The backend requires one input per \
{{ReadOnly, plain-ReadWrite, Uniform}} buffer in buffer order; pass a zero-filled \
slot for each plain-ReadWrite output.",
inputs.len(),
buffer.name()
))
})?;
values.push(Value::from(bytes.clone()));
}
if next_input.next().is_some() {
return Err(DispatchError::BadInputs(format!(
"ReferenceEvalDispatcher: {} dispatch inputs provided but the program has fewer \
input-consuming buffers. The backend requires exactly one input per {{ReadOnly, \
plain-ReadWrite, Uniform}} buffer; do not pass slots for backend-allocated outputs.",
inputs.len()
)));
}
let outputs = vyre_reference::reference_eval(program, &values).map_err(|err| {
DispatchError::BackendError(format!(
"ReferenceEvalDispatcher: reference_eval failed. {err}"
))
})?;
Ok(outputs.iter().map(Value::to_bytes).collect())
}
}