From 020b10e5735fd11297df35c349a175a081f467e6 Mon Sep 17 00:00:00 2001 From: guipublic Date: Fri, 24 May 2024 09:32:06 +0000 Subject: [PATCH 1/2] Avoid creating witness for simple multiplications --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 90cdbb650c2..b6e88a8d4b0 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -614,13 +614,44 @@ impl AcirContext { expr.push_multiplication_term(FieldElement::one(), lhs_witness, rhs_witness); self.add_data(AcirVarData::Expr(expr)) } - ( - AcirVarData::Expr(_) | AcirVarData::Witness(_), - AcirVarData::Expr(_) | AcirVarData::Witness(_), - ) => { + (AcirVarData::Expr(expression), AcirVarData::Witness(witness)) + | (AcirVarData::Witness(witness), AcirVarData::Expr(expression)) + if expression.is_linear() => + { + let mut expr = Expression::default(); + for term in expression.linear_combinations.iter() { + expr.push_multiplication_term(term.0, term.1, witness); + } + expr.push_addition_term(expression.q_c, witness); + self.add_data(AcirVarData::Expr(expr)) + } + (AcirVarData::Expr(lhs_expr), AcirVarData::Expr(rhs_expr)) => { + let degree_one = if lhs_expr.is_linear() && rhs_expr.is_degree_one_univariate() { + Some((lhs_expr, rhs_expr)) + } else if rhs_expr.is_linear() && lhs_expr.is_degree_one_univariate() { + Some((rhs_expr, lhs_expr)) + } else { + None + }; + if let Some((lin, univariate)) = degree_one { + let mut expr = Expression::default(); + let rhs_term = univariate.linear_combinations[0]; + for term in lin.linear_combinations.iter() { + expr.push_multiplication_term(term.0 * rhs_term.0, term.1, rhs_term.1); + } + expr.push_addition_term(lin.q_c * rhs_term.0, rhs_term.1); + expr.sort(); + expr = expr.add_mul(univariate.q_c, &lin); + self.add_data(AcirVarData::Expr(expr)) + } else { + let lhs = self.get_or_create_witness_var(lhs)?; + let rhs = self.get_or_create_witness_var(rhs)?; + self.mul_var(lhs, rhs)? + } + } + _ => { let lhs = self.get_or_create_witness_var(lhs)?; let rhs = self.get_or_create_witness_var(rhs)?; - self.mul_var(lhs, rhs)? } }; From 91e6e5319c648122d10d0b8af41782190243829d Mon Sep 17 00:00:00 2001 From: guipublic Date: Fri, 24 May 2024 12:09:46 +0000 Subject: [PATCH 2/2] Fix the width transformation --- acvm-repo/acvm/src/compiler/transformers/csat.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs index 9e2e3091c74..12a37e3e37a 100644 --- a/acvm-repo/acvm/src/compiler/transformers/csat.rs +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -210,16 +210,16 @@ impl CSatTransformer { } } else { // No more usable elements left in the old opcode - opcode.linear_combinations = remaining_linear_terms; break; } } + opcode.linear_combinations.extend(remaining_linear_terms); + // Constraint this intermediate_opcode to be equal to the temp variable by adding it into the IndexMap // We need a unique name for our intermediate variable // XXX: Another optimization, which could be applied in another algorithm // If two opcodes have a large fan-in/out and they share a few common terms, then we should create intermediate variables for them // Do some sort of subset matching algorithm for this on the terms of the polynomial - let inter_var = Self::get_or_create_intermediate_vars( intermediate_variables, intermediate_opcode,