From f2b2391536b56aea8183831b77f77a65b059a56d Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 1 May 2024 19:56:47 +0000 Subject: [PATCH 1/4] working complex outputs from acir call --- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 4 +- .../fold_complex_outputs/Nargo.toml | 7 ++ .../fold_complex_outputs/Prover.toml | 2 + .../fold_complex_outputs/src/main.nr | 74 +++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 test_programs/execution_success/fold_complex_outputs/Nargo.toml create mode 100644 test_programs/execution_success/fold_complex_outputs/Prover.toml create mode 100644 test_programs/execution_success/fold_complex_outputs/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 10d58f327e5..b5b01256739 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -713,10 +713,9 @@ impl<'a> Context<'a> { assert!(!matches!(inline_type, InlineType::Inline), "ICE: Got an ACIR function named {} that should have already been inlined", func.name()); let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); - // TODO(https://github.com/noir-lang/noir/issues/4608): handle complex return types from ACIR functions let output_count = result_ids.iter().fold(0usize, |sum, result_id| { - sum + dfg.try_get_array_length(*result_id).unwrap_or(1) + sum + dfg.type_of_value(*result_id).flattened_size() }); let acir_function_id = ssa @@ -729,6 +728,7 @@ impl<'a> Context<'a> { output_count, self.current_side_effects_enabled_var, )?; + let output_values = self.convert_vars_to_values(output_vars, dfg, result_ids); diff --git a/test_programs/execution_success/fold_complex_outputs/Nargo.toml b/test_programs/execution_success/fold_complex_outputs/Nargo.toml new file mode 100644 index 00000000000..f00c6520b4a --- /dev/null +++ b/test_programs/execution_success/fold_complex_outputs/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_complex_outputs" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/execution_success/fold_complex_outputs/Prover.toml b/test_programs/execution_success/fold_complex_outputs/Prover.toml new file mode 100644 index 00000000000..a26b97d6471 --- /dev/null +++ b/test_programs/execution_success/fold_complex_outputs/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "3" diff --git a/test_programs/execution_success/fold_complex_outputs/src/main.nr b/test_programs/execution_success/fold_complex_outputs/src/main.nr new file mode 100644 index 00000000000..2daf22d8d25 --- /dev/null +++ b/test_programs/execution_success/fold_complex_outputs/src/main.nr @@ -0,0 +1,74 @@ +struct MyStruct { + x: u32, + y: u32, + z: u32, + nested_struct: InnerStruct +} + +struct InnerStruct { + small_array: [u32; 2], + big_array: [u32; 5], +} + +struct ParentStruct { + basic_array: [Field; 3], + id: u32, + my_structs: [MyStruct; 2], +} + +fn main(x: u32, y: pub u32) { + let nested_struct = InnerStruct { small_array: [1 as u32; 2], big_array: [0 as u32; 5] }; + let s = MyStruct { x, y, z: x + y, nested_struct }; + let parent = ParentStruct { basic_array: [1; 3], id: 100, my_structs: [s, s] }; + let new_parent = map_fields(parent); + assert(new_parent.basic_array[0] == 1); + assert(new_parent.basic_array[1] == 18); + assert(new_parent.basic_array[2] == 1); + + let struct_0 = new_parent.my_structs[0]; + assert(struct_0.x == 5); + assert(struct_0.y == 3); + assert(struct_0.z == 8); + assert(struct_0.nested_struct.small_array == nested_struct.small_array); + assert(struct_0.nested_struct.big_array == nested_struct.big_array); + + let struct_1 = new_parent.my_structs[1]; + assert(struct_1.x == 50); + assert(struct_1.y == 30); + assert(struct_1.z == 80); + assert(struct_1.nested_struct.small_array == [5, 10]); + assert(struct_1.nested_struct.big_array == [15, 20, 25, 30, 35]); + + assert(new_parent.basic_array[1] == 18); + assert(new_parent.basic_array[2] == 1); + +} + +// Meaningless mapping to test whether the values returned are what we expect +#[fold] +fn map_fields(mut input: ParentStruct) -> ParentStruct { + let current_struct = input.my_structs[0]; + let mut sum = 0; + for value in current_struct.nested_struct.small_array { + sum += value; + } + for value in current_struct.nested_struct.big_array { + sum += value; + } + sum += (current_struct.x + current_struct.y + current_struct.z); + + input.basic_array[1] = sum as Field; + + input.my_structs[1].nested_struct.small_array = [5, 10]; + input.my_structs[1].nested_struct.big_array = [15, 20, 25, 30, 35]; + + // LHS input.my_structs[1].x == 50 + input.my_structs[1].x = input.my_structs[1].x * 10; + // LHS input.my_structs[1].y == 30 + input.my_structs[1].y = input.my_structs[1].y * 10; + // LHS input.my_structs[1].x == 80 + input.my_structs[1].z = input.my_structs[1].x + input.my_structs[1].y; + + input +} + From 2948cbfce272cde6b4dc1aeaa886b6f74abfa5da Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 1 May 2024 20:02:32 +0000 Subject: [PATCH 2/4] update comment --- .../execution_success/fold_complex_outputs/src/main.nr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test_programs/execution_success/fold_complex_outputs/src/main.nr b/test_programs/execution_success/fold_complex_outputs/src/main.nr index 2daf22d8d25..309d9747598 100644 --- a/test_programs/execution_success/fold_complex_outputs/src/main.nr +++ b/test_programs/execution_success/fold_complex_outputs/src/main.nr @@ -21,6 +21,8 @@ fn main(x: u32, y: pub u32) { let s = MyStruct { x, y, z: x + y, nested_struct }; let parent = ParentStruct { basic_array: [1; 3], id: 100, my_structs: [s, s] }; let new_parent = map_fields(parent); + + // Now check that the outputs are as we expect them to be assert(new_parent.basic_array[0] == 1); assert(new_parent.basic_array[1] == 18); assert(new_parent.basic_array[2] == 1); @@ -38,10 +40,6 @@ fn main(x: u32, y: pub u32) { assert(struct_1.z == 80); assert(struct_1.nested_struct.small_array == [5, 10]); assert(struct_1.nested_struct.big_array == [15, 20, 25, 30, 35]); - - assert(new_parent.basic_array[1] == 18); - assert(new_parent.basic_array[2] == 1); - } // Meaningless mapping to test whether the values returned are what we expect From 2d86fa713d2c9a62c8cf970f5dc968196d7564d6 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 1 May 2024 20:12:26 +0000 Subject: [PATCH 3/4] debugger ignored tests --- tooling/debugger/ignored-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tooling/debugger/ignored-tests.txt b/tooling/debugger/ignored-tests.txt index cbef395e65c..f2338e85bef 100644 --- a/tooling/debugger/ignored-tests.txt +++ b/tooling/debugger/ignored-tests.txt @@ -22,3 +22,4 @@ no_predicates_numeric_generic_poseidon regression_4709 fold_distinct_return fold_fibonacci +fold_complex_outputs \ No newline at end of file From 9350e085834553674758815d815e73185ed816bd Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 1 May 2024 20:56:49 +0000 Subject: [PATCH 4/4] use iter sum --- compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index b5b01256739..65cd9c05992 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -713,10 +713,10 @@ impl<'a> Context<'a> { assert!(!matches!(inline_type, InlineType::Inline), "ICE: Got an ACIR function named {} that should have already been inlined", func.name()); let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); - let output_count = - result_ids.iter().fold(0usize, |sum, result_id| { - sum + dfg.type_of_value(*result_id).flattened_size() - }); + let output_count = result_ids + .iter() + .map(|result_id| dfg.type_of_value(*result_id).flattened_size()) + .sum(); let acir_function_id = ssa .entry_point_to_generated_index