diff --git a/crates/prover/src/core/air/accumulation.rs b/crates/prover/src/core/air/accumulation.rs index f53519929..51020494a 100644 --- a/crates/prover/src/core/air/accumulation.rs +++ b/crates/prover/src/core/air/accumulation.rs @@ -7,11 +7,10 @@ use itertools::Itertools; use tracing::{span, Level}; -use crate::core::backend::{Backend, Col, Column, CpuBackend}; +use crate::core::backend::{Backend, Col, Column, ColumnOps, CpuBackend}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::secure_column::SecureColumnByCoords; -use crate::core::fields::FieldOps; use crate::core::poly::circle::{CanonicCoset, CircleEvaluation, CirclePoly, SecureCirclePoly}; use crate::core::poly::BitReversedOrder; @@ -149,7 +148,7 @@ impl DomainEvaluationAccumulator { } } -pub trait AccumulationOps: FieldOps + Sized { +pub trait AccumulationOps: ColumnOps + Sized { /// Accumulates other into column: /// column = column + other. fn accumulate(column: &mut SecureColumnByCoords, other: &SecureColumnByCoords); diff --git a/crates/prover/src/core/backend/cpu/mod.rs b/crates/prover/src/core/backend/cpu/mod.rs index 457ca9d2a..4ae7c3e5c 100644 --- a/crates/prover/src/core/backend/cpu/mod.rs +++ b/crates/prover/src/core/backend/cpu/mod.rs @@ -12,8 +12,7 @@ use std::fmt::Debug; use serde::{Deserialize, Serialize}; -use super::{Backend, BackendForChannel, Column, ColumnOps, FieldOps}; -use crate::core::fields::Field; +use super::{Backend, BackendForChannel, Column, ColumnOps}; use crate::core::lookups::mle::Mle; use crate::core::poly::circle::{CircleEvaluation, CirclePoly}; use crate::core::utils::bit_reverse_index; @@ -54,14 +53,6 @@ impl ColumnOps for CpuBackend { } } -impl FieldOps for CpuBackend { - /// Batch inversion using the Montgomery's trick. - // TODO(Ohad): Benchmark this function. - fn batch_inverse(column: &Self::Column, dst: &mut Self::Column) { - F::batch_inverse(column, &mut dst[..]); - } -} - impl Column for Vec { fn zeros(len: usize) -> Self { vec![T::default(); len] @@ -97,7 +88,7 @@ mod tests { use rand::rngs::SmallRng; use crate::core::backend::cpu::bit_reverse; - use crate::core::backend::{Column, CpuBackend, FieldOps}; + use crate::core::backend::Column; use crate::core::fields::qm31::QM31; use crate::core::fields::FieldExpOps; @@ -120,9 +111,9 @@ mod tests { let mut rng = SmallRng::seed_from_u64(0); let column = rng.gen::<[QM31; 16]>().to_vec(); let expected = column.iter().map(|e| e.inverse()).collect_vec(); - let mut dst = Column::zeros(column.len()); + let mut dst = Vec::zeros(column.len()); - CpuBackend::batch_inverse(&column, &mut dst); + FieldExpOps::batch_inverse(&column, &mut dst); assert_eq!(expected, dst); } diff --git a/crates/prover/src/core/backend/mod.rs b/crates/prover/src/core/backend/mod.rs index 288ecc123..a8f5f717f 100644 --- a/crates/prover/src/core/backend/mod.rs +++ b/crates/prover/src/core/backend/mod.rs @@ -6,7 +6,6 @@ use super::air::accumulation::AccumulationOps; use super::channel::MerkleChannel; use super::fields::m31::BaseField; use super::fields::qm31::SecureField; -use super::fields::FieldOps; use super::fri::FriOps; use super::lookups::gkr_prover::GkrOps; use super::pcs::quotients::QuotientOps; @@ -21,8 +20,8 @@ pub trait Backend: Copy + Clone + Debug - + FieldOps - + FieldOps + + ColumnOps + + ColumnOps + PolyOps + QuotientOps + FriOps diff --git a/crates/prover/src/core/backend/simd/column.rs b/crates/prover/src/core/backend/simd/column.rs index 819f79cbb..87b89d4ce 100644 --- a/crates/prover/src/core/backend/simd/column.rs +++ b/crates/prover/src/core/backend/simd/column.rs @@ -18,19 +18,6 @@ use crate::core::fields::cm31::CM31; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::secure_column::{SecureColumnByCoords, SECURE_EXTENSION_DEGREE}; -use crate::core::fields::{FieldExpOps, FieldOps}; - -impl FieldOps for SimdBackend { - fn batch_inverse(column: &BaseColumn, dst: &mut BaseColumn) { - PackedBaseField::batch_inverse(&column.data, &mut dst.data); - } -} - -impl FieldOps for SimdBackend { - fn batch_inverse(column: &SecureColumn, dst: &mut SecureColumn) { - PackedSecureField::batch_inverse(&column.data, &mut dst.data); - } -} /// An efficient structure for storing and operating on a arbitrary number of [`BaseField`] values. #[derive(Clone, Debug)] diff --git a/crates/prover/src/core/fields/mod.rs b/crates/prover/src/core/fields/mod.rs index abbcbf2b1..b19ea9bc9 100644 --- a/crates/prover/src/core/fields/mod.rs +++ b/crates/prover/src/core/fields/mod.rs @@ -4,18 +4,11 @@ use std::ops::{Mul, MulAssign, Neg}; use num_traits::{NumAssign, NumAssignOps, NumOps, One}; -use super::backend::ColumnOps; - pub mod cm31; pub mod m31; pub mod qm31; pub mod secure_column; -pub trait FieldOps: ColumnOps { - // TODO(Ohad): change to use a mutable slice. - fn batch_inverse(column: &Self::Column, dst: &mut Self::Column); -} - pub trait FieldExpOps: Mul + MulAssign + Sized + One + Clone { fn square(&self) -> Self { self.clone() * self.clone() diff --git a/crates/prover/src/core/fields/secure_column.rs b/crates/prover/src/core/fields/secure_column.rs index 872954f86..9d9d826e3 100644 --- a/crates/prover/src/core/fields/secure_column.rs +++ b/crates/prover/src/core/fields/secure_column.rs @@ -3,8 +3,8 @@ use std::iter::zip; use super::m31::BaseField; use super::qm31::SecureField; -use super::{ExtensionOf, FieldOps}; -use crate::core::backend::{Col, Column, CpuBackend}; +use super::ExtensionOf; +use crate::core::backend::{Col, Column, ColumnOps, CpuBackend}; pub const SECURE_EXTENSION_DEGREE: usize = >::EXTENSION_DEGREE; @@ -12,7 +12,7 @@ pub const SECURE_EXTENSION_DEGREE: usize = /// A column major array of `SECURE_EXTENSION_DEGREE` base field columns, that represents a column /// of secure field element coordinates. #[derive(Clone, Debug)] -pub struct SecureColumnByCoords> { +pub struct SecureColumnByCoords> { pub columns: [Col; SECURE_EXTENSION_DEGREE], } impl SecureColumnByCoords { @@ -21,7 +21,7 @@ impl SecureColumnByCoords { (0..self.len()).map(|i| self.at(i)).collect() } } -impl> SecureColumnByCoords { +impl> SecureColumnByCoords { pub fn at(&self, index: usize) -> SecureField { SecureField::from_m31_array(std::array::from_fn(|i| self.columns[i].at(index))) } diff --git a/crates/prover/src/core/fri.rs b/crates/prover/src/core/fri.rs index 6bcb3cb2a..50501eb1f 100644 --- a/crates/prover/src/core/fri.rs +++ b/crates/prover/src/core/fri.rs @@ -10,12 +10,11 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use tracing::instrument; -use super::backend::{Col, CpuBackend}; +use super::backend::{Col, ColumnOps, CpuBackend}; use super::channel::{Channel, MerkleChannel}; use super::fields::m31::BaseField; use super::fields::qm31::{SecureField, QM31}; use super::fields::secure_column::{SecureColumnByCoords, SECURE_EXTENSION_DEGREE}; -use super::fields::FieldOps; use super::poly::circle::{CircleDomain, PolyOps, SecureEvaluation}; use super::poly::line::{LineEvaluation, LinePoly}; use super::poly::twiddles::TwiddleTree; @@ -75,7 +74,7 @@ impl FriConfig { } } -pub trait FriOps: FieldOps + PolyOps + Sized + FieldOps { +pub trait FriOps: ColumnOps + PolyOps + Sized + ColumnOps { /// Folds a degree `d` polynomial into a degree `d/2` polynomial. /// /// Let `eval` be a polynomial evaluated on a [LineDomain] `E`, `alpha` be a random field diff --git a/crates/prover/src/core/poly/circle/evaluation.rs b/crates/prover/src/core/poly/circle/evaluation.rs index 6094df399..c46a298a6 100644 --- a/crates/prover/src/core/poly/circle/evaluation.rs +++ b/crates/prover/src/core/poly/circle/evaluation.rs @@ -6,10 +6,10 @@ use educe::Educe; use super::{CanonicCoset, CircleDomain, CirclePoly, PolyOps}; use crate::core::backend::cpu::CpuCircleEvaluation; use crate::core::backend::simd::SimdBackend; -use crate::core::backend::{Col, Column, CpuBackend}; +use crate::core::backend::{Col, Column, ColumnOps, CpuBackend}; use crate::core::circle::{CirclePointIndex, Coset}; use crate::core::fields::m31::BaseField; -use crate::core::fields::{ExtensionOf, FieldOps}; +use crate::core::fields::ExtensionOf; use crate::core::poly::twiddles::TwiddleTree; use crate::core::poly::{BitReversedOrder, NaturalOrder}; use crate::core::utils::bit_reverse_index; @@ -18,13 +18,13 @@ use crate::core::utils::bit_reverse_index; /// The values are ordered according to the [CircleDomain] ordering. #[derive(Educe)] #[educe(Clone, Debug)] -pub struct CircleEvaluation, F: ExtensionOf, EvalOrder = NaturalOrder> { +pub struct CircleEvaluation, F: ExtensionOf, EvalOrder = NaturalOrder> { pub domain: CircleDomain, pub values: Col, _eval_order: PhantomData, } -impl, F: ExtensionOf, EvalOrder> CircleEvaluation { +impl, F: ExtensionOf, EvalOrder> CircleEvaluation { pub fn new(domain: CircleDomain, values: Col) -> Self { assert_eq!(domain.size(), values.len()); Self { @@ -38,7 +38,7 @@ impl, F: ExtensionOf, EvalOrder> CircleEvaluation, B: FieldOps> CircleEvaluation { +impl, B: ColumnOps> CircleEvaluation { // TODO(alont): Remove. Is this even used. pub fn get_at(&self, point_index: CirclePointIndex) -> F { self.values @@ -95,7 +95,7 @@ impl CircleEvaluation { } } -impl, F: ExtensionOf> CircleEvaluation { +impl, F: ExtensionOf> CircleEvaluation { pub fn bit_reverse(mut self) -> CircleEvaluation { B::bit_reverse_column(&mut self.values); CircleEvaluation::new(self.domain, self.values) @@ -111,14 +111,14 @@ impl, F: ExtensionOf> CircleEvaluation, EvalOrder> CircleEvaluation where - SimdBackend: FieldOps, + SimdBackend: ColumnOps, { pub fn to_cpu(&self) -> CircleEvaluation { CircleEvaluation::new(self.domain, self.values.to_cpu()) } } -impl, F: ExtensionOf, EvalOrder> Deref +impl, F: ExtensionOf, EvalOrder> Deref for CircleEvaluation { type Target = Col; diff --git a/crates/prover/src/core/poly/circle/ops.rs b/crates/prover/src/core/poly/circle/ops.rs index 9aa6b2686..17b8d40f5 100644 --- a/crates/prover/src/core/poly/circle/ops.rs +++ b/crates/prover/src/core/poly/circle/ops.rs @@ -1,17 +1,16 @@ use itertools::Itertools; use super::{CanonicCoset, CircleDomain, CircleEvaluation, CirclePoly}; -use crate::core::backend::Col; +use crate::core::backend::{Col, ColumnOps}; use crate::core::circle::{CirclePoint, Coset}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; -use crate::core::fields::FieldOps; use crate::core::poly::twiddles::TwiddleTree; use crate::core::poly::BitReversedOrder; use crate::core::ColumnVec; /// Operations on BaseField polynomials. -pub trait PolyOps: FieldOps + Sized { +pub trait PolyOps: ColumnOps + Sized { // TODO(alont): Use a column instead of this type. /// The type for precomputed twiddles. type Twiddles; diff --git a/crates/prover/src/core/poly/circle/poly.rs b/crates/prover/src/core/poly/circle/poly.rs index 6744a0c80..6cd9c73e9 100644 --- a/crates/prover/src/core/poly/circle/poly.rs +++ b/crates/prover/src/core/poly/circle/poly.rs @@ -1,15 +1,14 @@ use super::{CircleDomain, CircleEvaluation, PolyOps}; -use crate::core::backend::{Col, Column}; +use crate::core::backend::{Col, Column, ColumnOps}; use crate::core::circle::CirclePoint; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; -use crate::core::fields::FieldOps; use crate::core::poly::twiddles::TwiddleTree; use crate::core::poly::BitReversedOrder; /// A polynomial defined on a [CircleDomain]. #[derive(Clone, Debug)] -pub struct CirclePoly> { +pub struct CirclePoly> { /// Coefficients of the polynomial in the FFT basis. /// Note: These are not the coefficients of the polynomial in the standard /// monomial basis. The FFT basis is a tensor product of the twiddles: diff --git a/crates/prover/src/core/poly/circle/secure_poly.rs b/crates/prover/src/core/poly/circle/secure_poly.rs index a5ae1f4cd..566c82458 100644 --- a/crates/prover/src/core/poly/circle/secure_poly.rs +++ b/crates/prover/src/core/poly/circle/secure_poly.rs @@ -2,16 +2,15 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use super::{CircleDomain, CircleEvaluation, CirclePoly, PolyOps}; -use crate::core::backend::CpuBackend; +use crate::core::backend::{ColumnOps, CpuBackend}; use crate::core::circle::CirclePoint; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::secure_column::{SecureColumnByCoords, SECURE_EXTENSION_DEGREE}; -use crate::core::fields::FieldOps; use crate::core::poly::twiddles::TwiddleTree; use crate::core::poly::BitReversedOrder; -pub struct SecureCirclePoly>(pub [CirclePoly; SECURE_EXTENSION_DEGREE]); +pub struct SecureCirclePoly>(pub [CirclePoly; SECURE_EXTENSION_DEGREE]); impl SecureCirclePoly { pub fn eval_at_point(&self, point: CirclePoint) -> SecureField { @@ -49,7 +48,7 @@ impl SecureCirclePoly { } } -impl> Deref for SecureCirclePoly { +impl> Deref for SecureCirclePoly { type Target = [CirclePoly; SECURE_EXTENSION_DEGREE]; fn deref(&self) -> &Self::Target { @@ -62,13 +61,13 @@ impl> Deref for SecureCirclePoly { /// The evaluation is stored as a column major array of [`SECURE_EXTENSION_DEGREE`] many base field /// evaluations. The evaluations are ordered according to the [CircleDomain] ordering. #[derive(Clone)] -pub struct SecureEvaluation, EvalOrder> { +pub struct SecureEvaluation, EvalOrder> { pub domain: CircleDomain, pub values: SecureColumnByCoords, _eval_order: PhantomData, } -impl, EvalOrder> SecureEvaluation { +impl, EvalOrder> SecureEvaluation { pub fn new(domain: CircleDomain, values: SecureColumnByCoords) -> Self { assert_eq!(domain.size(), values.len()); Self { @@ -94,7 +93,7 @@ impl, EvalOrder> SecureEvaluation { } } -impl, EvalOrder> Deref for SecureEvaluation { +impl, EvalOrder> Deref for SecureEvaluation { type Target = SecureColumnByCoords; fn deref(&self) -> &Self::Target { @@ -102,7 +101,7 @@ impl, EvalOrder> Deref for SecureEvaluation } } -impl, EvalOrder> DerefMut for SecureEvaluation { +impl, EvalOrder> DerefMut for SecureEvaluation { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.values } diff --git a/crates/prover/src/core/poly/line.rs b/crates/prover/src/core/poly/line.rs index d684d0c58..5ab29a9c1 100644 --- a/crates/prover/src/core/poly/line.rs +++ b/crates/prover/src/core/poly/line.rs @@ -16,7 +16,7 @@ use crate::core::fft::ibutterfly; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::secure_column::SecureColumnByCoords; -use crate::core::fields::{ExtensionOf, FieldOps}; +use crate::core::fields::ExtensionOf; /// Domain comprising of the x-coordinates of points in a [Coset]. /// @@ -186,13 +186,13 @@ impl DerefMut for LinePoly { // only used by FRI where evaluations are in bit-reversed order. // TODO(andrew): Remove pub. #[derive(Clone, Debug)] -pub struct LineEvaluation> { +pub struct LineEvaluation> { /// Evaluations of a univariate polynomial on `domain`. pub values: SecureColumnByCoords, domain: LineDomain, } -impl> LineEvaluation { +impl> LineEvaluation { /// Creates new [LineEvaluation] from a set of polynomial evaluations over a [LineDomain]. /// /// # Panics