use crate::{
zerocheck::{ZerocheckCpuBackendHelper, ZerocheckRoundInput, ZerocheckRoundParameters},
Error,
};
use binius_field::{ExtensionField, Field, PackedExtension, PackedField};
use rayon::iter::FromParallelIterator;
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
pub trait HalSlice<P: Debug + Send + Sync>:
Deref<Target = [P]>
+ DerefMut<Target = [P]>
+ Debug
+ FromIterator<P>
+ FromParallelIterator<P>
+ Send
+ Sync
+ 'static
{
}
impl<P: Send + Sync + Debug + 'static> HalSlice<P> for Vec<P> {}
pub trait ComputationBackend: Clone + Send + Sync + Debug {
type Vec<P: Send + Sync + Debug + 'static>: HalSlice<P>;
fn to_hal_slice<P: Debug + Send + Sync>(v: Vec<P>) -> Self::Vec<P>;
fn tensor_product_full_query<P: PackedField>(
&self,
query: &[P::Scalar],
) -> Result<Self::Vec<P>, Error>;
fn zerocheck_compute_round_coeffs<F, PW, FDomain>(
&self,
params: &ZerocheckRoundParameters,
input: &ZerocheckRoundInput<F, PW, FDomain>,
cpu_handler: &mut dyn ZerocheckCpuBackendHelper<F, PW, FDomain>,
) -> Result<Vec<PW::Scalar>, Error>
where
F: Field,
PW: PackedField + PackedExtension<FDomain>,
PW::Scalar: From<F> + Into<F> + ExtensionField<FDomain>,
FDomain: Field;
}
impl<'a, T: 'a + ComputationBackend> ComputationBackend for &'a T
where
&'a T: Debug + Sync + Clone + Send,
{
type Vec<P: Send + Sync + Debug + 'static> = T::Vec<P>;
fn to_hal_slice<P: Debug + Send + Sync>(v: Vec<P>) -> Self::Vec<P> {
T::to_hal_slice(v)
}
fn tensor_product_full_query<P: PackedField>(
&self,
query: &[P::Scalar],
) -> Result<Self::Vec<P>, Error> {
T::tensor_product_full_query(self, query)
}
fn zerocheck_compute_round_coeffs<F, PW, FDomain>(
&self,
params: &ZerocheckRoundParameters,
input: &ZerocheckRoundInput<F, PW, FDomain>,
cpu_handler: &mut dyn ZerocheckCpuBackendHelper<F, PW, FDomain>,
) -> Result<Vec<PW::Scalar>, Error>
where
F: Field,
PW: PackedField + PackedExtension<FDomain>,
PW::Scalar: From<F> + Into<F> + ExtensionField<FDomain>,
FDomain: Field,
{
T::zerocheck_compute_round_coeffs(self, params, input, cpu_handler)
}
}