#![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_matvec(matrix: &[u32], vector: &[u32], n: usize) -> Vec<u32> {
(0..n)
.map(|row| {
let mut acc = 0u32;
for column in 0..n {
acc = acc.wrapping_add(fixed_mul(matrix[row * n + column], vector[column]));
}
acc
})
.collect()
}
pub(crate) fn xorshift32(state: &mut u32) -> u32 {
*state ^= *state << 13;
*state ^= *state >> 17;
*state ^= *state << 5;
*state
}
fn signed_fixed_with_mask(state: &mut u32, magnitude_mask: u32) -> u32 {
let magnitude = (xorshift32(state) & magnitude_mask) as i32;
if xorshift32(state) & 1 == 0 {
magnitude as u32
} else {
(-magnitude) as u32
}
}
pub(crate) fn signed_fixed_19(state: &mut u32) -> u32 {
signed_fixed_with_mask(state, 0x0007_FFFF)
}
pub(crate) fn signed_fixed_17(state: &mut u32) -> u32 {
signed_fixed_with_mask(state, 0x0001_FFFF)
}
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())
}
}