diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index af838ab6..fd5aae7f 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -4,7 +4,7 @@ use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTar use crate::field::extension_field::FieldExtension; use crate::field::extension_field::{Extendable, OEF}; use crate::field::field_types::{Field, RichField}; -use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; +use crate::gates::arithmetic::ArithmeticExtensionGate; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness}; @@ -21,12 +21,15 @@ impl, const D: usize> CircuitBuilder { .get(&(const_0, const_1)) .copied() .unwrap_or_else(|| { - let gate = self.add_gate(ArithmeticExtensionGate, vec![const_0, const_1]); + let gate = self.add_gate( + ArithmeticExtensionGate::new_from_config(&self.config), + vec![const_0, const_1], + ); (gate, 0) }); // Update `free_arithmetic` with new values. - if i < NUM_ARITHMETIC_OPS - 1 { + if i < ArithmeticExtensionGate::::num_ops(&self.config) - 1 { self.free_arithmetic .insert((const_0, const_1), (gate, i + 1)); } else { diff --git a/src/gates/arithmetic.rs b/src/gates/arithmetic.rs index af939d0d..7e4e0c96 100644 --- a/src/gates/arithmetic.rs +++ b/src/gates/arithmetic.rs @@ -9,16 +9,29 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; -/// Number of arithmetic operations performed by an arithmetic gate. -pub const NUM_ARITHMETIC_OPS: usize = 4; - /// A gate which can a linear combination `c0*x*y+c1*z` twice with the same `x`. #[derive(Debug)] -pub struct ArithmeticExtensionGate; +pub struct ArithmeticExtensionGate { + /// Number of arithmetic operations performed by an arithmetic gate. + pub num_ops: usize, +} impl ArithmeticExtensionGate { + pub fn new_from_config(config: &CircuitConfig) -> Self { + Self { + num_ops: Self::num_ops(config), + } + } + + /// Determine the maximum number of operations that can fit in one gate for the given config. + pub(crate) fn num_ops(config: &CircuitConfig) -> usize { + let wires_per_op = 4 * D; + config.num_routed_wires / wires_per_op + } + pub fn wires_ith_multiplicand_0(i: usize) -> Range { 4 * D * i..4 * D * i + D } @@ -43,7 +56,7 @@ impl, const D: usize> Gate for ArithmeticExte let const_1 = vars.local_constants[1]; let mut constraints = Vec::new(); - for i in 0..NUM_ARITHMETIC_OPS { + for i in 0..self.num_ops { let multiplicand_0 = vars.get_local_ext_algebra(Self::wires_ith_multiplicand_0(i)); let multiplicand_1 = vars.get_local_ext_algebra(Self::wires_ith_multiplicand_1(i)); let addend = vars.get_local_ext_algebra(Self::wires_ith_addend(i)); @@ -62,7 +75,7 @@ impl, const D: usize> Gate for ArithmeticExte let const_1 = vars.local_constants[1]; let mut constraints = Vec::new(); - for i in 0..NUM_ARITHMETIC_OPS { + for i in 0..self.num_ops { let multiplicand_0 = vars.get_local_ext(Self::wires_ith_multiplicand_0(i)); let multiplicand_1 = vars.get_local_ext(Self::wires_ith_multiplicand_1(i)); let addend = vars.get_local_ext(Self::wires_ith_addend(i)); @@ -85,7 +98,7 @@ impl, const D: usize> Gate for ArithmeticExte let const_1 = vars.local_constants[1]; let mut constraints = Vec::new(); - for i in 0..NUM_ARITHMETIC_OPS { + for i in 0..self.num_ops { let multiplicand_0 = vars.get_local_ext_algebra(Self::wires_ith_multiplicand_0(i)); let multiplicand_1 = vars.get_local_ext_algebra(Self::wires_ith_multiplicand_1(i)); let addend = vars.get_local_ext_algebra(Self::wires_ith_addend(i)); @@ -109,7 +122,7 @@ impl, const D: usize> Gate for ArithmeticExte gate_index: usize, local_constants: &[F], ) -> Vec>> { - (0..NUM_ARITHMETIC_OPS) + (0..self.num_ops) .map(|i| { let g: Box> = Box::new( ArithmeticExtensionGenerator { @@ -126,7 +139,7 @@ impl, const D: usize> Gate for ArithmeticExte } fn num_wires(&self) -> usize { - NUM_ARITHMETIC_OPS * 4 * D + self.num_ops * 4 * D } fn num_constants(&self) -> usize { @@ -138,7 +151,7 @@ impl, const D: usize> Gate for ArithmeticExte } fn num_constraints(&self) -> usize { - NUM_ARITHMETIC_OPS * D + self.num_ops * D } } @@ -196,13 +209,17 @@ mod tests { use crate::field::crandall_field::CrandallField; use crate::gates::arithmetic::ArithmeticExtensionGate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; + use crate::plonk::circuit_data::CircuitConfig; #[test] fn low_degree() { - test_low_degree::(ArithmeticExtensionGate) + let gate = ArithmeticExtensionGate::new_from_config(&CircuitConfig::large_config()); + test_low_degree::(gate); } + #[test] fn eval_fns() -> Result<()> { - test_eval_fns::(ArithmeticExtensionGate) + let gate = ArithmeticExtensionGate::new_from_config(&CircuitConfig::large_config()); + test_eval_fns::(gate) } } diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 8546b683..10acc9e2 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -239,7 +239,7 @@ mod tests { let gates = vec![ GateRef::new(NoopGate), GateRef::new(ConstantGate), - GateRef::new(ArithmeticExtensionGate), + GateRef::new(ArithmeticExtensionGate { num_ops: 4 }), GateRef::new(BaseSumGate::<4>::new(4)), GateRef::new(GMiMCGate::::new()), GateRef::new(InterpolationGate::new(4)), diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index eeef44da..ed0bdbdc 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -12,7 +12,7 @@ use crate::field::fft::fft_root_table; use crate::field::field_types::RichField; use crate::fri::commitment::PolynomialBatchCommitment; use crate::fri::FriParams; -use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; +use crate::gates::arithmetic::ArithmeticExtensionGate; use crate::gates::constant::ConstantGate; use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate}; use crate::gates::gate_tree::Tree; @@ -509,7 +509,7 @@ impl, const D: usize> CircuitBuilder { let zero = self.zero_extension(); let remaining_arithmetic_gates = self.free_arithmetic.values().copied().collect::>(); for (gate, i) in remaining_arithmetic_gates { - for j in i..NUM_ARITHMETIC_OPS { + for j in i..ArithmeticExtensionGate::::num_ops(&self.config) { let wires_multiplicand_0 = ExtensionTarget::from_range( gate, ArithmeticExtensionGate::::wires_ith_multiplicand_0(j),