diff --git a/insertion/src/insertion_gate.rs b/insertion/src/insertion_gate.rs index 8ee60483..cb5fdc22 100644 --- a/insertion/src/insertion_gate.rs +++ b/insertion/src/insertion_gate.rs @@ -3,6 +3,7 @@ use std::ops::Range; use plonky2::field::extension_field::{Extendable, FieldExtension}; use plonky2::field::field_types::Field; +use plonky2::gates::batchable::MultiOpsGate; use plonky2::gates::gate::Gate; use plonky2::gates::util::StridedConstraintConsumer; use plonky2::hash::hash_types::RichField; @@ -242,6 +243,16 @@ impl, const D: usize> Gate for InsertionGate< } } +impl, const D: usize> MultiOpsGate for InsertionGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + #[derive(Debug)] struct InsertionGenerator, const D: usize> { gate_index: usize, diff --git a/plonky2/src/gadgets/interpolation.rs b/plonky2/src/gadgets/interpolation.rs index 7907a337..92b17098 100644 --- a/plonky2/src/gadgets/interpolation.rs +++ b/plonky2/src/gadgets/interpolation.rs @@ -2,6 +2,7 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; +use crate::gates::batchable::BatchableGate; use crate::gates::gate::Gate; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; @@ -12,7 +13,7 @@ use crate::plonk::circuit_builder::CircuitBuilder; /// with the given size, and whose values are extension field elements, given by input wires. /// Outputs the evaluation of the interpolant at a given (extension field) evaluation point. pub(crate) trait InterpolationGate, const D: usize>: - Gate + Copy + BatchableGate + Copy { fn new(subgroup_bits: usize) -> Self; diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 8f67dab2..ca308923 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -1,6 +1,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -151,6 +152,20 @@ impl, const D: usize> Gate for ArithmeticGate } } +impl, const D: usize> MultiOpsGate for ArithmeticGate { + fn num_ops(&self) -> usize { + self.num_ops + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + vec![ + Target::wire(gate_index, Self::wire_ith_multiplicand_0(i)), + Target::wire(gate_index, Self::wire_ith_multiplicand_1(i)), + Target::wire(gate_index, Self::wire_ith_addend(i)), + ] + } +} + impl, const D: usize> PackedEvaluableBase for ArithmeticGate { fn eval_unfiltered_base_packed>( &self, diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 93f7277c..bd575272 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -3,6 +3,7 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; use plonky2_field::extension_field::FieldExtension; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -158,6 +159,23 @@ impl, const D: usize> Gate for ArithmeticExte } } +impl, const D: usize> MultiOpsGate + for ArithmeticExtensionGate +{ + fn num_ops(&self) -> usize { + self.num_ops + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + [ + ExtensionTarget::::from_range(gate_index, Self::wires_ith_multiplicand_0(i)).0, + ExtensionTarget::::from_range(gate_index, Self::wires_ith_multiplicand_1(i)).0, + ExtensionTarget::::from_range(gate_index, Self::wires_ith_addend(i)).0, + ] + .concat() + } +} + #[derive(Clone, Debug)] struct ArithmeticExtensionGenerator, const D: usize> { gate_index: usize, diff --git a/plonky2/src/gates/arithmetic_u32.rs b/plonky2/src/gates/arithmetic_u32.rs index 1d4a834c..10d16ec2 100644 --- a/plonky2/src/gates/arithmetic_u32.rs +++ b/plonky2/src/gates/arithmetic_u32.rs @@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -232,6 +233,20 @@ impl, const D: usize> Gate for U32ArithmeticG } } +impl, const D: usize> MultiOpsGate for U32ArithmeticGate { + fn num_ops(&self) -> usize { + self.num_ops + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + vec![ + Target::wire(gate_index, self.wire_ith_multiplicand_0(i)), + Target::wire(gate_index, self.wire_ith_multiplicand_1(i)), + Target::wire(gate_index, self.wire_ith_addend(i)), + ] + } +} + impl, const D: usize> PackedEvaluableBase for U32ArithmeticGate { diff --git a/plonky2/src/gates/assert_le.rs b/plonky2/src/gates/assert_le.rs index 6a99acd9..759faf51 100644 --- a/plonky2/src/gates/assert_le.rs +++ b/plonky2/src/gates/assert_le.rs @@ -5,6 +5,7 @@ use plonky2_field::field_types::{Field, PrimeField}; use plonky2_field::packed_field::PackedField; use plonky2_util::{bits_u64, ceil_div_usize}; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -280,6 +281,16 @@ impl, const D: usize> Gate for AssertLessThan } } +impl, const D: usize> MultiOpsGate for AssertLessThanGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + impl, const D: usize> PackedEvaluableBase for AssertLessThanGate { diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index a5391abf..87db3c61 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::{Field, PrimeField}; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -135,6 +136,17 @@ impl, const D: usize, const B: usize> Gate fo 1 + self.num_limbs } } +impl, const D: usize, const B: usize> MultiOpsGate + for BaseSumGate +{ + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} impl, const D: usize, const B: usize> PackedEvaluableBase for BaseSumGate diff --git a/plonky2/src/gates/batchable.rs b/plonky2/src/gates/batchable.rs index b0aaa87a..a2daef6f 100644 --- a/plonky2/src/gates/batchable.rs +++ b/plonky2/src/gates/batchable.rs @@ -1,28 +1,94 @@ use std::collections::HashMap; -use std::hash::Hash; +use std::fmt::{Debug, Error, Formatter}; +use std::hash::{Hash, Hasher}; +use std::marker::PhantomData; 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 { - type Parameters: Copy; - - fn find_available_slot(&self, params: Self::Parameters) -> (usize, usize); - - fn fill_gate(&self, params: Self::Parameters, builder: &mut CircuitBuilder); + // TODO: It would be nice to have a `Parameters` associated type. + fn fill_gate( + &self, + params: &[F], + current_slot: &CurrentSlot, + builder: &mut CircuitBuilder, + ); } -pub struct CurrentSlot, const D: usize, G: BatchableGate> { - current_slot: HashMap, +pub struct CurrentSlot, const D: usize> { + current_slot: HashMap, (usize, usize)>, } -// pub struct Yo, const D: usize>( -// CurrentSlot>, -// ); +#[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 { + fn num_ops(&self) -> usize; + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec; +} + +impl, G: MultiOpsGate, const D: usize> BatchableGate + for G +{ + fn fill_gate( + &self, + params: &[F], + current_slot: &CurrentSlot, + builder: &mut CircuitBuilder, + ) { + if let Some(&(gate_index, op)) = current_slot.current_slot.get(params) { + let zero = builder.zero(); + for i in op..self.num_ops() { + for dep in self.dependencies_ith_op(gate_index, i) { + builder.connect(dep, zero); + } + } + } + } +} diff --git a/plonky2/src/gates/comparison.rs b/plonky2/src/gates/comparison.rs index 9a119b1d..f0ab000f 100644 --- a/plonky2/src/gates/comparison.rs +++ b/plonky2/src/gates/comparison.rs @@ -5,6 +5,7 @@ use plonky2_field::field_types::{Field, PrimeField}; use plonky2_field::packed_field::PackedField; use plonky2_util::{bits_u64, ceil_div_usize}; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -313,6 +314,26 @@ impl, const D: usize> Gate for ComparisonGate } } +impl, const D: usize> MultiOpsGate for ComparisonGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + +// 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 14b21867..f59f3604 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -102,6 +103,16 @@ impl, const D: usize> Gate for ConstantGate { } } +impl, const D: usize> MultiOpsGate for ConstantGate { + fn num_ops(&self) -> usize { + self.num_consts + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + vec![] + } +} + impl, const D: usize> PackedEvaluableBase for ConstantGate { fn eval_unfiltered_base_packed>( &self, diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index 51558a21..6d72e21b 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -5,6 +5,7 @@ use plonky2_field::field_types::Field; use plonky2_field::ops::Square; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::{BatchableGate, MultiOpsGate}; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -190,6 +191,16 @@ impl, const D: usize> Gate for Exponentiation } } +impl, const D: usize> MultiOpsGate for ExponentiationGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + impl, const D: usize> PackedEvaluableBase for ExponentiationGate { diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 9ae2a271..5cc15216 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -6,6 +6,7 @@ use plonky2_field::batch_util::batch_multiply_inplace; use plonky2_field::extension_field::{Extendable, FieldExtension}; use plonky2_field::field_types::Field; +use crate::gates::batchable::GateRef; use crate::gates::gate_tree::Tree; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -141,35 +142,35 @@ pub trait Gate, const D: usize>: 'static + Send + S fn num_constraints(&self) -> usize; } -/// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. -#[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()) - } -} +// /// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. +// #[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()) +// } +// } /// A gate along with any constants used to configure it. pub struct GateInstance, const D: usize> { diff --git a/plonky2/src/gates/gate_tree.rs b/plonky2/src/gates/gate_tree.rs index 029616a8..8c8ecfe1 100644 --- a/plonky2/src/gates/gate_tree.rs +++ b/plonky2/src/gates/gate_tree.rs @@ -1,7 +1,7 @@ use log::debug; use plonky2_field::extension_field::Extendable; -use crate::gates::gate::GateRef; +use crate::gates::batchable::GateRef; use crate::hash::hash_types::RichField; /// A binary tree where leaves hold some type `T` and other nodes are empty. diff --git a/plonky2/src/gates/gmimc.rs b/plonky2/src/gates/gmimc.rs index fdfb8673..a27f4b71 100644 --- a/plonky2/src/gates/gmimc.rs +++ b/plonky2/src/gates/gmimc.rs @@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -215,6 +216,17 @@ impl + GMiMC, const D: usize, const WIDTH: u gmimc::NUM_ROUNDS + WIDTH + 1 } } +impl + GMiMC, const D: usize, const WIDTH: usize> + MultiOpsGate for GMiMCGate +{ + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} impl + GMiMC, const D: usize, const WIDTH: usize> PackedEvaluableBase for GMiMCGate diff --git a/plonky2/src/gates/interpolation.rs b/plonky2/src/gates/interpolation.rs index 9d3d6e3f..c1ac866c 100644 --- a/plonky2/src/gates/interpolation.rs +++ b/plonky2/src/gates/interpolation.rs @@ -8,6 +8,7 @@ use plonky2_field::polynomial::PolynomialCoeffs; use crate::gadgets::interpolation::InterpolationGate; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -202,6 +203,17 @@ impl, const D: usize> Gate self.num_points() * D + D } } +impl, const D: usize> MultiOpsGate + for HighDegreeInterpolationGate +{ + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} #[derive(Debug)] struct InterpolationGenerator, const D: usize> { diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index b7307470..5f707fdb 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -9,6 +9,7 @@ use plonky2_field::polynomial::PolynomialCoeffs; use crate::gadgets::interpolation::InterpolationGate; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -294,6 +295,18 @@ impl, const D: usize> Gate for LowDegreeInter } } +impl, const D: usize> MultiOpsGate + for LowDegreeInterpolationGate +{ + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + #[derive(Debug)] struct InterpolationGenerator, const D: usize> { gate_index: usize, diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 9ccfe637..031edfdc 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -3,6 +3,7 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; use plonky2_field::extension_field::FieldExtension; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -145,6 +146,20 @@ impl, const D: usize> Gate for MulExtensionGa } } +impl, const D: usize> MultiOpsGate for MulExtensionGate { + fn num_ops(&self) -> usize { + self.num_ops + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + [ + ExtensionTarget::::from_range(gate_index, Self::wires_ith_multiplicand_0(i)).0, + ExtensionTarget::::from_range(gate_index, Self::wires_ith_multiplicand_1(i)).0, + ] + .concat() + } +} + #[derive(Clone, Debug)] struct MulExtensionGenerator, const D: usize> { gate_index: usize, diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index 4cd872d8..56942308 100644 --- a/plonky2/src/gates/noop.rs +++ b/plonky2/src/gates/noop.rs @@ -1,9 +1,11 @@ use plonky2_field::extension_field::Extendable; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGenerator; +use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch}; @@ -56,6 +58,16 @@ impl, const D: usize> Gate for NoopGate { } } +impl, const D: usize> MultiOpsGate for NoopGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + #[cfg(test)] mod tests { use plonky2_field::goldilocks_field::GoldilocksField; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index 366e200e..f2e3ebbf 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -3,6 +3,7 @@ use std::marker::PhantomData; use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::poseidon_mds::PoseidonMdsGate; use crate::gates::util::StridedConstraintConsumer; @@ -406,6 +407,15 @@ impl, const D: usize> Gate for PoseidonGate, const D: usize> MultiOpsGate for PoseidonGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} #[derive(Debug)] struct PoseidonGenerator + Poseidon, const D: usize> { diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index 81583f88..8b1fe9c4 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -6,6 +6,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::extension_field::FieldExtension; use plonky2_field::field_types::Field; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -196,6 +197,17 @@ impl + Poseidon, const D: usize> Gate for Pos SPONGE_WIDTH * D } } +impl + Poseidon, const D: usize> MultiOpsGate + for PoseidonMdsGate +{ + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} #[derive(Clone, Debug)] struct PoseidonMdsGenerator { diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index 20fc59c8..d8fd0355 100644 --- a/plonky2/src/gates/public_input.rs +++ b/plonky2/src/gates/public_input.rs @@ -3,12 +3,14 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; 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::WitnessGenerator; +use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, @@ -87,6 +89,16 @@ impl, const D: usize> Gate for PublicInputGat } } +impl, const D: usize> MultiOpsGate for PublicInputGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + impl, const D: usize> PackedEvaluableBase for PublicInputGate { fn eval_unfiltered_base_packed>( &self, diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 77359a19..6a93b259 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -230,6 +231,21 @@ impl, const D: usize> Gate for RandomAccessGa } } +impl, const D: usize> MultiOpsGate for RandomAccessGate { + fn num_ops(&self) -> usize { + self.num_copies + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + RandomAccessGenerator { + gate_index, + gate: *self, + copy: i, + } + .dependencies() + } +} + impl, const D: usize> PackedEvaluableBase for RandomAccessGate { diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index 2abf8425..ed75bfb5 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -3,6 +3,7 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; use plonky2_field::extension_field::FieldExtension; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -166,6 +167,16 @@ impl, const D: usize> Gate for ReducingGate, const D: usize> MultiOpsGate for ReducingGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + #[derive(Debug)] struct ReducingGenerator { gate_index: usize, diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 6655f1d7..de8b15b6 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -3,6 +3,7 @@ use std::ops::Range; use plonky2_field::extension_field::Extendable; use plonky2_field::extension_field::FieldExtension; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -166,6 +167,16 @@ impl, const D: usize> Gate for ReducingExtens } } +impl, const D: usize> MultiOpsGate for ReducingExtensionGate { + fn num_ops(&self) -> usize { + 1 + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + unreachable!() + } +} + #[derive(Debug)] struct ReducingGenerator { gate_index: usize, diff --git a/plonky2/src/gates/subtraction_u32.rs b/plonky2/src/gates/subtraction_u32.rs index fa817ce4..a6fa5e74 100644 --- a/plonky2/src/gates/subtraction_u32.rs +++ b/plonky2/src/gates/subtraction_u32.rs @@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -221,6 +222,22 @@ impl, const D: usize> Gate for U32Subtraction } } +impl, const D: usize> MultiOpsGate for U32SubtractionGate { + fn num_ops(&self) -> usize { + self.num_ops + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + U32SubtractionGenerator { + gate: *self, + gate_index, + i, + _phantom: Default::default(), + } + .dependencies() + } +} + impl, const D: usize> PackedEvaluableBase for U32SubtractionGate { diff --git a/plonky2/src/gates/switch.rs b/plonky2/src/gates/switch.rs index c5271a60..f782947a 100644 --- a/plonky2/src/gates/switch.rs +++ b/plonky2/src/gates/switch.rs @@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; +use crate::gates::batchable::MultiOpsGate; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -189,6 +190,16 @@ impl, const D: usize> Gate for SwitchGate, const D: usize> MultiOpsGate for SwitchGate { + fn num_ops(&self) -> usize { + self.num_copies + } + + fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec { + todo!() + } +} + impl, const D: usize> PackedEvaluableBase for SwitchGate { fn eval_unfiltered_base_packed>( &self, diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index cc4a19a4..cdd169ff 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -18,9 +18,9 @@ use crate::gadgets::arithmetic_u32::U32Target; use crate::gates::arithmetic_base::ArithmeticGate; use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::arithmetic_u32::U32ArithmeticGate; -use crate::gates::batchable::{BatchableGate, CurrentSlot}; +use crate::gates::batchable::{BatchableGate, CurrentSlot, GateRef}; use crate::gates::constant::ConstantGate; -use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate}; +use crate::gates::gate::{Gate, GateInstance, PrefixedGate}; use crate::gates::gate_tree::Tree; use crate::gates::multiplication_extension::MulExtensionGate; use crate::gates::noop::NoopGate; @@ -86,6 +86,8 @@ pub struct CircuitBuilder, const D: usize> { // yo: Vec>, batched_gates: BatchedGates, + + current_slots: HashMap, CurrentSlot>, } impl, const D: usize> CircuitBuilder { @@ -105,6 +107,7 @@ impl, const D: usize> CircuitBuilder { arithmetic_results: HashMap::new(), targets_to_constants: HashMap::new(), batched_gates: BatchedGates::new(), + current_slots: HashMap::new(), }; builder.check_config(); builder @@ -189,7 +192,7 @@ impl, const D: usize> CircuitBuilder { } /// Adds a gate to the circuit, and returns its index. - pub fn add_gate>(&mut self, gate_type: G, constants: Vec) -> usize { + pub fn add_gate>(&mut self, gate_type: G, constants: Vec) -> usize { self.check_gate_compatibility(&gate_type); assert_eq!( gate_type.num_constants(),