From 9d253f85568fc950f688e8cf83eadfa972e055bd Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Mon, 17 Jul 2023 09:13:13 +0000 Subject: [PATCH] fix: emit opcodes for sorting variables in order of execution --- .../acir_gen/acir_ir/acir_variable.rs | 6 ++++-- .../acir_gen/acir_ir/generated_acir.rs | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs index 98f551239b0..a1fb66ab749 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs @@ -869,12 +869,14 @@ impl AcirContext { let outputs_var = vecmap(&outputs_witness, |witness_index| { self.add_data(AcirVarData::Witness(*witness_index)) }); + + // Enforce the outputs to be a permutation of the inputs + self.acir_ir.permutation(&inputs_expr, &output_expr); + // Enforce the outputs to be sorted for i in 0..(outputs_var.len() - 1) { self.less_than_constrain(outputs_var[i], outputs_var[i + 1], bit_size, None)?; } - // Enforce the outputs to be a permutation of the inputs - self.acir_ir.permutation(&inputs_expr, &output_expr); Ok(outputs_var) } diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs index edd9777b127..16e07c29730 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs @@ -795,19 +795,25 @@ impl GeneratedAcir { /// n.b. A sorting network is a predetermined set of switches, /// the control bits indicate the configuration of each switch: false for pass-through and true for cross-over pub(crate) fn permutation(&mut self, in_expr: &[Expression], out_expr: &[Expression]) { - let bits = Vec::new(); - let (w, b) = self.permutation_layer(in_expr, &bits, true); - // Constrain the network output to out_expr - for (b, o) in b.iter().zip(out_expr) { - self.push_opcode(AcirOpcode::Arithmetic(b - o)); + let mut bits_len = 0; + for i in 0..in_expr.len() { + bits_len += ((i + 1) as f32).log2().ceil() as u32; } + + let bits = vecmap(0..bits_len, |_| self.next_witness_index()); let inputs = in_expr.iter().map(|a| vec![a.clone()]).collect(); self.push_opcode(AcirOpcode::Directive(Directive::PermutationSort { inputs, tuple: 1, - bits: w, + bits: bits.clone(), sort_by: vec![0], })); + let (_, b) = self.permutation_layer(in_expr, &bits, false); + + // Constrain the network output to out_expr + for (b, o) in b.iter().zip(out_expr) { + self.push_opcode(AcirOpcode::Arithmetic(b - o)); + } } }