diff --git a/plonky2/src/gates/batchable.rs b/plonky2/src/gates/batchable.rs deleted file mode 100644 index 20ab39f3..00000000 --- a/plonky2/src/gates/batchable.rs +++ /dev/null @@ -1,80 +0,0 @@ -// use std::collections::HashMap; -// use std::fmt::{Debug, Error, Formatter}; -// use std::hash::{Hash, Hasher}; -// use std::sync::Arc; -// -// use plonky2_field::extension_field::Extendable; -// -// use crate::gates::gate::Gate; -// use crate::hash::hash_types::RichField; -// use crate::iop::target::Target; -// use crate::plonk::circuit_builder::CircuitBuilder; -// -// pub trait BatchableGate, const D: usize>: Gate { -// fn num_ops(&self) -> usize; -// -// // TODO: It would be nice to have a `Parameters` associated type. -// fn fill_gate( -// &self, -// params: &[F], -// current_slot: &CurrentSlot, -// builder: &mut CircuitBuilder, -// ); -// } -// -// #[derive(Clone, Debug)] -// pub struct CurrentSlot, const D: usize> { -// pub current_slot: HashMap, (usize, usize)>, -// } -// -// #[derive(Clone)] -// pub struct GateRef, const D: usize>( -// pub(crate) Arc>, -// ); -// -// impl, const D: usize> GateRef { -// pub fn new>(gate: G) -> GateRef { -// GateRef(Arc::new(gate)) -// } -// } -// -// impl, const D: usize> PartialEq for GateRef { -// fn eq(&self, other: &Self) -> bool { -// self.0.id() == other.0.id() -// } -// } -// -// impl, const D: usize> Hash for GateRef { -// fn hash(&self, state: &mut H) { -// self.0.id().hash(state) -// } -// } -// -// impl, const D: usize> Eq for GateRef {} -// -// impl, const D: usize> Debug for GateRef { -// fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { -// write!(f, "{}", self.0.id()) -// } -// } -// -// // pub trait SingleOpGate, const D: usize>: Gate {} -// // impl, G: SingleOpGate, const D: usize> MultiOpsGate for G { -// // fn num_ops(&self) -> usize { -// // 1 -// // } -// // -// // fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { -// // unreachable!() -// // } -// // } -// -// pub trait MultiOpsGate, const D: usize>: Gate {} -// -// impl, G: MultiOpsGate, const D: usize> BatchableGate -// for G -// { -// fn num_ops(&self) -> usize { -// self.num_ops() -// } -// } diff --git a/plonky2/src/gates/comparison.rs b/plonky2/src/gates/comparison.rs index 00e7f4d3..4a68adb7 100644 --- a/plonky2/src/gates/comparison.rs +++ b/plonky2/src/gates/comparison.rs @@ -321,16 +321,6 @@ impl, const D: usize> Gate for ComparisonGate } } -// impl, const D: usize> Singleopgate for multiopsgate { -// fn num_ops(&self) -> usize { -// 1 -// } -// -// fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { -// unreachable!() -// } -// } - impl, const D: usize> PackedEvaluableBase for ComparisonGate { diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index 455e5349..d62befc4 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -1,5 +1,3 @@ -use std::ops::Range; - use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; @@ -26,12 +24,14 @@ pub struct ConstantGate { } impl ConstantGate { - pub fn consts_inputs(&self) -> Range { - 0..self.num_consts + pub fn const_input(&self, i: usize) -> usize { + debug_assert!(i < self.num_consts); + i } - pub fn wires_outputs(&self) -> Range { - 0..self.num_consts + pub fn wire_output(&self, i: usize) -> usize { + debug_assert!(i < self.num_consts); + i } } @@ -41,9 +41,10 @@ impl, const D: usize> Gate for ConstantGate { } fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec { - self.consts_inputs() - .zip(self.wires_outputs()) - .map(|(con, out)| vars.local_constants[con] - vars.local_wires[out]) + (0..self.num_consts) + .map(|i| { + vars.local_constants[self.const_input(i)] - vars.local_wires[self.wire_output(i)] + }) .collect() } @@ -64,10 +65,12 @@ impl, const D: usize> Gate for ConstantGate { builder: &mut CircuitBuilder, vars: EvaluationTargets, ) -> Vec> { - self.consts_inputs() - .zip(self.wires_outputs()) - .map(|(con, out)| { - builder.sub_extension(vars.local_constants[con], vars.local_wires[out]) + (0..self.num_consts) + .map(|i| { + builder.sub_extension( + vars.local_constants[self.const_input(i)], + vars.local_wires[self.wire_output(i)], + ) }) .collect() } @@ -77,12 +80,20 @@ impl, const D: usize> Gate for ConstantGate { gate_index: usize, local_constants: &[F], ) -> Vec>> { - let gen = ConstantGenerator { - gate_index, - gate: *self, - constants: local_constants[self.consts_inputs()].to_vec(), - }; - vec![Box::new(gen.adapter())] + (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() } fn num_wires(&self) -> usize { @@ -116,11 +127,9 @@ impl, const D: usize> PackedEvaluableBase for vars: EvaluationVarsBasePacked

