From 23abefa20d44aae42dccb2980193488f15dd3a94 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 24 Jul 2023 09:01:34 +0000 Subject: [PATCH 1/5] feat: first version of to_radix and to_bits --- Cargo.lock | 23 ++- Cargo.toml | 3 +- .../brillig_to_be_bytes/Nargo.toml | 5 + .../brillig_to_be_bytes/Prover.toml | 1 + .../brillig_to_be_bytes/src/main.nr | 14 ++ .../brillig_to_bits/Nargo.toml | 5 + .../brillig_to_bits/src/main.nr | 24 +++ .../brillig_to_bytes_integration/Nargo.toml | 5 + .../brillig_to_bytes_integration/Prover.toml | 2 + .../brillig_to_bytes_integration/src/main.nr | 27 ++++ .../brillig_to_le_bytes/Nargo.toml | 5 + .../brillig_to_le_bytes/Prover.toml | 1 + .../brillig_to_le_bytes/src/main.nr | 14 ++ .../src/brillig/brillig_gen/brillig_block.rs | 41 +++++- .../noirc_evaluator/src/brillig/brillig_ir.rs | 138 ++++++++++++++++++ 15 files changed, 292 insertions(+), 16 deletions(-) create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/src/main.nr create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/src/main.nr create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/src/main.nr create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/src/main.nr diff --git a/Cargo.lock b/Cargo.lock index 6b81b673b42..7a86efd3980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,8 +5,7 @@ version = 3 [[package]] name = "acir" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269617cfc7050d47915308c2ae20c33642cbfbc5c25097ba10a522539556065b" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir_field", "bincode", @@ -19,8 +18,7 @@ dependencies = [ [[package]] name = "acir_field" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ace9d882b85479aa678c7272aa717acdcabe1f4d0cb6236cd17dcda8c4bb32" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "ark-bn254", "ark-ff", @@ -33,8 +31,7 @@ dependencies = [ [[package]] name = "acvm" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5eeabcd9c38133eb860c1ad4c0ced8d0032f9f22b6de0699bddacb69bd772ec" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir", "acvm_blackbox_solver", @@ -71,8 +68,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e3636cfc0b6a6e6e02a5b813b12941ef0979ec532290ee83587f42d7610dae" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir", "blake2", @@ -86,8 +82,7 @@ dependencies = [ [[package]] name = "acvm_stdlib" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fc3882d621cb13af2793e35fff3aa8ba34959c486808e665212d5423835386" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir", ] @@ -525,8 +520,7 @@ dependencies = [ [[package]] name = "brillig" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23339a18ea207882da08076a70564b5a44bad80ce2ebb3a46e89172979ae09fb" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir_field", "serde", @@ -535,11 +529,12 @@ dependencies = [ [[package]] name = "brillig_vm" version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "024f52eb86d8f320cbbf8c2f231acdd84fe2171d3d1926c4bc95d64e933aa23e" +source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" dependencies = [ "acir", "acvm_blackbox_solver", + "num-bigint", + "num-traits", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e272989b2aa..8084148823d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,4 +57,5 @@ wasm-bindgen-test = "0.3.33" base64 = "0.21.2" [patch.crates-io] -async-lsp = { git = "https://github.com/oxalica/async-lsp", rev = "09dbcc11046f7a188a80137f8d36484d86c78c78" } \ No newline at end of file +async-lsp = { git = "https://github.com/oxalica/async-lsp", rev = "09dbcc11046f7a188a80137f8d36484d86c78c78" } +acvm = { git = "https://github.com/noir-lang/acvm", branch = "gd/bigger_integer"} diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Nargo.toml new file mode 100644 index 00000000000..e0b467ce5da --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Prover.toml new file mode 100644 index 00000000000..07fe857ac7c --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/Prover.toml @@ -0,0 +1 @@ +x = "2040124" diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/src/main.nr new file mode 100644 index 00000000000..508725407d0 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_be_bytes/src/main.nr @@ -0,0 +1,14 @@ +use dep::std; + +unconstrained fn main(x : Field) -> pub [u8; 31] { + // The result of this byte array will be big-endian + let byte_array = x.to_be_bytes(31); + let mut bytes = [0; 31]; + for i in 0..31 { + bytes[i] = byte_array[i]; + } + assert(bytes[30] == 60); + assert(bytes[29] == 33); + assert(bytes[28] == 31); + bytes +} diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/Nargo.toml new file mode 100644 index 00000000000..5a02ffe4729 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.7.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/src/main.nr new file mode 100644 index 00000000000..65b0e5ca86c --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bits/src/main.nr @@ -0,0 +1,24 @@ +use dep::std; + +unconstrained fn main() { + let field = 1000; + let be_bits = field.to_be_bits(16); + let le_bits = field.to_le_bits(16); + + for i in 0..16 { + let x = be_bits[i]; + let y = le_bits[15-i]; + assert(x == y); + } + + let x = 3; + let be_bits_x = x.to_be_bits(4); + let le_bits_x = x.to_le_bits(4); + + for i in 0..4 { + let be_bit = be_bits_x[i]; + let le_bit = le_bits_x[3-i]; + assert(be_bit == le_bit); + } + +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Nargo.toml new file mode 100644 index 00000000000..5082c6e12ec --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Prover.toml new file mode 100644 index 00000000000..23f7acea449 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/Prover.toml @@ -0,0 +1,2 @@ +x = "2040124" +_y = "0x2000000000000000000000000000000000000000000000000000000000000000" diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/src/main.nr new file mode 100644 index 00000000000..964f4b49bf5 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_bytes_integration/src/main.nr @@ -0,0 +1,27 @@ +use dep::std; + +unconstrained fn main(x : Field, _y: Field) { + // The result of this byte array will be big-endian + let y: Field = 2040124; + let be_byte_array = y.to_be_bytes(31); + // The result of this byte array will be little-endian + let le_byte_array = x.to_le_bytes(31); + + assert(le_byte_array[0] == 60); + assert(le_byte_array[0] == be_byte_array[30]); + assert(le_byte_array[1] == be_byte_array[29]); + assert(le_byte_array[2] == be_byte_array[28]); + + let z = 0 - 1; + let p_bytes = std::field::modulus_le_bytes(); + let z_bytes = z.to_le_bytes(32); + assert(p_bytes[10] == z_bytes[10]); + assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8); + + let p_bits = std::field::modulus_le_bits(); + let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32); + assert(z_bits[0] == 0); + assert(p_bits[100] == z_bits[100]); + + _y.to_le_bits(std::field::modulus_num_bits() as u32); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Nargo.toml new file mode 100644 index 00000000000..e0b467ce5da --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Prover.toml new file mode 100644 index 00000000000..07fe857ac7c --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/Prover.toml @@ -0,0 +1 @@ +x = "2040124" diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/src/main.nr new file mode 100644 index 00000000000..3afa65d9eff --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig_to_le_bytes/src/main.nr @@ -0,0 +1,14 @@ +use dep::std; + +unconstrained fn main(x : Field) -> pub [u8; 4] { + // The result of this byte array will be little-endian + let byte_array = x.to_le_bytes(31); + let mut first_four_bytes = [0; 4]; + for i in 0..4 { + first_four_bytes[i] = byte_array[i]; + } + // Issue #617 fix + // We were incorrectly mapping our output array from bit decomposition functions during acir generation + first_four_bytes[3] = byte_array[31]; + first_four_bytes +} diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 3beae3db64b..6d2112b7933 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -5,7 +5,7 @@ use crate::brillig::brillig_ir::{ BrilligBinaryOp, BrilligContext, BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE, }; use crate::ssa_refactor::ir::function::FunctionId; -use crate::ssa_refactor::ir::instruction::Intrinsic; +use crate::ssa_refactor::ir::instruction::{Endian, Intrinsic}; use crate::ssa_refactor::ir::{ basic_block::{BasicBlock, BasicBlockId}, dfg::DataFlowGraph, @@ -327,6 +327,45 @@ impl<'block> BrilligBlock<'block> { arguments, ); } + Value::Intrinsic(Intrinsic::ToRadix(endianness)) => { + let source = self.convert_ssa_register_value(arguments[0], dfg); + let radix = self.convert_ssa_register_value(arguments[1], dfg); + let limb_count = self.convert_ssa_register_value(arguments[2], dfg); + let target_slice = self.function_context.create_variable( + self.brillig_context, + dfg.instruction_results(instruction_id)[0], + dfg, + ); + + self.brillig_context.radix_instruction( + source, + self.function_context.extract_heap_vector(target_slice), + radix, + limb_count, + matches!(endianness, Endian::Big), + ); + } + Value::Intrinsic(Intrinsic::ToBits(endianness)) => { + let source = self.convert_ssa_register_value(arguments[0], dfg); + let limb_count = self.convert_ssa_register_value(arguments[1], dfg); + let target_slice = self.function_context.create_variable( + self.brillig_context, + dfg.instruction_results(instruction_id)[0], + dfg, + ); + + let radix = self.brillig_context.make_constant(2_usize.into()); + + self.brillig_context.radix_instruction( + source, + self.function_context.extract_heap_vector(target_slice), + radix, + limb_count, + matches!(endianness, Endian::Big), + ); + + self.brillig_context.deallocate_register(radix); + } _ => { unreachable!("unsupported function call type {:?}", dfg[*func]) } diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir.rs b/crates/noirc_evaluator/src/brillig/brillig_ir.rs index 2de3aeb16dc..e1a09900ebc 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_ir.rs @@ -853,6 +853,144 @@ impl BrilligContext { self.debug_show.black_box_op_instruction(op); self.push_opcode(BrilligOpcode::BlackBox(op)); } + + pub(crate) fn radix_instruction( + &mut self, + source: RegisterIndex, + target_vector: HeapVector, + radix: RegisterIndex, + limb_count: RegisterIndex, + big_endian: bool, + ) { + // TODO check if it'll fit + self.mov_instruction(target_vector.size, limb_count); + self.allocate_array_instruction(target_vector.pointer, target_vector.size); + let shifted_register = self.allocate_register(); + self.mov_instruction(shifted_register, source); + + let index_register = self.make_constant(0_u128.into()); + let modulus_register = self.allocate_register(); + let loop_label = self.next_section_label(); + self.enter_next_section(); + + // Loop body + + // Check if index < num_elements + let index_less_than_array_len = self.allocate_register(); + self.memory_op( + index_register, + target_vector.size, + index_less_than_array_len, + BinaryIntOp::LessThan, + ); + + let exit_loop_label = self.next_section_label(); + + self.not_instruction(index_less_than_array_len, 1, index_less_than_array_len); + self.jump_if_instruction(index_less_than_array_len, exit_loop_label); + + // Compute the modulus + self.modulo_instruction( + modulus_register, + shifted_register, + radix, + FieldElement::max_num_bits(), + false, + ); + // Write it + self.array_set(target_vector.pointer, index_register, modulus_register); + // Integer div the field + self.binary_instruction( + shifted_register, + radix, + shifted_register, + BrilligBinaryOp::Integer { + op: BinaryIntOp::UnsignedDiv, + bit_size: FieldElement::max_num_bits(), + }, + ); + + // Increment the index register + self.usize_op_in_place(index_register, BinaryIntOp::Add, 1); + + self.jump_instruction(loop_label); + + // Exit the loop + self.enter_next_section(); + + // Deallocate our temporary registers + self.deallocate_register(shifted_register); + self.deallocate_register(index_register); + self.deallocate_register(modulus_register); + self.deallocate_register(index_less_than_array_len); + + if big_endian { + self.reverse_vector_in_place_instruction(target_vector); + } + } + + fn reverse_vector_in_place_instruction(&mut self, vector: HeapVector) { + let iterator_register = self.make_constant(0_u128.into()); + let iteration_count = self.allocate_register(); + self.usize_op(vector.size, iteration_count, BinaryIntOp::UnsignedDiv, 2); + + let loop_label = self.next_section_label(); + self.enter_next_section(); + + // Loop body + + // Check if iterator < iteration_count + let iterator_less_than_count = self.allocate_register(); + self.memory_op( + iterator_register, + iteration_count, + iterator_less_than_count, + BinaryIntOp::LessThan, + ); + + let exit_loop_label = self.next_section_label(); + + self.not_instruction(iterator_less_than_count, 1, iterator_less_than_count); + self.jump_if_instruction(iterator_less_than_count, exit_loop_label); + + // Load both values + let start_value_register = self.allocate_register(); + self.array_get(vector.pointer, iterator_register, start_value_register); + + // The index at the end of array is size - 1 - iterator + let index_at_end_of_array = self.allocate_register(); + self.mov_instruction(index_at_end_of_array, vector.size); + self.usize_op_in_place(index_at_end_of_array, BinaryIntOp::Sub, 1); + self.memory_op( + index_at_end_of_array, + iterator_register, + index_at_end_of_array, + BinaryIntOp::Sub, + ); + + let end_value_register = self.allocate_register(); + self.array_get(vector.pointer, index_at_end_of_array, end_value_register); + + // Write both values + self.array_set(vector.pointer, iterator_register, end_value_register); + self.array_set(vector.pointer, index_at_end_of_array, start_value_register); + + // Increment the index register + self.usize_op_in_place(iterator_register, BinaryIntOp::Add, 1); + + self.jump_instruction(loop_label); + + // Exit the loop + self.enter_next_section(); + + // Deallocate our temporary registers + self.deallocate_register(iterator_register); + self.deallocate_register(iteration_count); + self.deallocate_register(iterator_less_than_count); + self.deallocate_register(start_value_register); + self.deallocate_register(end_value_register); + self.deallocate_register(index_at_end_of_array); + } } /// Type to encapsulate the binary operation types in Brillig From 31f6a71af71d0a9455a6e214cf90e68cf59f108f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 24 Jul 2023 09:26:46 +0000 Subject: [PATCH 2/5] refactor: use loop hof --- .../noirc_evaluator/src/brillig/brillig_ir.rs | 190 +++++++----------- 1 file changed, 74 insertions(+), 116 deletions(-) diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir.rs b/crates/noirc_evaluator/src/brillig/brillig_ir.rs index e1a09900ebc..443df6ee15d 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_ir.rs @@ -230,43 +230,55 @@ impl BrilligContext { destination_pointer, num_elements_register, ); - let index_register = self.make_constant(0_u128.into()); + + let value_register = self.allocate_register(); + + self.loop_instruction(num_elements_register, |ctx, iterator| { + ctx.array_get(source_pointer, iterator, value_register); + ctx.array_set(destination_pointer, iterator, value_register); + }); + + self.deallocate_register(value_register); + } + + fn loop_instruction(&mut self, iteration_count: RegisterIndex, on_iteration: F) + where + F: FnOnce(&mut BrilligContext, RegisterIndex), + { + let iterator_register = self.make_constant(0_u128.into()); let loop_label = self.next_section_label(); self.enter_next_section(); // Loop body - // Check if index < num_elements - let index_less_than_array_len = self.allocate_register(); + // Check if iterator < iteration_count + let iterator_less_than_iterations = self.allocate_register(); self.memory_op( - index_register, - num_elements_register, - index_less_than_array_len, + iterator_register, + iteration_count, + iterator_less_than_iterations, BinaryIntOp::LessThan, ); let exit_loop_label = self.next_section_label(); - self.not_instruction(index_less_than_array_len, 1, index_less_than_array_len); - self.jump_if_instruction(index_less_than_array_len, exit_loop_label); + self.not_instruction(iterator_less_than_iterations, 1, iterator_less_than_iterations); + self.jump_if_instruction(iterator_less_than_iterations, exit_loop_label); - // Copy the element from source to destination - let value_register = self.allocate_register(); - self.array_get(source_pointer, index_register, value_register); - self.array_set(destination_pointer, index_register, value_register); + // Call the on iteration function + on_iteration(self, iterator_register); - // Increment the index register - self.usize_op_in_place(index_register, BinaryIntOp::Add, 1); + // Increment the iterator register + self.usize_op_in_place(iterator_register, BinaryIntOp::Add, 1); self.jump_instruction(loop_label); // Exit the loop self.enter_next_section(); // Deallocate our temporary registers - self.deallocate_register(index_less_than_array_len); - self.deallocate_register(value_register); - self.deallocate_register(index_register); + self.deallocate_register(iterator_less_than_iterations); + self.deallocate_register(iterator_register); } /// Adds a label to the next opcode @@ -865,64 +877,38 @@ impl BrilligContext { // TODO check if it'll fit self.mov_instruction(target_vector.size, limb_count); self.allocate_array_instruction(target_vector.pointer, target_vector.size); + let shifted_register = self.allocate_register(); self.mov_instruction(shifted_register, source); - let index_register = self.make_constant(0_u128.into()); - let modulus_register = self.allocate_register(); - let loop_label = self.next_section_label(); - self.enter_next_section(); - - // Loop body - - // Check if index < num_elements - let index_less_than_array_len = self.allocate_register(); - self.memory_op( - index_register, - target_vector.size, - index_less_than_array_len, - BinaryIntOp::LessThan, - ); - - let exit_loop_label = self.next_section_label(); - - self.not_instruction(index_less_than_array_len, 1, index_less_than_array_len); - self.jump_if_instruction(index_less_than_array_len, exit_loop_label); - - // Compute the modulus - self.modulo_instruction( - modulus_register, - shifted_register, - radix, - FieldElement::max_num_bits(), - false, - ); - // Write it - self.array_set(target_vector.pointer, index_register, modulus_register); - // Integer div the field - self.binary_instruction( - shifted_register, - radix, - shifted_register, - BrilligBinaryOp::Integer { - op: BinaryIntOp::UnsignedDiv, - bit_size: FieldElement::max_num_bits(), - }, - ); - - // Increment the index register - self.usize_op_in_place(index_register, BinaryIntOp::Add, 1); - - self.jump_instruction(loop_label); - - // Exit the loop - self.enter_next_section(); + let modulus_register: RegisterIndex = self.allocate_register(); + + self.loop_instruction(target_vector.size, |ctx, iterator_register| { + // Compute the modulus + ctx.modulo_instruction( + modulus_register, + shifted_register, + radix, + FieldElement::max_num_bits(), + false, + ); + // Write it + ctx.array_set(target_vector.pointer, iterator_register, modulus_register); + // Integer div the field + ctx.binary_instruction( + shifted_register, + radix, + shifted_register, + BrilligBinaryOp::Integer { + op: BinaryIntOp::UnsignedDiv, + bit_size: FieldElement::max_num_bits(), + }, + ); + }); // Deallocate our temporary registers self.deallocate_register(shifted_register); - self.deallocate_register(index_register); self.deallocate_register(modulus_register); - self.deallocate_register(index_less_than_array_len); if big_endian { self.reverse_vector_in_place_instruction(target_vector); @@ -930,63 +916,35 @@ impl BrilligContext { } fn reverse_vector_in_place_instruction(&mut self, vector: HeapVector) { - let iterator_register = self.make_constant(0_u128.into()); let iteration_count = self.allocate_register(); self.usize_op(vector.size, iteration_count, BinaryIntOp::UnsignedDiv, 2); - let loop_label = self.next_section_label(); - self.enter_next_section(); - - // Loop body - - // Check if iterator < iteration_count - let iterator_less_than_count = self.allocate_register(); - self.memory_op( - iterator_register, - iteration_count, - iterator_less_than_count, - BinaryIntOp::LessThan, - ); - - let exit_loop_label = self.next_section_label(); - - self.not_instruction(iterator_less_than_count, 1, iterator_less_than_count); - self.jump_if_instruction(iterator_less_than_count, exit_loop_label); - - // Load both values let start_value_register = self.allocate_register(); - self.array_get(vector.pointer, iterator_register, start_value_register); - - // The index at the end of array is size - 1 - iterator let index_at_end_of_array = self.allocate_register(); - self.mov_instruction(index_at_end_of_array, vector.size); - self.usize_op_in_place(index_at_end_of_array, BinaryIntOp::Sub, 1); - self.memory_op( - index_at_end_of_array, - iterator_register, - index_at_end_of_array, - BinaryIntOp::Sub, - ); - let end_value_register = self.allocate_register(); - self.array_get(vector.pointer, index_at_end_of_array, end_value_register); - - // Write both values - self.array_set(vector.pointer, iterator_register, end_value_register); - self.array_set(vector.pointer, index_at_end_of_array, start_value_register); - // Increment the index register - self.usize_op_in_place(iterator_register, BinaryIntOp::Add, 1); - - self.jump_instruction(loop_label); - - // Exit the loop - self.enter_next_section(); + self.loop_instruction(iteration_count, |ctx, iterator_register| { + // Load both values + ctx.array_get(vector.pointer, iterator_register, start_value_register); + + // The index at the end of array is size - 1 - iterator + ctx.mov_instruction(index_at_end_of_array, vector.size); + ctx.usize_op_in_place(index_at_end_of_array, BinaryIntOp::Sub, 1); + ctx.memory_op( + index_at_end_of_array, + iterator_register, + index_at_end_of_array, + BinaryIntOp::Sub, + ); + + ctx.array_get(vector.pointer, index_at_end_of_array, end_value_register); + + // Write both values + ctx.array_set(vector.pointer, iterator_register, end_value_register); + ctx.array_set(vector.pointer, index_at_end_of_array, start_value_register); + }); - // Deallocate our temporary registers - self.deallocate_register(iterator_register); self.deallocate_register(iteration_count); - self.deallocate_register(iterator_less_than_count); self.deallocate_register(start_value_register); self.deallocate_register(end_value_register); self.deallocate_register(index_at_end_of_array); From 0dea654a569f063ba85d4167c4dfe8069017f4af Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 24 Jul 2023 09:36:08 +0000 Subject: [PATCH 3/5] doc: updated comments for radix instructions --- crates/noirc_evaluator/src/brillig/brillig_ir.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/noirc_evaluator/src/brillig/brillig_ir.rs b/crates/noirc_evaluator/src/brillig/brillig_ir.rs index 443df6ee15d..ce371a05647 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_ir.rs @@ -241,6 +241,8 @@ impl BrilligContext { self.deallocate_register(value_register); } + /// This instruction will issue a loop that will iterate iteration_count times + /// The body of the loop should be issued by the caller in the on_iteration closure. fn loop_instruction(&mut self, iteration_count: RegisterIndex, on_iteration: F) where F: FnOnce(&mut BrilligContext, RegisterIndex), @@ -866,6 +868,8 @@ impl BrilligContext { self.push_opcode(BrilligOpcode::BlackBox(op)); } + /// Issues a to_radix instruction. This instruction will write the modulus of the source register + /// And the radix register limb_count times to the target vector. pub(crate) fn radix_instruction( &mut self, source: RegisterIndex, @@ -874,7 +878,6 @@ impl BrilligContext { limb_count: RegisterIndex, big_endian: bool, ) { - // TODO check if it'll fit self.mov_instruction(target_vector.size, limb_count); self.allocate_array_instruction(target_vector.pointer, target_vector.size); @@ -915,7 +918,8 @@ impl BrilligContext { } } - fn reverse_vector_in_place_instruction(&mut self, vector: HeapVector) { + /// This instruction will reverse the order of the elements in a vector. + pub(crate) fn reverse_vector_in_place_instruction(&mut self, vector: HeapVector) { let iteration_count = self.allocate_register(); self.usize_op(vector.size, iteration_count, BinaryIntOp::UnsignedDiv, 2); From 3778ab80beeb5c2e4880110e88c7b97535a20751 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 24 Jul 2023 09:39:20 +0000 Subject: [PATCH 4/5] chore: point to git acvm --- Cargo.lock | 28 +++++++++++++++++++--------- Cargo.toml | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a86efd3980..aea0c119eb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,8 @@ version = 3 [[package]] name = "acir" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269617cfc7050d47915308c2ae20c33642cbfbc5c25097ba10a522539556065b" dependencies = [ "acir_field", "bincode", @@ -18,7 +19,8 @@ dependencies = [ [[package]] name = "acir_field" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ace9d882b85479aa678c7272aa717acdcabe1f4d0cb6236cd17dcda8c4bb32" dependencies = [ "ark-bn254", "ark-ff", @@ -31,7 +33,8 @@ dependencies = [ [[package]] name = "acvm" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5eeabcd9c38133eb860c1ad4c0ced8d0032f9f22b6de0699bddacb69bd772ec" dependencies = [ "acir", "acvm_blackbox_solver", @@ -68,7 +71,8 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e3636cfc0b6a6e6e02a5b813b12941ef0979ec532290ee83587f42d7610dae" dependencies = [ "acir", "blake2", @@ -82,7 +86,8 @@ dependencies = [ [[package]] name = "acvm_stdlib" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fc3882d621cb13af2793e35fff3aa8ba34959c486808e665212d5423835386" dependencies = [ "acir", ] @@ -520,7 +525,8 @@ dependencies = [ [[package]] name = "brillig" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23339a18ea207882da08076a70564b5a44bad80ce2ebb3a46e89172979ae09fb" dependencies = [ "acir_field", "serde", @@ -529,12 +535,11 @@ dependencies = [ [[package]] name = "brillig_vm" version = "0.19.1" -source = "git+https://github.com/noir-lang/acvm?branch=gd/bigger_integer#e148118aaf01b7713f55d932470ae890385923eb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "024f52eb86d8f320cbbf8c2f231acdd84fe2171d3d1926c4bc95d64e933aa23e" dependencies = [ "acir", "acvm_blackbox_solver", - "num-bigint", - "num-traits", ] [[package]] @@ -4217,3 +4222,8 @@ dependencies = [ "quote", "syn 2.0.26", ] + +[[patch.unused]] +name = "acvm" +version = "0.20.0" +source = "git+https://github.com/noir-lang/acvm?rev=ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429#ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429" diff --git a/Cargo.toml b/Cargo.toml index 8084148823d..caf458f06df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,4 +58,4 @@ base64 = "0.21.2" [patch.crates-io] async-lsp = { git = "https://github.com/oxalica/async-lsp", rev = "09dbcc11046f7a188a80137f8d36484d86c78c78" } -acvm = { git = "https://github.com/noir-lang/acvm", branch = "gd/bigger_integer"} +acvm = { git = "https://github.com/noir-lang/acvm", rev = "ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429"} From 0e4daac454a9b5a09de409bb01b6645ea65f9db9 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 24 Jul 2023 09:45:49 +0000 Subject: [PATCH 5/5] chore: update deps --- Cargo.lock | 39 +++++++++++++++++-------------------- Cargo.toml | 3 +-- crates/nargo_cli/Cargo.toml | 2 +- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aea0c119eb3..6c98390a533 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "acir" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269617cfc7050d47915308c2ae20c33642cbfbc5c25097ba10a522539556065b" +checksum = "bb6315da836487843323dc07343365167ca1c5d9005affa1e412a87b74a98ed6" dependencies = [ "acir_field", "bincode", @@ -18,9 +18,9 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ace9d882b85479aa678c7272aa717acdcabe1f4d0cb6236cd17dcda8c4bb32" +checksum = "7aa14cddc3b16bf9e661d830f7209193b27c1b540f2d2d0249182b6436a963c6" dependencies = [ "ark-bn254", "ark-ff", @@ -32,9 +32,9 @@ dependencies = [ [[package]] name = "acvm" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5eeabcd9c38133eb860c1ad4c0ced8d0032f9f22b6de0699bddacb69bd772ec" +checksum = "48bed7a285c69be779c8e07e72e0b146326c4a23a0eaf03725fd089f1337d07c" dependencies = [ "acir", "acvm_blackbox_solver", @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "acvm-backend-barretenberg" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff47ff4fd4ae9c6a606f88f1f67a5b4e382313ae3e99edfdc7403bef4a49972" +checksum = "06094a352644202d2094d2221ae0ebc480af7a755dceb72e6ddda3cd69e406e2" dependencies = [ "acvm", "barretenberg-sys", @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e3636cfc0b6a6e6e02a5b813b12941ef0979ec532290ee83587f42d7610dae" +checksum = "76b6a5c28ccefa5b6e4162995c7b6e250c5e3ae5109b7e19738ae17a35cb545c" dependencies = [ "acir", "blake2", @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "acvm_stdlib" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fc3882d621cb13af2793e35fff3aa8ba34959c486808e665212d5423835386" +checksum = "31b5871d78fbaab07689caeb46f7128da17267d6b1775a831339bca86ca22ff0" dependencies = [ "acir", ] @@ -524,9 +524,9 @@ dependencies = [ [[package]] name = "brillig" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23339a18ea207882da08076a70564b5a44bad80ce2ebb3a46e89172979ae09fb" +checksum = "36139e8a7c0bcc1a5d7638a2851d1315d3256777f3c4f713b4ffd0ccd2770e60" dependencies = [ "acir_field", "serde", @@ -534,12 +534,14 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "024f52eb86d8f320cbbf8c2f231acdd84fe2171d3d1926c4bc95d64e933aa23e" +checksum = "7a8b61359c74d9c1fd5dbb847a0e4950aa7cb8c2de284ab820f9dcffb6db9fd7" dependencies = [ "acir", "acvm_blackbox_solver", + "num-bigint", + "num-traits", ] [[package]] @@ -4222,8 +4224,3 @@ dependencies = [ "quote", "syn 2.0.26", ] - -[[patch.unused]] -name = "acvm" -version = "0.20.0" -source = "git+https://github.com/noir-lang/acvm?rev=ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429#ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429" diff --git a/Cargo.toml b/Cargo.toml index caf458f06df..c29dc739341 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ edition = "2021" rust-version = "1.66" [workspace.dependencies] -acvm = "0.19.1" +acvm = "0.20.0" arena = { path = "crates/arena" } fm = { path = "crates/fm" } iter-extended = { path = "crates/iter-extended" } @@ -58,4 +58,3 @@ base64 = "0.21.2" [patch.crates-io] async-lsp = { git = "https://github.com/oxalica/async-lsp", rev = "09dbcc11046f7a188a80137f8d36484d86c78c78" } -acvm = { git = "https://github.com/noir-lang/acvm", rev = "ceaf5fe4f45ac3d6bf4f5d7657aa7a42dafc5429"} diff --git a/crates/nargo_cli/Cargo.toml b/crates/nargo_cli/Cargo.toml index 0fd2ce19927..9f211604b8f 100644 --- a/crates/nargo_cli/Cargo.toml +++ b/crates/nargo_cli/Cargo.toml @@ -48,7 +48,7 @@ color-eyre = "0.6.2" tokio = { version = "1.0", features = ["io-std"] } # Backends -acvm-backend-barretenberg = { version = "0.9.0", default-features = false } +acvm-backend-barretenberg = { version = "0.9.1", default-features = false } [dev-dependencies] tempdir = "0.3.7"