From ffa567302ead6b3ca59ef5eee2a4a63438a9aa19 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 7 Oct 2024 11:42:26 +0000 Subject: [PATCH 1/5] handle nested arrays in calldata --- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 37 +++++++++++-------- .../src/ssa/function_builder/data_bus.rs | 17 ++++++--- .../databus_composite_calldata/Prover.toml | 10 +++-- .../databus_composite_calldata/src/main.nr | 10 ++--- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 15d72c2ae74..1a547f57bbf 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1316,27 +1316,32 @@ impl<'a> Context<'a> { let block_id = self.ensure_array_is_initialized(array, dfg)?; let results = dfg.instruction_results(instruction); let res_typ = dfg.type_of_value(results[0]); - // Get operations to call-data parameters are replaced by a get to the call-data-bus array - if let Some(call_data) = - self.data_bus.call_data.iter().find(|cd| cd.index_map.contains_key(&array)) - { - let type_size = res_typ.flattened_size(); - let type_size = self.acir_context.add_constant(FieldElement::from(type_size as i128)); - let offset = self.acir_context.mul_var(var_index, type_size)?; + let call_data = + self.data_bus.call_data.iter().find(|cd| cd.index_map.contains_key(&array)).cloned(); + if let Some(call_data) = call_data { + let call_data_block = self.ensure_array_is_initialized(call_data.array_id, dfg)?; let bus_index = self .acir_context .add_constant(FieldElement::from(call_data.index_map[&array] as i128)); - let new_index = self.acir_context.add_var(offset, bus_index)?; - return self.array_get( - instruction, - call_data.array_id, - new_index, - dfg, - index_side_effect, - ); - } + let type_size = res_typ.flattened_size(); + let mut current_index = self.acir_context.add_var(bus_index, var_index)?; + let mut acir_array = Vector::new(); + for _i in 0..type_size { + let read = + self.array_get_value(&Type::field(), call_data_block, &mut current_index)?; + acir_array.push_back(read); + } + if acir_array.len() == 1 { + self.define_result(dfg, instruction, acir_array[0].clone()); + return Ok(acir_array[0].clone()); + } else { + let result = AcirValue::Array(acir_array); + self.define_result(dfg, instruction, result.clone()); + return Ok(result); + } + } // Compiler sanity check assert!( !res_typ.contains_slice_element(), diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs b/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs index 61dfa096fce..05d9a28e22a 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs @@ -122,15 +122,20 @@ impl FunctionBuilder { } Type::Array(typ, len) => { databus.map.insert(value, databus.index); - for i in 0..len { - for (subitem_index, subitem_typ) in typ.iter().enumerate() { - let index = i * typ.len() + subitem_index; - // load each element of the array - let index = self + + let mut index = 0; + for _i in 0..len { + for subitem_typ in typ.iter() { + // load each element of the array, and add it to the databus + let index_var = self .current_function .dfg .make_constant(FieldElement::from(index as i128), Type::length_type()); - let element = self.insert_array_get(value, index, subitem_typ.clone()); + let element = self.insert_array_get(value, index_var, subitem_typ.clone()); + index += match subitem_typ { + Type::Array(_, _) | Type::Slice(_) => subitem_typ.element_size(), + _ => 1, + }; self.add_to_data_bus(element, databus); } } diff --git a/test_programs/execution_success/databus_composite_calldata/Prover.toml b/test_programs/execution_success/databus_composite_calldata/Prover.toml index ff173cc70cd..1881b9f6468 100644 --- a/test_programs/execution_success/databus_composite_calldata/Prover.toml +++ b/test_programs/execution_success/databus_composite_calldata/Prover.toml @@ -1,9 +1,11 @@ zero = "0" one = "1" +values = [[["12", "33"], ["30", "11"]],[["14", "33"], ["30", "10"]],[["10", "30"], ["30", "10"]]] + [[foos]] -x = "27" -y = "40" +x = 1 +y = [1,2,3,4,5,6,7,8,9,0] [[foos]] -x = "28" -y = "42" +x = 2 +y = [1,2,3,5,6,8,7,8,9,0] \ No newline at end of file diff --git a/test_programs/execution_success/databus_composite_calldata/src/main.nr b/test_programs/execution_success/databus_composite_calldata/src/main.nr index c4da253cbce..dd2753195a7 100644 --- a/test_programs/execution_success/databus_composite_calldata/src/main.nr +++ b/test_programs/execution_success/databus_composite_calldata/src/main.nr @@ -1,11 +1,11 @@ struct Foo { x: u32, - y: u32, + y: [u32; 10], } -fn main(foos: call_data(0) [Foo; 2], zero: u32, one: u32) -> return_data u32 { +fn main(foos: call_data(0) [Foo; 2], values: call_data(0) [[[u32; 2]; 2]; 3], zero: u32, one: u32) -> pub u32 { assert_eq(foos[zero].x + 1, foos[one].x); - assert_eq(foos[zero].y + 2, foos[one].y); - foos[zero].x + foos[one].y + assert_eq(foos[zero].y[3] + 2, foos[one].y[4]); + assert_eq(values[zero][one][zero], values[one][zero][one]); + foos[zero].x + foos[one].y[0] } - From 6f3d405884a0fe4f5b54df49688747dd7cf57fbc Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 7 Oct 2024 12:58:44 +0000 Subject: [PATCH 2/5] nargo fmt --- .../databus_composite_calldata/src/main.nr | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test_programs/execution_success/databus_composite_calldata/src/main.nr b/test_programs/execution_success/databus_composite_calldata/src/main.nr index dd2753195a7..e8b88e84d0d 100644 --- a/test_programs/execution_success/databus_composite_calldata/src/main.nr +++ b/test_programs/execution_success/databus_composite_calldata/src/main.nr @@ -3,7 +3,12 @@ struct Foo { y: [u32; 10], } -fn main(foos: call_data(0) [Foo; 2], values: call_data(0) [[[u32; 2]; 2]; 3], zero: u32, one: u32) -> pub u32 { +fn main( + foos: call_data(0) [Foo; 2], + values: call_data(0) [[[u32; 2]; 2]; 3], + zero: u32, + one: u32 +) -> pub u32 { assert_eq(foos[zero].x + 1, foos[one].x); assert_eq(foos[zero].y[3] + 2, foos[one].y[4]); assert_eq(values[zero][one][zero], values[one][zero][one]); From b37573cdd7592fe2a2ba2f14b867b24c1bc6339c Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 7 Oct 2024 14:46:55 +0000 Subject: [PATCH 3/5] handle any nest level --- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 46 ++++++++++++------- .../databus_composite_calldata/Prover.toml | 2 +- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 1a547f57bbf..7fa85049f46 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1303,6 +1303,32 @@ impl<'a> Context<'a> { } } + /// Returns the acir value at the provided databus offset + fn get_from_call_data( + &mut self, + offset: &mut AcirVar, + call_data_block: BlockId, + typ: &Type, + ) -> Result { + match typ { + Type::Numeric(_) => { + self.array_get_value(&Type::field(), call_data_block, offset) + } + Type::Array(arc, len) => { + let mut result = Vector::new(); + for _i in 0..*len { + for sub_type in arc.iter() { + let element = + self.get_from_call_data(offset, call_data_block, sub_type)?; + result.push_back(element); + } + } + Ok(AcirValue::Array(result)) + } + _ => unimplemented!("Unsupported type in databus"), + } + } + /// Generates a read opcode for the array /// `index_side_effect == false` means that we ensured `var_index` will have a type matching the value in the array fn array_get( @@ -1324,23 +1350,11 @@ impl<'a> Context<'a> { let bus_index = self .acir_context .add_constant(FieldElement::from(call_data.index_map[&array] as i128)); - let type_size = res_typ.flattened_size(); let mut current_index = self.acir_context.add_var(bus_index, var_index)?; - let mut acir_array = Vector::new(); - for _i in 0..type_size { - let read = - self.array_get_value(&Type::field(), call_data_block, &mut current_index)?; - acir_array.push_back(read); - } - - if acir_array.len() == 1 { - self.define_result(dfg, instruction, acir_array[0].clone()); - return Ok(acir_array[0].clone()); - } else { - let result = AcirValue::Array(acir_array); - self.define_result(dfg, instruction, result.clone()); - return Ok(result); - } + let result = + self.get_from_call_data(&mut current_index, call_data_block, &res_typ)?; + self.define_result(dfg, instruction, result.clone()); + return Ok(result); } // Compiler sanity check assert!( diff --git a/test_programs/execution_success/databus_composite_calldata/Prover.toml b/test_programs/execution_success/databus_composite_calldata/Prover.toml index 1881b9f6468..ab154c13372 100644 --- a/test_programs/execution_success/databus_composite_calldata/Prover.toml +++ b/test_programs/execution_success/databus_composite_calldata/Prover.toml @@ -1,6 +1,6 @@ zero = "0" one = "1" -values = [[["12", "33"], ["30", "11"]],[["14", "33"], ["30", "10"]],[["10", "30"], ["30", "10"]]] +values = [[["12", "33"], ["37", "11"]],[["14", "37"], ["30", "10"]],[["10", "30"], ["30", "10"]]] [[foos]] x = 1 From b3b022a008686e06eeb939bb7feebe3bdfff8745 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 7 Oct 2024 14:51:18 +0000 Subject: [PATCH 4/5] format --- compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 7fa85049f46..b560fafd337 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1311,15 +1311,12 @@ impl<'a> Context<'a> { typ: &Type, ) -> Result { match typ { - Type::Numeric(_) => { - self.array_get_value(&Type::field(), call_data_block, offset) - } + Type::Numeric(_) => self.array_get_value(&Type::field(), call_data_block, offset), Type::Array(arc, len) => { let mut result = Vector::new(); for _i in 0..*len { for sub_type in arc.iter() { - let element = - self.get_from_call_data(offset, call_data_block, sub_type)?; + let element = self.get_from_call_data(offset, call_data_block, sub_type)?; result.push_back(element); } } @@ -1351,8 +1348,7 @@ impl<'a> Context<'a> { .acir_context .add_constant(FieldElement::from(call_data.index_map[&array] as i128)); let mut current_index = self.acir_context.add_var(bus_index, var_index)?; - let result = - self.get_from_call_data(&mut current_index, call_data_block, &res_typ)?; + let result = self.get_from_call_data(&mut current_index, call_data_block, &res_typ)?; self.define_result(dfg, instruction, result.clone()); return Ok(result); } From fe7145161e7df3d5fe1dd4b0835cf498c6496d1b Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 7 Oct 2024 17:21:39 +0000 Subject: [PATCH 5/5] code review --- compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs b/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs index 05d9a28e22a..de9ae8a24d7 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs @@ -134,7 +134,8 @@ impl FunctionBuilder { let element = self.insert_array_get(value, index_var, subitem_typ.clone()); index += match subitem_typ { Type::Array(_, _) | Type::Slice(_) => subitem_typ.element_size(), - _ => 1, + Type::Numeric(_) => 1, + _ => unreachable!("Unsupported type for databus"), }; self.add_to_data_bus(element, databus); }