, mut yield_constr: StridedConstraintConsumer

, ) { - yield_constr.many( - self.consts_inputs() - .zip(self.wires_outputs()) - .map(|(con, out)| vars.local_constants[con] - vars.local_wires[out]), - ); + yield_constr.many((0..self.num_consts).map(|i| { + vars.local_constants[self.const_input(i)] - vars.local_wires[self.wire_output(i)] + })); } } @@ -128,7 +137,8 @@ impl, const D: usize> PackedEvaluableBase for struct ConstantGenerator { gate_index: usize, gate: ConstantGate, - constants: Vec, + i: usize, + constant: F, } impl SimpleGenerator for ConstantGenerator { @@ -137,13 +147,11 @@ impl SimpleGenerator for ConstantGenerator { } fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { - for (con, out) in self.gate.consts_inputs().zip(self.gate.wires_outputs()) { - let wire = Wire { - gate: self.gate_index, - input: out, - }; - out_buffer.set_wire(wire, self.constants[con]); - } + let wire = Wire { + gate: self.gate_index, + input: self.gate.wire_output(self.i), + }; + out_buffer.set_wire(wire, self.constant); } } diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 391533a7..1d487db7 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -142,10 +142,13 @@ pub trait Gate, const D: usize>: 'static + Send + S fn num_constraints(&self) -> usize; + /// Number of operations performed by the gate. fn num_ops(&self) -> usize; + /// Dependencies (inputs) for the i-th operation. fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec; + /// Fill the dependencies of the fn fill_gate( &self, params: &[F], diff --git a/plonky2/src/gates/mod.rs b/plonky2/src/gates/mod.rs index 4f01b7ce..18e3e99b 100644 --- a/plonky2/src/gates/mod.rs +++ b/plonky2/src/gates/mod.rs @@ -7,7 +7,6 @@ pub mod arithmetic_extension; pub mod arithmetic_u32; pub mod assert_le; pub mod base_sum; -pub mod batchable; pub mod comparison; pub mod constant; pub mod exponentiation; diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index e9507a31..5ef7c318 100644 --- a/plonky2/src/gates/noop.rs +++ b/plonky2/src/gates/noop.rs @@ -57,7 +57,7 @@ impl, const D: usize> Gate for NoopGate { } fn num_ops(&self) -> usize { - 1 + 0 } fn dependencies_ith_op(&self, _gate_index: usize, _i: usize) -> Vec { diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index c749ba4e..aa0c19a2 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -662,6 +662,15 @@ impl, const D: usize> CircuitBuilder { let start = Instant::now(); let rate_bits = self.config.fri_config.rate_bits; + for g in &self.gate_instances { + assert_eq!( + g.gate_ref.0.generators(0, &[F::ZERO; 100]).len(), + g.gate_ref.0.num_ops(), + "{}", + g.gate_ref.0.id() + ); + } + self.fill_batched_gates(); // Hash the public inputs, and route them to a `PublicInputGate` which will enforce that @@ -739,11 +748,6 @@ impl, const D: usize> CircuitBuilder { constants_sigmas_cap: constants_sigmas_cap.clone(), }; - let mut gens = self.generators.len(); - for (i, g) in self.gate_instances.iter().enumerate() { - gens += g.gate_ref.0.generators(i, &g.constants).len(); - dbg!(g.gate_ref.0.id(), gens); - } // Add gate generators. self.add_generators( self.gate_instances