From b2264752dea4c0238e92a05c421b0e4a83f9830b Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 7 Nov 2021 11:29:15 -0800 Subject: [PATCH] Optimize combination of gate constraints in recursive circuit (#342) Just passing the "combined constraints" buffer into `eval_filtered_recursively`, so that we can combine a mul by the filter with an add into the buffer. Saves 56 wires. --- src/gates/gate.rs | 12 +++++++----- src/plonk/vanishing_poly.rs | 22 +++++++++------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/gates/gate.rs b/src/gates/gate.rs index b882c336..a83adacf 100644 --- a/src/gates/gate.rs +++ b/src/gates/gate.rs @@ -86,18 +86,20 @@ pub trait Gate, const D: usize>: 'static + Send + S .collect() } + /// Adds this gate's filtered constraints into the `combined_gate_constraints` buffer. fn eval_filtered_recursively( &self, builder: &mut CircuitBuilder, mut vars: EvaluationTargets, prefix: &[bool], - ) -> Vec> { + combined_gate_constraints: &mut Vec>, + ) { let filter = compute_filter_recursively(builder, prefix, vars.local_constants); vars.remove_prefix(prefix); - self.eval_unfiltered_recursively(builder, vars) - .into_iter() - .map(|c| builder.mul_extension(filter, c)) - .collect() + let my_constraints = self.eval_unfiltered_recursively(builder, vars); + for (acc, c) in combined_gate_constraints.iter_mut().zip(my_constraints) { + *acc = builder.mul_add_extension(filter, c, *acc); + } } fn generators( diff --git a/src/plonk/vanishing_poly.rs b/src/plonk/vanishing_poly.rs index 0ebdbd22..28c6a287 100644 --- a/src/plonk/vanishing_poly.rs +++ b/src/plonk/vanishing_poly.rs @@ -288,24 +288,20 @@ pub fn evaluate_gate_constraints_recursively, const num_gate_constraints: usize, vars: EvaluationTargets, ) -> Vec> { - let mut all_gate_constraints = vec![vec![]; num_gate_constraints]; + let mut all_gate_constraints = vec![builder.zero_extension(); num_gate_constraints]; for gate in gates { - let gate_constraints = with_context!( + with_context!( builder, &format!("evaluate {} constraints", gate.gate.0.id()), - gate.gate - .0 - .eval_filtered_recursively(builder, vars, &gate.prefix) + gate.gate.0.eval_filtered_recursively( + builder, + vars, + &gate.prefix, + &mut all_gate_constraints + ) ); - for (i, c) in gate_constraints.into_iter().enumerate() { - all_gate_constraints[i].push(c); - } } - let mut constraints = vec![builder.zero_extension(); num_gate_constraints]; - for (i, v) in all_gate_constraints.into_iter().enumerate() { - constraints[i] = builder.add_many_extension(&v); - } - constraints + all_gate_constraints } /// Evaluate the vanishing polynomial at `x`. In this context, the vanishing polynomial is a random