mod avx2;
#[cfg(feature = "simd512")]
pub(crate) mod avx512;
pub use avx2::{
mul_add_matrix_u32_avx2_with, mul_add_u8_avx2, mul_add_u32_avx2, mul_add_u64_avx2,
mul_assign_u8_avx2, mul_assign_u32_avx2, mul_assign_u64_avx2, mul_elementwise_assign_u32_avx2,
mul_elementwise_u32_avx2, mul_into_matrix_u32_avx2_with, mul_into_u8_avx2, mul_into_u32_avx2,
mul_into_u64_avx2,
};
#[allow(unused_imports)]
pub use crate::kernel::residue::PreparedResidue;
use crate::field::finite_field::{FiniteField, Residue};
use crate::kernel::Matrix;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct U32Params {
pub p: u32,
pub norm_mu: u32,
pub barrett_mu: u32,
pub shift: u32,
}
impl U32Params {
#[allow(clippy::cast_possible_truncation)]
#[must_use]
pub const fn new(p: u32) -> Self {
let shift = p.ilog2();
let s = shift + 32;
Self {
p,
norm_mu: ((1u128 << 32) / p as u128) as u32,
barrett_mu: ((1u128 << s) / p as u128) as u32,
shift,
}
}
}
impl<const P: u64> FiniteField<P, 1, Residue> {
#[allow(clippy::cast_possible_truncation)]
pub(crate) const U32_PARAMS: U32Params = U32Params::new(P as u32);
}
struct SourceGroup<'a, M: Matrix<PreparedResidue> + ?Sized> {
terms: &'a M,
base: usize,
len: usize,
}
impl<M: Matrix<PreparedResidue> + ?Sized> Matrix<PreparedResidue> for SourceGroup<'_, M> {
fn len(&self) -> usize {
self.len
}
fn coefficient(&self, term: usize, row: usize) -> PreparedResidue {
self.terms.coefficient(self.base + term, row)
}
fn source(&self, term: usize) -> &[u8] {
self.terms.source(self.base + term)
}
}