use std::mem::MaybeUninit;
use crate::{septic_digest::SepticDigest, MachineRecord, UntrustedConfig};
use slop_air::BaseAir;
use slop_algebra::Field;
use slop_matrix::dense::RowMajorMatrix;
pub use sp1_derive::MachineAir;
#[macro_export]
macro_rules! chip_name {
($chip:ident, $field:ty) => {
<$chip as MachineAir<$field>>::name(&$chip {})
};
}
pub trait MachineAir<F: Field>: BaseAir<F> + 'static + Send + Sync {
type Record: MachineRecord;
type Program: MachineProgram<F>;
fn name(&self) -> &'static str;
fn column_names(&self) -> Vec<String> {
(0..self.width()).map(|i| format!("col_{i}")).collect()
}
fn num_rows(&self, _input: &Self::Record) -> Option<usize> {
None
}
fn generate_trace(&self, input: &Self::Record, output: &mut Self::Record) -> RowMajorMatrix<F> {
let padded_nb_rows = self.num_rows(input).unwrap();
let num_columns = <Self as BaseAir<F>>::width(self);
let mut values: Vec<F> = Vec::with_capacity(padded_nb_rows * num_columns);
self.generate_trace_into(input, output, values.spare_capacity_mut());
unsafe {
values.set_len(padded_nb_rows * num_columns);
}
RowMajorMatrix::new(values, num_columns)
}
fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) {
self.generate_trace(input, output);
}
fn generate_trace_into(
&self,
input: &Self::Record,
output: &mut Self::Record,
buffer: &mut [MaybeUninit<F>],
);
fn included(&self, shard: &Self::Record) -> bool;
fn preprocessed_width(&self) -> usize {
0
}
fn preprocessed_num_rows(&self, _program: &Self::Program) -> Option<usize> {
None
}
fn preprocessed_num_rows_with_instrs_len(
&self,
_program: &Self::Program,
_instrs_len: usize,
) -> Option<usize> {
None
}
fn generate_preprocessed_trace_into(&self, _: &Self::Program, _: &mut [MaybeUninit<F>]) {}
fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option<RowMajorMatrix<F>> {
if self.preprocessed_width() == 0 {
return None;
}
let padded_nb_rows = self.preprocessed_num_rows(program).unwrap();
let num_columns = self.preprocessed_width();
let mut values: Vec<F> = Vec::with_capacity(padded_nb_rows * num_columns);
self.generate_preprocessed_trace_into(program, values.spare_capacity_mut());
unsafe {
values.set_len(padded_nb_rows * num_columns);
}
Some(RowMajorMatrix::new(values, num_columns))
}
}
pub trait MachineProgram<F>: Send + Sync {
fn pc_start(&self) -> [F; 3];
fn initial_global_cumulative_sum(&self) -> SepticDigest<F>;
fn untrusted_config(&self) -> UntrustedConfig<F>;
}