diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index a4bc9731..5e6cb07a 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -1,7 +1,4 @@ -use std::ops::Range; - use plonky2_field::extension_field::Extendable; -use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; use crate::gates::gate::Gate; @@ -9,12 +6,7 @@ use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::generator::{ - ConstantGenerator, GeneratedValues, SimpleGenerator, WitnessGenerator, -}; -use crate::iop::target::Target; -use crate::iop::wire::Wire; -use crate::iop::witness::PartitionWitness; +use crate::iop::generator::{ConstantGenerator, WitnessGenerator}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, @@ -81,23 +73,9 @@ impl, const D: usize> Gate for ConstantGate { fn generators( &self, - gate_index: usize, - local_constants: &[F], + _gate_index: usize, + _local_constants: &[F], ) -> Vec>> { - // (0..self.num_consts) - // .map(|i| { - // let g: Box> = Box::new( - // ConstantGenerator { - // gate_index, - // gate: *self, - // i, - // constant: local_constants[self.const_input(i)], - // } - // .adapter(), - // ); - // g - // }) - // .collect() vec![] } @@ -143,28 +121,6 @@ impl, const D: usize> PackedEvaluableBase for } } -// #[derive(Debug)] -// struct ConstantGenerator { -// gate_index: usize, -// gate: ConstantGate, -// i: usize, -// constant: F, -// } - -// impl SimpleGenerator for ConstantGenerator { -// fn dependencies(&self) -> Vec { -// Vec::new() -// } -// -// fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { -// let wire = Wire { -// gate: self.gate_index, -// input: self.gate.wire_output(self.i), -// }; -// out_buffer.set_wire(wire, self.constant); -// } -// } - #[cfg(test)] mod tests { use anyhow::Result; diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index d41a1721..969e3abd 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -181,6 +181,7 @@ pub trait Gate, const D: usize>: 'static + Send + S .len() } + /// Extra constants (i.e. constants that are not used in the gate's core functionality) generated by the gate. fn extra_constants(&self, _gate_index: usize) -> Vec> { vec![] } diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 687e5e53..384d2ee9 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -1,5 +1,4 @@ use std::marker::PhantomData; -use std::ops::Range; use itertools::Itertools; use plonky2_field::extension_field::Extendable; @@ -23,7 +22,6 @@ use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; -use crate::with_context; /// A gate for checking that a particular element of a list matches a given value. #[derive(Copy, Clone, Debug)] @@ -51,7 +49,12 @@ impl, const D: usize> RandomAccessGate { // Need `(2 + vec_size + bits) * num_copies` wires config.num_wires / (2 + vec_size + bits), ); - Self::new(max_copies, bits, config.num_constants) + let max_extra_constants = config.num_routed_wires - (2 + vec_size) * max_copies; + Self::new( + max_copies, + bits, + max_extra_constants.min(config.num_constants), + ) } fn vec_size(&self) -> usize { @@ -218,7 +221,7 @@ impl, const D: usize> Gate for RandomAccessGa fn generators( &self, gate_index: usize, - local_constants: &[F], + _local_constants: &[F], ) -> Vec>> { (0..self.num_copies) .map(|copy| { @@ -232,18 +235,6 @@ impl, const D: usize> Gate for RandomAccessGa ); g }) - // .chain((0..self.num_extra_constants).map(|i| { - // let g: Box> = Box::new( - // RandomAccessExtraConstantsGenerator { - // gate_index, - // gate: *self, - // i, - // constant: local_constants[i], - // } - // .adapter(), - // ); - // g - // })) .collect() } @@ -264,10 +255,6 @@ impl, const D: usize> Gate for RandomAccessGa self.num_copies * constraints_per_copy + self.num_extra_constants } - fn num_ops(&self) -> usize { - self.num_copies - } - fn extra_constants(&self, gate_index: usize) -> Vec> { (0..self.num_extra_constants) .map(|i| ConstantGenerator::new(gate_index, i, self.wire_extra_constant(i), F::ZERO)) @@ -375,30 +362,6 @@ impl, const D: usize> SimpleGenerator } } -#[derive(Debug)] -struct RandomAccessExtraConstantsGenerator, const D: usize> { - gate_index: usize, - gate: RandomAccessGate, - i: usize, - constant: F, -} - -impl, const D: usize> SimpleGenerator - for RandomAccessExtraConstantsGenerator -{ - fn dependencies(&self) -> Vec { - Vec::new() - } - - fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { - let wire = Wire { - gate: self.gate_index, - input: self.gate.wire_extra_constant(self.i), - }; - out_buffer.set_wire(wire, self.constant); - } -} - #[cfg(test)] mod tests { use std::marker::PhantomData; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index f38fc65c..aab33d1b 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -8,7 +8,6 @@ use plonky2_field::field_types::{Field, PrimeField}; use crate::gadgets::arithmetic_u32::U32Target; use crate::gadgets::biguint::BigUintTarget; use crate::gadgets::nonnative::NonNativeTarget; -use crate::gates::gate::Gate; use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; @@ -327,6 +326,7 @@ impl SimpleGenerator for NonzeroTestGenerator { } } +/// Generator used fill an extra constant. #[derive(Debug, Clone)] pub struct ConstantGenerator { pub gate_index: usize, diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 45e51aa0..79e2eb2f 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -2,7 +2,6 @@ use std::cmp::max; use std::collections::{BTreeMap, HashMap, HashSet}; use std::time::Instant; -use itertools::{EitherOrBoth, Itertools}; use log::{debug, info, Level}; use plonky2_field::cosets::get_unique_coset_shifts; use plonky2_field::extension_field::{Extendable, FieldExtension}; @@ -85,8 +84,8 @@ pub struct CircuitBuilder, const D: usize> { /// Map between gate type and the current gate of this type with available slots. current_slots: HashMap, CurrentSlot>, - /// gate_index, constant_index, target_index, ConstantGen - constants_slots: Vec>, + /// List of constant generators used to fill the constant wires. + constant_generators: Vec>, } impl, const D: usize> CircuitBuilder { @@ -106,7 +105,7 @@ impl, const D: usize> CircuitBuilder { arithmetic_results: HashMap::new(), targets_to_constants: HashMap::new(), current_slots: HashMap::new(), - constants_slots: Vec::new(), + constant_generators: Vec::new(), }; builder.check_config(); builder @@ -213,22 +212,17 @@ impl, const D: usize> CircuitBuilder { /// Adds a gate to the circuit, and returns its index. pub fn add_gate>(&mut self, gate_type: G, mut constants: Vec) -> usize { self.check_gate_compatibility(&gate_type); - // assert_eq!( - // gate_type.num_constants(), - // constants.len(), - // "Number of constants doesn't match." - // ); - assert!(constants.len() <= gate_type.num_constants()); + assert!( + constants.len() <= gate_type.num_constants(), + "Too many constants." + ); constants.resize(gate_type.num_constants(), F::ZERO); let index = self.gate_instances.len(); - self.constants_slots + self.constant_generators .extend(gate_type.extra_constants(index)); - // for const_gen in gate_type.extra_constants() { - // self.constants_slots.push((index, ci, ti, gen)); - // } // Note that we can't immediately add this gate's generators, because the list of constants // could be modified later, i.e. in the case of `ConstantGate`. We will add them later in @@ -664,8 +658,8 @@ impl, const D: usize> CircuitBuilder { self.connect(hash_part, Target::wire(pi_gate, wire)) } - // Fill constants - while self.constants_to_targets.len() > self.constants_slots.len() { + // Make sure we have enough constant generators. If not, add a `ConstantGate`. + while self.constants_to_targets.len() > self.constant_generators.len() { self.add_gate( ConstantGate { num_consts: self.config.num_constants, @@ -673,19 +667,22 @@ impl, const D: usize> CircuitBuilder { vec![], ); } - dbg!(self.constants_to_targets.len(), self.constants_slots.len()); + // For each constant-target pair used in the circuit, use a constant generator to fill this target. for ((c, t), mut const_gen) in self .constants_to_targets .clone() .into_iter() - .zip(self.constants_slots.clone()) + .zip(self.constant_generators.clone()) { + // Set the constant in the constant polynomial. self.gate_instances[const_gen.gate_index].constants[const_gen.constant_index] = c; - self.generate_copy( + // Generate a copy between the target and the routable wire. + self.connect( Target::wire(const_gen.gate_index, const_gen.target_index), t, ); + // Set the constant in the generator (it's initially set with a dummy value). const_gen.set_constant(c); self.add_simple_generator(const_gen); }