From 0b36119f8a3216267166c7b73ae68896e8c16e67 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 22 Sep 2025 13:01:27 -0300 Subject: [PATCH 01/18] add reference countin for circuit_outputs --- src/libfuncs/circuit.rs | 5 +-- src/types/circuit.rs | 80 +++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 5781c7a1a..ef2078f6c 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -397,6 +397,7 @@ fn build_eval<'ctx, 'this>( // Build output struct let outputs_type_id = &info.branch_signatures()[0].vars[2].ty; + let ref_count = entry.const_int(context, location, 1, 8)?; let outputs = build_struct_value( context, registry, @@ -405,7 +406,7 @@ fn build_eval<'ctx, 'this>( helper, metadata, outputs_type_id, - &[outputs_ptr, modulus_struct], + &[ref_count, outputs_ptr, modulus_struct], )?; helper.br(ok_block, 0, &[add_mod, mul_mod, outputs], location)?; @@ -919,7 +920,7 @@ fn build_get_output<'ctx, 'this>( location, outputs, llvm::r#type::pointer(context, 0), - 0, + 1, )?; let modulus_struct = entry.extract_value( context, diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 5cb616334..3ca83807b 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -21,7 +21,7 @@ use cairo_lang_sierra::{ program_registry::ProgramRegistry, }; use melior::{ - dialect::{func, llvm}, + dialect::{arith::CmpiPredicate, func, llvm, scf}, helpers::{ArithBlockExt, BuiltinBlockExt, LlvmBlockExt}, ir::{r#type::IntegerType, Block, BlockLike, Location, Module, Region, Type, Value}, Context, @@ -302,14 +302,7 @@ pub fn build_circuit_outputs<'ctx>( metadata: &mut MetadataStorage, info: WithSelf, ) -> Result> { - let Some(GenericArg::Type(circuit_type_id)) = info.info.long_id.generic_args.first() else { - return Err(SierraAssertError::BadTypeInfo.into()); - }; - let CoreTypeConcrete::Circuit(CircuitTypeConcrete::Circuit(circuit)) = - registry.get_type(circuit_type_id)? - else { - return Err(SierraAssertError::BadTypeInfo.into()); - }; + let u8_ty = IntegerType::new(context, 8).into(); DupOverridesMeta::register_with( context, @@ -322,29 +315,15 @@ pub fn build_circuit_outputs<'ctx>( let region = Region::new(); let value_ty = registry.build_type(context, module, metadata, info.self_ty())?; let entry = region.append_block(Block::new(&[(value_ty, location)])); + let k1 = entry.const_int(context, location, 1, 8)?; let outputs = entry.arg(0)?; - let gates_ptr = entry.extract_value( - context, - location, - outputs, - llvm::r#type::pointer(context, 0), - 0, - )?; + let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?; + let ref_count_inc = entry.addi(ref_count, k1, location)?; - let u384_integer_layout = get_integer_layout(384); - - let new_gates_ptr = build_array_dup( - context, - &entry, - location, - gates_ptr, - circuit.circuit_info.values.len(), - u384_integer_layout, - )?; + entry.insert_value(context, location, outputs, ref_count_inc, 0)?; - let new_outputs = entry.insert_value(context, location, outputs, new_gates_ptr, 0)?; - entry.append_operation(func::r#return(&[outputs, new_outputs], location)); + entry.append_operation(func::r#return(&[outputs, outputs], location)); Ok(Some(region)) }, @@ -360,9 +339,10 @@ pub fn build_circuit_outputs<'ctx>( let region = Region::new(); let value_ty = registry.build_type(context, module, metadata, info.self_ty())?; let entry = region.append_block(Block::new(&[(value_ty, location)])); + let k1 = entry.const_int(context, location, 1, 8)?; let outputs = entry.arg(0)?; - let gates_ptr = entry.extract_value( + let ref_count = entry.extract_value( context, location, outputs, @@ -370,7 +350,46 @@ pub fn build_circuit_outputs<'ctx>( 0, )?; - entry.append_operation(ReallocBindingsMeta::free(context, gates_ptr, location)?); + // Check that the reference counting is different from 1. If it is equeal to 1, then it is shared. + let is_shared = entry.cmpi(context, CmpiPredicate::Ne, ref_count, k1, location)?; + + entry.append_operation(scf::r#if( + is_shared, + &[], + { + // If it is shared then decrement the reference counting. + let region = Region::new(); + let entry = region.append_block(Block::new(&[])); + let ref_count_dec = entry.subi(ref_count, k1, location)?; + + entry.insert_value(context, location, ref_count_dec, outputs, 0)?; + + entry.append_operation(scf::r#yield(&[], location)); + + region + }, + { + // If it is not shared then free the memory. + let region = Region::new(); + let entry = region.append_block(Block::new(&[])); + + let gates_ptr = entry.extract_value( + context, + location, + outputs, + llvm::r#type::pointer(context, 0), + 1, + )?; + + entry + .append_operation(ReallocBindingsMeta::free(context, gates_ptr, location)?); + entry.append_operation(scf::r#yield(&[], location)); + + region + }, + location, + )); + entry.append_operation(func::r#return(&[], location)); Ok(Some(region)) @@ -380,6 +399,7 @@ pub fn build_circuit_outputs<'ctx>( Ok(llvm::r#type::r#struct( context, &[ + u8_ty, llvm::r#type::pointer(context, 0), build_u384_struct_type(context), ], From 8292458f0fe763f150a63f65cba542dab63a9857 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 22 Sep 2025 14:46:51 -0300 Subject: [PATCH 02/18] fix no terminator error --- src/libfuncs/circuit.rs | 2 +- src/types/circuit.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index ef2078f6c..3449b72ef 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -397,7 +397,7 @@ fn build_eval<'ctx, 'this>( // Build output struct let outputs_type_id = &info.branch_signatures()[0].vars[2].ty; - let ref_count = entry.const_int(context, location, 1, 8)?; + let ref_count = ok_block.const_int(context, location, 1, 8)?; let outputs = build_struct_value( context, registry, diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 3ca83807b..5cce91404 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -346,7 +346,7 @@ pub fn build_circuit_outputs<'ctx>( context, location, outputs, - llvm::r#type::pointer(context, 0), + u8_ty, 0, )?; From 90bee166dcaf3e010e1462d36c68f26ccd97446d Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 22 Sep 2025 14:56:42 -0300 Subject: [PATCH 03/18] some comments --- src/libfuncs/circuit.rs | 6 +----- src/types/circuit.rs | 5 ++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 3449b72ef..4451ae30f 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -927,7 +927,7 @@ fn build_get_output<'ctx, 'this>( location, outputs, build_u384_struct_type(context), - 1, + 2, )?; let output_integer_ptr = entry.gep( @@ -953,10 +953,6 @@ fn build_get_output<'ctx, 'this>( )?; // We drop the circuit outputs value, as its consumed by this libfunc. - // NOTE: As this libfunc consumes circuit_outputs, this implies that - // calling it multiple times involves duplicating the circuit outputs - // each time. This could be fixed by implementing a reference counter, - // like we do with regular arrays. if let Some(drop_overrides_meta) = metadata.get::() { drop_overrides_meta.invoke_override( context, diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 5cce91404..946507360 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -278,12 +278,15 @@ pub fn build_circuit_data<'ctx>( /// /// ## Layout: /// -/// Holds the evaluated circuit output gates and the circuit modulus. +/// Holds the reference count, the evaluated circuit output gates and the circuit modulus. +/// - The reference count is stored as a u8. Tells the amount of currently alived references +/// to the output value. /// - The data is stored as a dynamic array of u384 integers. /// - The modulus is stored as a u384 in struct form (multi-limb). /// /// ```txt /// type = struct { +/// reference_count: u8, /// data: *u384, /// modulus: u384struct, /// }; From aa46b9a491953466896c1adc148c24be7b8fb227 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 22 Sep 2025 15:29:04 -0300 Subject: [PATCH 04/18] increment ref count correctly --- src/types/circuit.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 946507360..78636b4ab 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -324,9 +324,9 @@ pub fn build_circuit_outputs<'ctx>( let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?; let ref_count_inc = entry.addi(ref_count, k1, location)?; - entry.insert_value(context, location, outputs, ref_count_inc, 0)?; + let output_new = entry.insert_value(context, location, outputs, ref_count_inc, 0)?; - entry.append_operation(func::r#return(&[outputs, outputs], location)); + entry.append_operation(func::r#return(&[output_new, output_new], location)); Ok(Some(region)) }, @@ -345,13 +345,7 @@ pub fn build_circuit_outputs<'ctx>( let k1 = entry.const_int(context, location, 1, 8)?; let outputs = entry.arg(0)?; - let ref_count = entry.extract_value( - context, - location, - outputs, - u8_ty, - 0, - )?; + let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?; // Check that the reference counting is different from 1. If it is equeal to 1, then it is shared. let is_shared = entry.cmpi(context, CmpiPredicate::Ne, ref_count, k1, location)?; From 5dadf3933f1933829c0605eb9737233950a53510 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 13:17:41 -0300 Subject: [PATCH 05/18] use ref count in the allocation pointer --- Cargo.toml | 1 + src/libfuncs/circuit.rs | 46 ++++++++++++++------ src/types/circuit.rs | 96 +++++++++++++++++++++++++++++++---------- 3 files changed, 108 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ecf0d0a1b..183ec262d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ repository.workspace = true resolver = "2" [features] +default = ["with-debug-utils"] with-cheatcode = [] with-debug-utils = [] with-mem-tracing = [] diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 4451ae30f..0d8f72fb8 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -8,11 +8,13 @@ use crate::{ execution_result::{ADD_MOD_BUILTIN_SIZE, MUL_MOD_BUILTIN_SIZE, RANGE_CHECK96_BUILTIN_SIZE}, libfuncs::r#struct::build_struct_value, metadata::{ - drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, - runtime_bindings::RuntimeBindingsMeta, MetadataStorage, + debug_utils::DebugUtils, drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, runtime_bindings::RuntimeBindingsMeta, MetadataStorage }, native_panic, - types::{circuit::build_u384_struct_type, TypeBuilder}, + types::{ + circuit::{build_u384_struct_type, calc_circuit_output_prefix_layout}, + TypeBuilder, + }, utils::{get_integer_layout, layout_repeat, ProgramRegistryExt}, }; use cairo_lang_sierra::{ @@ -363,13 +365,15 @@ fn build_eval<'ctx, 'this>( circuit_info.mul_offsets.len() * MUL_MOD_BUILTIN_SIZE, )?; - // Calculate capacity for array. let outputs_capacity = circuit_info.values.len(); let u384_integer_layout = get_integer_layout(384); - let outputs_layout = layout_repeat(&u384_integer_layout, outputs_capacity)?.0; - let outputs_capacity_bytes = outputs_layout.pad_to_align().size(); + let outputs_prefix_layout = calc_circuit_output_prefix_layout(); + let outputs_layout = outputs_prefix_layout + .extend(layout_repeat(&u384_integer_layout, outputs_capacity)?.0)? + .0 + .pad_to_align(); let outputs_capacity_bytes_value = - ok_block.const_int(context, location, outputs_capacity_bytes, 64)?; + ok_block.const_int(context, location, outputs_layout.size(), 64)?; // Alloc memory for array. let ptr_ty = llvm::r#type::pointer(context, 0); @@ -381,13 +385,19 @@ fn build_eval<'ctx, 'this>( location, )?)?; + // Insert initial reference count, equal to 1. + let k1 = ok_block.const_int(context, location, 1, 32)?; + ok_block.store(context, location, outputs_ptr, k1)?; + // Insert evaluated gates into the array. for (i, gate) in gates.into_iter().enumerate() { let value_ptr = ok_block.gep( context, location, outputs_ptr, - &[GepIndex::Const(i as i32)], + &[GepIndex::Const( + outputs_prefix_layout.size() as i32 + i as i32, + )], IntegerType::new(context, 384).into(), )?; ok_block.store(context, location, value_ptr, gate)?; @@ -397,7 +407,6 @@ fn build_eval<'ctx, 'this>( // Build output struct let outputs_type_id = &info.branch_signatures()[0].vars[2].ty; - let ref_count = ok_block.const_int(context, location, 1, 8)?; let outputs = build_struct_value( context, registry, @@ -406,7 +415,7 @@ fn build_eval<'ctx, 'this>( helper, metadata, outputs_type_id, - &[ref_count, outputs_ptr, modulus_struct], + &[outputs_ptr, modulus_struct], )?; helper.br(ok_block, 0, &[add_mod, mul_mod, outputs], location)?; @@ -920,23 +929,34 @@ fn build_get_output<'ctx, 'this>( location, outputs, llvm::r#type::pointer(context, 0), - 1, + 0, )?; let modulus_struct = entry.extract_value( context, location, outputs, build_u384_struct_type(context), - 2, + 1, )?; + let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size(); + metadata + .get_mut::() + .unwrap() + .debug_print(context, helper.module, &entry, "AFTER OUTPUT", location)?; let output_integer_ptr = entry.gep( context, location, circuit_ptr, - &[GepIndex::Const(output_idx as i32)], + &[GepIndex::Const( + circuit_output_prefix_offset as i32 + output_idx as i32, + )], u384_type, )?; + metadata + .get_mut::() + .unwrap() + .debug_print(context, helper.module, &entry, "BEFORE OUTPUT", location)?; let output_integer = entry.load(context, location, output_integer_ptr, u384_type)?; let output_struct = u384_integer_to_struct(context, entry, location, output_integer)?; diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 78636b4ab..c07064635 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -6,8 +6,8 @@ use super::WithSelf; use crate::{ error::{Result, SierraAssertError}, metadata::{ - drop_overrides::DropOverridesMeta, dup_overrides::DupOverridesMeta, - realloc_bindings::ReallocBindingsMeta, MetadataStorage, + debug_utils::DebugUtils, drop_overrides::DropOverridesMeta, + dup_overrides::DupOverridesMeta, realloc_bindings::ReallocBindingsMeta, MetadataStorage, }, utils::{get_integer_layout, layout_repeat, ProgramRegistryExt}, }; @@ -22,7 +22,7 @@ use cairo_lang_sierra::{ }; use melior::{ dialect::{arith::CmpiPredicate, func, llvm, scf}, - helpers::{ArithBlockExt, BuiltinBlockExt, LlvmBlockExt}, + helpers::{ArithBlockExt, BuiltinBlockExt, GepIndex, LlvmBlockExt}, ir::{r#type::IntegerType, Block, BlockLike, Location, Module, Region, Type, Value}, Context, }; @@ -305,8 +305,6 @@ pub fn build_circuit_outputs<'ctx>( metadata: &mut MetadataStorage, info: WithSelf, ) -> Result> { - let u8_ty = IntegerType::new(context, 8).into(); - DupOverridesMeta::register_with( context, module, @@ -318,15 +316,42 @@ pub fn build_circuit_outputs<'ctx>( let region = Region::new(); let value_ty = registry.build_type(context, module, metadata, info.self_ty())?; let entry = region.append_block(Block::new(&[(value_ty, location)])); - let k1 = entry.const_int(context, location, 1, 8)?; + let k1 = entry.const_int(context, location, 1, 32)?; let outputs = entry.arg(0)?; - let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?; + let gates_ptr = entry.extract_value( + context, + location, + outputs, + llvm::r#type::pointer(context, 0), + 0, + )?; + let ref_count_ptr = entry.gep( + context, + location, + gates_ptr, + &[GepIndex::Const(0)], + IntegerType::new(context, 8).into(), + )?; + let ref_count = entry.load( + context, + location, + ref_count_ptr, + IntegerType::new(context, 32).into(), + )?; let ref_count_inc = entry.addi(ref_count, k1, location)?; - let output_new = entry.insert_value(context, location, outputs, ref_count_inc, 0)?; + metadata + .get_mut::() + .unwrap() + .debug_print(context, module, &entry, "DUP", location)?; + metadata + .get_mut::() + .unwrap() + .print_i32(context, module, &entry, ref_count, location)?; - entry.append_operation(func::r#return(&[output_new, output_new], location)); + entry.store(context, location, ref_count_ptr, ref_count_inc)?; + entry.append_operation(func::r#return(&[outputs, outputs], location)); Ok(Some(region)) }, @@ -342,14 +367,43 @@ pub fn build_circuit_outputs<'ctx>( let region = Region::new(); let value_ty = registry.build_type(context, module, metadata, info.self_ty())?; let entry = region.append_block(Block::new(&[(value_ty, location)])); - let k1 = entry.const_int(context, location, 1, 8)?; + let k1 = entry.const_int(context, location, 1, 32)?; let outputs = entry.arg(0)?; - let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?; + let gates_ptr = entry.extract_value( + context, + location, + outputs, + llvm::r#type::pointer(context, 0), + 0, + )?; + + let ref_count_ptr = entry.gep( + context, + location, + gates_ptr, + &[GepIndex::Const(0)], + IntegerType::new(context, 8).into(), + )?; + let ref_count = entry.load( + context, + location, + ref_count_ptr, + IntegerType::new(context, 32).into(), + )?; // Check that the reference counting is different from 1. If it is equeal to 1, then it is shared. let is_shared = entry.cmpi(context, CmpiPredicate::Ne, ref_count, k1, location)?; + metadata + .get_mut::() + .unwrap() + .debug_print(context, module, &entry, "DROP", location)?; + metadata + .get_mut::() + .unwrap() + .print_i32(context, module, &entry, ref_count, location)?; + entry.append_operation(scf::r#if( is_shared, &[], @@ -359,8 +413,7 @@ pub fn build_circuit_outputs<'ctx>( let entry = region.append_block(Block::new(&[])); let ref_count_dec = entry.subi(ref_count, k1, location)?; - entry.insert_value(context, location, ref_count_dec, outputs, 0)?; - + entry.store(context, location, ref_count_ptr, ref_count_dec)?; entry.append_operation(scf::r#yield(&[], location)); region @@ -370,14 +423,6 @@ pub fn build_circuit_outputs<'ctx>( let region = Region::new(); let entry = region.append_block(Block::new(&[])); - let gates_ptr = entry.extract_value( - context, - location, - outputs, - llvm::r#type::pointer(context, 0), - 1, - )?; - entry .append_operation(ReallocBindingsMeta::free(context, gates_ptr, location)?); entry.append_operation(scf::r#yield(&[], location)); @@ -396,7 +441,6 @@ pub fn build_circuit_outputs<'ctx>( Ok(llvm::r#type::r#struct( context, &[ - u8_ty, llvm::r#type::pointer(context, 0), build_u384_struct_type(context), ], @@ -546,3 +590,11 @@ pub fn build_u384_struct_type(context: &Context) -> Type<'_> { false, ) } + +pub fn calc_circuit_output_prefix_layout() -> Layout { + let u384_layout = get_integer_layout(384); + get_integer_layout(32) + .align_to(u384_layout.align()) + .expect("layout size rounded up to the next multiple of layout alignment should never be greater than ISIZE::MAX") + .pad_to_align() +} From 4e1a420433e8cad6f19cfbde100fcabace1e04f8 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 13:50:39 -0300 Subject: [PATCH 06/18] fix invalid memory error --- src/libfuncs/circuit.rs | 25 ++++++++++--------------- src/types/circuit.rs | 22 ++-------------------- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 0d8f72fb8..aa890cd6a 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -8,7 +8,8 @@ use crate::{ execution_result::{ADD_MOD_BUILTIN_SIZE, MUL_MOD_BUILTIN_SIZE, RANGE_CHECK96_BUILTIN_SIZE}, libfuncs::r#struct::build_struct_value, metadata::{ - debug_utils::DebugUtils, drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, runtime_bindings::RuntimeBindingsMeta, MetadataStorage + drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, + runtime_bindings::RuntimeBindingsMeta, MetadataStorage, }, native_panic, types::{ @@ -365,11 +366,11 @@ fn build_eval<'ctx, 'this>( circuit_info.mul_offsets.len() * MUL_MOD_BUILTIN_SIZE, )?; - let outputs_capacity = circuit_info.values.len(); - let u384_integer_layout = get_integer_layout(384); + // Calculate capacity for array. + let elem_stride = get_integer_layout(384); let outputs_prefix_layout = calc_circuit_output_prefix_layout(); let outputs_layout = outputs_prefix_layout - .extend(layout_repeat(&u384_integer_layout, outputs_capacity)?.0)? + .extend(layout_repeat(&elem_stride, circuit_info.values.len())?.0)? .0 .pad_to_align(); let outputs_capacity_bytes_value = @@ -396,7 +397,7 @@ fn build_eval<'ctx, 'this>( location, outputs_ptr, &[GepIndex::Const( - outputs_prefix_layout.size() as i32 + i as i32, + outputs_prefix_layout.size() as i32 + elem_stride.size() as i32 * i as i32, )], IntegerType::new(context, 384).into(), )?; @@ -939,24 +940,18 @@ fn build_get_output<'ctx, 'this>( 1, )?; - let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size(); - metadata - .get_mut::() - .unwrap() - .debug_print(context, helper.module, &entry, "AFTER OUTPUT", location)?; + let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size() as i32; + let elem_stride = get_integer_layout(384).size() as i32; let output_integer_ptr = entry.gep( context, location, circuit_ptr, &[GepIndex::Const( - circuit_output_prefix_offset as i32 + output_idx as i32, + circuit_output_prefix_offset + elem_stride * output_idx as i32, )], u384_type, )?; - metadata - .get_mut::() - .unwrap() - .debug_print(context, helper.module, &entry, "BEFORE OUTPUT", location)?; + let output_integer = entry.load(context, location, output_integer_ptr, u384_type)?; let output_struct = u384_integer_to_struct(context, entry, location, output_integer)?; diff --git a/src/types/circuit.rs b/src/types/circuit.rs index c07064635..00ca94f74 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -6,8 +6,8 @@ use super::WithSelf; use crate::{ error::{Result, SierraAssertError}, metadata::{ - debug_utils::DebugUtils, drop_overrides::DropOverridesMeta, - dup_overrides::DupOverridesMeta, realloc_bindings::ReallocBindingsMeta, MetadataStorage, + drop_overrides::DropOverridesMeta, dup_overrides::DupOverridesMeta, + realloc_bindings::ReallocBindingsMeta, MetadataStorage, }, utils::{get_integer_layout, layout_repeat, ProgramRegistryExt}, }; @@ -341,15 +341,6 @@ pub fn build_circuit_outputs<'ctx>( )?; let ref_count_inc = entry.addi(ref_count, k1, location)?; - metadata - .get_mut::() - .unwrap() - .debug_print(context, module, &entry, "DUP", location)?; - metadata - .get_mut::() - .unwrap() - .print_i32(context, module, &entry, ref_count, location)?; - entry.store(context, location, ref_count_ptr, ref_count_inc)?; entry.append_operation(func::r#return(&[outputs, outputs], location)); @@ -395,15 +386,6 @@ pub fn build_circuit_outputs<'ctx>( // Check that the reference counting is different from 1. If it is equeal to 1, then it is shared. let is_shared = entry.cmpi(context, CmpiPredicate::Ne, ref_count, k1, location)?; - metadata - .get_mut::() - .unwrap() - .debug_print(context, module, &entry, "DROP", location)?; - metadata - .get_mut::() - .unwrap() - .print_i32(context, module, &entry, ref_count, location)?; - entry.append_operation(scf::r#if( is_shared, &[], From 9a304737caf1a8a858ea2d1b68739a939683b18b Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 13:53:09 -0300 Subject: [PATCH 07/18] update comments --- src/types/circuit.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 00ca94f74..90aeeb3bd 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -286,8 +286,7 @@ pub fn build_circuit_data<'ctx>( /// /// ```txt /// type = struct { -/// reference_count: u8, -/// data: *u384, +/// data: *void, /// modulus: u384struct, /// }; /// @@ -297,6 +296,10 @@ pub fn build_circuit_data<'ctx>( /// limb3: u96, /// limb4: u96, /// } +/// +/// The allocation pontier, data, contains: +/// * Reference counter. +/// * Circuit outputs. /// ``` pub fn build_circuit_outputs<'ctx>( context: &'ctx Context, From d57de99ccd8d2b81b9143094fc68b218f89ade3e Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 13:55:07 -0300 Subject: [PATCH 08/18] better code --- src/libfuncs/circuit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index aa890cd6a..1678cdb01 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -366,15 +366,15 @@ fn build_eval<'ctx, 'this>( circuit_info.mul_offsets.len() * MUL_MOD_BUILTIN_SIZE, )?; - // Calculate capacity for array. let elem_stride = get_integer_layout(384); + // Calculate capacity for array. let outputs_prefix_layout = calc_circuit_output_prefix_layout(); - let outputs_layout = outputs_prefix_layout + let outputs_capatity_bytes = outputs_prefix_layout .extend(layout_repeat(&elem_stride, circuit_info.values.len())?.0)? .0 - .pad_to_align(); + .pad_to_align().size(); let outputs_capacity_bytes_value = - ok_block.const_int(context, location, outputs_layout.size(), 64)?; + ok_block.const_int(context, location, outputs_capatity_bytes, 64)?; // Alloc memory for array. let ptr_ty = llvm::r#type::pointer(context, 0); From 8cf43bf878c6c98d2760b5f1ccf133addc34cb27 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 13:59:45 -0300 Subject: [PATCH 09/18] update comments --- src/libfuncs/circuit.rs | 3 ++- src/types/circuit.rs | 12 ++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 1678cdb01..b06ed3145 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -372,7 +372,8 @@ fn build_eval<'ctx, 'this>( let outputs_capatity_bytes = outputs_prefix_layout .extend(layout_repeat(&elem_stride, circuit_info.values.len())?.0)? .0 - .pad_to_align().size(); + .pad_to_align() + .size(); let outputs_capacity_bytes_value = ok_block.const_int(context, location, outputs_capatity_bytes, 64)?; diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 90aeeb3bd..fb8ad79cd 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -278,10 +278,10 @@ pub fn build_circuit_data<'ctx>( /// /// ## Layout: /// -/// Holds the reference count, the evaluated circuit output gates and the circuit modulus. -/// - The reference count is stored as a u8. Tells the amount of currently alived references -/// to the output value. -/// - The data is stored as a dynamic array of u384 integers. +/// Holds the evaluated circuit output gates and the circuit modulus. +/// - The data is stored as a dynamic array, which contains: +/// * Reference counter. +/// * Circuit output data (u384s). /// - The modulus is stored as a u384 in struct form (multi-limb). /// /// ```txt @@ -296,10 +296,6 @@ pub fn build_circuit_data<'ctx>( /// limb3: u96, /// limb4: u96, /// } -/// -/// The allocation pontier, data, contains: -/// * Reference counter. -/// * Circuit outputs. /// ``` pub fn build_circuit_outputs<'ctx>( context: &'ctx Context, From 17903b699b6d0a125bf5cd07c99eb6a3b5fd5f90 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 14:13:11 -0300 Subject: [PATCH 10/18] update tracedump --- src/metadata/trace_dump.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 6742d5683..dd250f6bd 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -227,7 +227,7 @@ pub mod trace_dump_runtime { use crate::{ starknet::ArrayAbi, - types::TypeBuilder, + types::{circuit::calc_circuit_output_prefix_layout, TypeBuilder}, utils::{get_integer_layout, layout_repeat}, }; @@ -572,17 +572,21 @@ pub mod trace_dump_runtime { let n_outputs = circuit.circuit_info.values.len(); let mut values = Vec::with_capacity(n_outputs); - let (u384_struct_layout, _) = layout_repeat(&u96_layout, 4).unwrap(); - let (gates_array_layout, gate_stride) = - layout_repeat(&u384_struct_layout, n_outputs).unwrap(); - let (_, modulus_offset) = - gates_array_layout.extend(u384_struct_layout).unwrap(); + let (gate_stride, _) = layout_repeat(&u96_layout, 4).unwrap(); + let outputs_prefix_layout = calc_circuit_output_prefix_layout(); + let gates_array_layout = outputs_prefix_layout + .extend(layout_repeat(&gate_stride, n_outputs).unwrap().0) + .unwrap() + .0 + .pad_to_align(); + let (_, modulus_offset) = gates_array_layout.extend(gate_stride).unwrap(); let value_ptr = value_ptr.cast::<[u8; 12]>(); // get gate values for i in 0..n_outputs { - let gate_ptr = value_ptr.byte_add(gate_stride * i); + let gate_ptr = value_ptr + .byte_add(outputs_prefix_layout.size() + gate_stride.size() * i); values.push(u384_struct_to_bigint(gate_ptr, 4)); } From 49443783810f589065896fd809af2f706595a899 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 17:10:32 -0300 Subject: [PATCH 11/18] add comments --- program.cairo | 29 +++++++++++++++++++++++++++++ src/libfuncs/circuit.rs | 12 ++++++++++-- src/metadata/trace_dump.rs | 3 +-- 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 program.cairo diff --git a/program.cairo b/program.cairo new file mode 100644 index 000000000..14bdff0ac --- /dev/null +++ b/program.cairo @@ -0,0 +1,29 @@ +use core::circuit::{ + CircuitData, CircuitElement, CircuitInput, circuit_add, circuit_sub, circuit_mul, circuit_inverse, + EvalCircuitResult, EvalCircuitTrait, u384, CircuitOutputsTrait, CircuitModulus, into_u96_guarantee, U96Guarantee, + CircuitInputs, AddInputResultTrait, AddInputResult, IntoCircuitInputValue, add_circuit_input + }; +fn main() -> u384 { + let in1 = CircuitElement::> {}; + let in2 = CircuitElement::> {}; + let add1 = circuit_add(in1, in2); + let mul1 = circuit_mul(add1, in1); + let mul2 = circuit_mul(mul1, add1); + let inv1 = circuit_inverse(mul2); + let sub1 = circuit_sub(inv1, in2); + let sub2 = circuit_sub(sub1, mul2); + let inv2 = circuit_inverse(sub2); + let add2 = circuit_add(inv2, inv2); + + let modulus = TryInto::<_, CircuitModulus>::try_into([17, 14, 14, 14]).unwrap(); + + let outputs = (add2,) + .new_inputs() + .next([9, 2, 9, 3]) + .next([5, 7, 0, 8]) + .done() + .eval(modulus) + .unwrap(); + + outputs.get_output(add2) + } diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index b06ed3145..617ac96a4 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -398,7 +398,11 @@ fn build_eval<'ctx, 'this>( location, outputs_ptr, &[GepIndex::Const( - outputs_prefix_layout.size() as i32 + elem_stride.size() as i32 * i as i32, + // The offset is calculated as the prefix, which is the 4 + // bytes from the reference counter plus the extra padding. + // Then, we need to add the element stride time the current + // index. + outputs_prefix_layout.size() as i32 + elem_stride.pad_to_align().size() as i32 * i as i32, )], IntegerType::new(context, 384).into(), )?; @@ -942,12 +946,16 @@ fn build_get_output<'ctx, 'this>( )?; let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size() as i32; - let elem_stride = get_integer_layout(384).size() as i32; + let elem_stride = get_integer_layout(384).pad_to_align().size() as i32; let output_integer_ptr = entry.gep( context, location, circuit_ptr, &[GepIndex::Const( + // The offset is calculated as the prefix, which is the 4 + // bytes from the reference counter plus the extra padding. + // Then, we need to add the element stride time the current + // index. circuit_output_prefix_offset + elem_stride * output_idx as i32, )], u384_type, diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index dd250f6bd..faa6f67d5 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -566,7 +566,6 @@ pub mod trace_dump_runtime { else { panic!("generic arg should be a Circuit"); }; - let u96_layout = get_integer_layout(96); let n_outputs = circuit.circuit_info.values.len(); @@ -586,7 +585,7 @@ pub mod trace_dump_runtime { // get gate values for i in 0..n_outputs { let gate_ptr = value_ptr - .byte_add(outputs_prefix_layout.size() + gate_stride.size() * i); + .byte_add(outputs_prefix_layout.size() + gate_stride.pad_to_align().size() * i); values.push(u384_struct_to_bigint(gate_ptr, 4)); } From ac9f14e44a85ab4b71a0772b71be890a0264af15 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 23 Sep 2025 17:55:13 -0300 Subject: [PATCH 12/18] fmt --- Cargo.toml | 1 - program.cairo | 29 ----------------------------- src/libfuncs/circuit.rs | 7 ++++--- src/metadata/trace_dump.rs | 5 +++-- src/types/circuit.rs | 2 ++ 5 files changed, 9 insertions(+), 35 deletions(-) delete mode 100644 program.cairo diff --git a/Cargo.toml b/Cargo.toml index cfcc81186..1c741ca0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,7 +109,6 @@ repository.workspace = true resolver = "2" [features] -default = ["with-debug-utils"] with-cheatcode = [] with-debug-utils = [] with-mem-tracing = [] diff --git a/program.cairo b/program.cairo deleted file mode 100644 index 14bdff0ac..000000000 --- a/program.cairo +++ /dev/null @@ -1,29 +0,0 @@ -use core::circuit::{ - CircuitData, CircuitElement, CircuitInput, circuit_add, circuit_sub, circuit_mul, circuit_inverse, - EvalCircuitResult, EvalCircuitTrait, u384, CircuitOutputsTrait, CircuitModulus, into_u96_guarantee, U96Guarantee, - CircuitInputs, AddInputResultTrait, AddInputResult, IntoCircuitInputValue, add_circuit_input - }; -fn main() -> u384 { - let in1 = CircuitElement::> {}; - let in2 = CircuitElement::> {}; - let add1 = circuit_add(in1, in2); - let mul1 = circuit_mul(add1, in1); - let mul2 = circuit_mul(mul1, add1); - let inv1 = circuit_inverse(mul2); - let sub1 = circuit_sub(inv1, in2); - let sub2 = circuit_sub(sub1, mul2); - let inv2 = circuit_inverse(sub2); - let add2 = circuit_add(inv2, inv2); - - let modulus = TryInto::<_, CircuitModulus>::try_into([17, 14, 14, 14]).unwrap(); - - let outputs = (add2,) - .new_inputs() - .next([9, 2, 9, 3]) - .next([5, 7, 0, 8]) - .done() - .eval(modulus) - .unwrap(); - - outputs.get_output(add2) - } diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 617ac96a4..5d4a9c65c 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -398,11 +398,12 @@ fn build_eval<'ctx, 'this>( location, outputs_ptr, &[GepIndex::Const( - // The offset is calculated as the prefix, which is the 4 + // The offset is calculated as the prefix, which is the 4 // bytes from the reference counter plus the extra padding. // Then, we need to add the element stride time the current // index. - outputs_prefix_layout.size() as i32 + elem_stride.pad_to_align().size() as i32 * i as i32, + outputs_prefix_layout.size() as i32 + + elem_stride.pad_to_align().size() as i32 * i as i32, )], IntegerType::new(context, 384).into(), )?; @@ -952,7 +953,7 @@ fn build_get_output<'ctx, 'this>( location, circuit_ptr, &[GepIndex::Const( - // The offset is calculated as the prefix, which is the 4 + // The offset is calculated as the prefix, which is the 4 // bytes from the reference counter plus the extra padding. // Then, we need to add the element stride time the current // index. diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index faa6f67d5..10a72fcfc 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -584,8 +584,9 @@ pub mod trace_dump_runtime { // get gate values for i in 0..n_outputs { - let gate_ptr = value_ptr - .byte_add(outputs_prefix_layout.size() + gate_stride.pad_to_align().size() * i); + let gate_ptr = value_ptr.byte_add( + outputs_prefix_layout.size() + gate_stride.pad_to_align().size() * i, + ); values.push(u384_struct_to_bigint(gate_ptr, 4)); } diff --git a/src/types/circuit.rs b/src/types/circuit.rs index fb8ad79cd..e76d66c97 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -406,6 +406,7 @@ pub fn build_circuit_outputs<'ctx>( entry .append_operation(ReallocBindingsMeta::free(context, gates_ptr, location)?); + entry.append_operation(scf::r#yield(&[], location)); region @@ -462,6 +463,7 @@ pub fn build_array_dup<'ctx, 'this>( let new_inputs_ptr = { let ptr_ty = llvm::r#type::pointer(context, 0); let new_inputs_ptr = block.append_op_result(llvm::zero(ptr_ty, location))?; + block.append_op_result(ReallocBindingsMeta::realloc( context, new_inputs_ptr, From ce033dfaa60084713cd791d680d3c72dd0896627 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 24 Sep 2025 12:39:58 -0300 Subject: [PATCH 13/18] fix pointer offseting --- src/libfuncs/circuit.rs | 56 +++++++++++++++++++++-------------------- src/types/circuit.rs | 23 +++-------------- 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 5d4a9c65c..16a8a48c0 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -366,16 +366,13 @@ fn build_eval<'ctx, 'this>( circuit_info.mul_offsets.len() * MUL_MOD_BUILTIN_SIZE, )?; - let elem_stride = get_integer_layout(384); + let u384_layout = get_integer_layout(384); // Calculate capacity for array. - let outputs_prefix_layout = calc_circuit_output_prefix_layout(); - let outputs_capatity_bytes = outputs_prefix_layout - .extend(layout_repeat(&elem_stride, circuit_info.values.len())?.0)? - .0 - .pad_to_align() - .size(); + let (data_layout, elem_stride) = layout_repeat(&u384_layout, circuit_info.values.len())?; + let (outputs_layout, data_start_offset) = + calc_circuit_output_prefix_layout().extend(data_layout)?; let outputs_capacity_bytes_value = - ok_block.const_int(context, location, outputs_capatity_bytes, 64)?; + ok_block.const_int(context, location, outputs_layout.pad_to_align().size(), 64)?; // Alloc memory for array. let ptr_ty = llvm::r#type::pointer(context, 0); @@ -391,20 +388,23 @@ fn build_eval<'ctx, 'this>( let k1 = ok_block.const_int(context, location, 1, 32)?; ok_block.store(context, location, outputs_ptr, k1)?; + let data_ptr = ok_block.gep( + context, + location, + outputs_ptr, + &[GepIndex::Const( + data_start_offset as i32, + )], + IntegerType::new(context, 8).into(), + )?; + // Insert evaluated gates into the array. for (i, gate) in gates.into_iter().enumerate() { let value_ptr = ok_block.gep( context, location, - outputs_ptr, - &[GepIndex::Const( - // The offset is calculated as the prefix, which is the 4 - // bytes from the reference counter plus the extra padding. - // Then, we need to add the element stride time the current - // index. - outputs_prefix_layout.size() as i32 - + elem_stride.pad_to_align().size() as i32 * i as i32, - )], + data_ptr, + &[GepIndex::Const(i as i32)], IntegerType::new(context, 384).into(), )?; ok_block.store(context, location, value_ptr, gate)?; @@ -946,19 +946,21 @@ fn build_get_output<'ctx, 'this>( 1, )?; - let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size() as i32; - let elem_stride = get_integer_layout(384).pad_to_align().size() as i32; - let output_integer_ptr = entry.gep( + let data_start_offset = calc_circuit_output_prefix_layout().size() as i32; + let elem_stride = get_integer_layout(384).size() as i32; + + let data_ptr = entry.gep( context, location, circuit_ptr, - &[GepIndex::Const( - // The offset is calculated as the prefix, which is the 4 - // bytes from the reference counter plus the extra padding. - // Then, we need to add the element stride time the current - // index. - circuit_output_prefix_offset + elem_stride * output_idx as i32, - )], + &[GepIndex::Const(data_start_offset)], + IntegerType::new(context, 8).into(), + )?; + let output_integer_ptr = entry.gep( + context, + location, + data_ptr, + &[GepIndex::Const(output_idx as i32)], u384_type, )?; diff --git a/src/types/circuit.rs b/src/types/circuit.rs index e76d66c97..5f1683322 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -325,22 +325,15 @@ pub fn build_circuit_outputs<'ctx>( llvm::r#type::pointer(context, 0), 0, )?; - let ref_count_ptr = entry.gep( - context, - location, - gates_ptr, - &[GepIndex::Const(0)], - IntegerType::new(context, 8).into(), - )?; let ref_count = entry.load( context, location, - ref_count_ptr, + gates_ptr, IntegerType::new(context, 32).into(), )?; let ref_count_inc = entry.addi(ref_count, k1, location)?; - entry.store(context, location, ref_count_ptr, ref_count_inc)?; + entry.store(context, location, gates_ptr, ref_count_inc)?; entry.append_operation(func::r#return(&[outputs, outputs], location)); Ok(Some(region)) @@ -367,18 +360,10 @@ pub fn build_circuit_outputs<'ctx>( llvm::r#type::pointer(context, 0), 0, )?; - - let ref_count_ptr = entry.gep( - context, - location, - gates_ptr, - &[GepIndex::Const(0)], - IntegerType::new(context, 8).into(), - )?; let ref_count = entry.load( context, location, - ref_count_ptr, + gates_ptr, IntegerType::new(context, 32).into(), )?; @@ -394,7 +379,7 @@ pub fn build_circuit_outputs<'ctx>( let entry = region.append_block(Block::new(&[])); let ref_count_dec = entry.subi(ref_count, k1, location)?; - entry.store(context, location, ref_count_ptr, ref_count_dec)?; + entry.store(context, location, gates_ptr, ref_count_dec)?; entry.append_operation(scf::r#yield(&[], location)); region From 385772b3e8d2814033ad1cce3de631301910e447 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 24 Sep 2025 12:47:23 -0300 Subject: [PATCH 14/18] update tracedump --- src/metadata/trace_dump.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 10a72fcfc..8d10bbf8b 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -566,27 +566,26 @@ pub mod trace_dump_runtime { else { panic!("generic arg should be a Circuit"); }; + let u96_layout = get_integer_layout(96); let n_outputs = circuit.circuit_info.values.len(); let mut values = Vec::with_capacity(n_outputs); - let (gate_stride, _) = layout_repeat(&u96_layout, 4).unwrap(); - let outputs_prefix_layout = calc_circuit_output_prefix_layout(); - let gates_array_layout = outputs_prefix_layout - .extend(layout_repeat(&gate_stride, n_outputs).unwrap().0) - .unwrap() - .0 - .pad_to_align(); - let (_, modulus_offset) = gates_array_layout.extend(gate_stride).unwrap(); + let (u384_struct_layout, _) = layout_repeat(&u96_layout, 4).unwrap(); + let (gates_array_layout, gate_stride) = + layout_repeat(&u384_struct_layout, n_outputs).unwrap(); + let (_, modulus_offset) = + gates_array_layout.extend(u384_struct_layout).unwrap(); - let value_ptr = value_ptr.cast::<[u8; 12]>(); + let value_ptr = { + let data_start_offset = calc_circuit_output_prefix_layout().size(); + value_ptr.byte_add(data_start_offset).cast::<[u8; 12]>() + }; // get gate values for i in 0..n_outputs { - let gate_ptr = value_ptr.byte_add( - outputs_prefix_layout.size() + gate_stride.pad_to_align().size() * i, - ); + let gate_ptr = value_ptr.byte_add(gate_stride * i); values.push(u384_struct_to_bigint(gate_ptr, 4)); } From 6af8c16ced2af9dfa4ab9f30923a51de9b4257d8 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 24 Sep 2025 12:50:15 -0300 Subject: [PATCH 15/18] update tracedump --- src/metadata/trace_dump.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 8d10bbf8b..4b62ab29f 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -579,6 +579,10 @@ pub mod trace_dump_runtime { gates_array_layout.extend(u384_struct_layout).unwrap(); let value_ptr = { + // The poiter holds: + // 1. Reference counter. + //. 2. data. + // So we need to offset it before we can use it. let data_start_offset = calc_circuit_output_prefix_layout().size(); value_ptr.byte_add(data_start_offset).cast::<[u8; 12]>() }; From cd0c72fb60e8808185aac5cf5fd33174188b2556 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 24 Sep 2025 12:52:08 -0300 Subject: [PATCH 16/18] fmt --- src/libfuncs/circuit.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 16a8a48c0..ed6c20a40 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -392,9 +392,7 @@ fn build_eval<'ctx, 'this>( context, location, outputs_ptr, - &[GepIndex::Const( - data_start_offset as i32, - )], + &[GepIndex::Const(data_start_offset as i32)], IntegerType::new(context, 8).into(), )?; From 584c6219cf332bf6ab65e656e94df1fdb6597721 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 24 Sep 2025 14:13:58 -0300 Subject: [PATCH 17/18] clippy --- src/libfuncs/circuit.rs | 3 +-- src/types/circuit.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index ed6c20a40..e1a1532a4 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -368,7 +368,7 @@ fn build_eval<'ctx, 'this>( let u384_layout = get_integer_layout(384); // Calculate capacity for array. - let (data_layout, elem_stride) = layout_repeat(&u384_layout, circuit_info.values.len())?; + let (data_layout, _) = layout_repeat(&u384_layout, circuit_info.values.len())?; let (outputs_layout, data_start_offset) = calc_circuit_output_prefix_layout().extend(data_layout)?; let outputs_capacity_bytes_value = @@ -945,7 +945,6 @@ fn build_get_output<'ctx, 'this>( )?; let data_start_offset = calc_circuit_output_prefix_layout().size() as i32; - let elem_stride = get_integer_layout(384).size() as i32; let data_ptr = entry.gep( context, diff --git a/src/types/circuit.rs b/src/types/circuit.rs index 5f1683322..48626c97d 100644 --- a/src/types/circuit.rs +++ b/src/types/circuit.rs @@ -22,7 +22,7 @@ use cairo_lang_sierra::{ }; use melior::{ dialect::{arith::CmpiPredicate, func, llvm, scf}, - helpers::{ArithBlockExt, BuiltinBlockExt, GepIndex, LlvmBlockExt}, + helpers::{ArithBlockExt, BuiltinBlockExt, LlvmBlockExt}, ir::{r#type::IntegerType, Block, BlockLike, Location, Module, Region, Type, Value}, Context, }; From 0b29a18695ab71944fa26dbe5541a8b5e9a13907 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 25 Sep 2025 09:56:24 -0300 Subject: [PATCH 18/18] add program to benchmark --- benches/benches.rs | 1 + programs/benches/heavy_output_circuit.cairo | 1536 +++++++++++++++++++ 2 files changed, 1537 insertions(+) create mode 100644 programs/benches/heavy_output_circuit.cairo diff --git a/benches/benches.rs b/benches/benches.rs index 066c58909..552bd5f7b 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -84,6 +84,7 @@ fn compare(c: &mut Criterion, path: impl AsRef) { } fn criterion_benchmark(c: &mut Criterion) { + compare(c, "programs/benches/heavy_output_circuit.cairo"); compare(c, "programs/benches/dict_snapshot.cairo"); compare(c, "programs/benches/dict_insert.cairo"); compare(c, "programs/benches/factorial_2M.cairo"); diff --git a/programs/benches/heavy_output_circuit.cairo b/programs/benches/heavy_output_circuit.cairo new file mode 100644 index 000000000..21a56efbe --- /dev/null +++ b/programs/benches/heavy_output_circuit.cairo @@ -0,0 +1,1536 @@ +use core::circuit::{ + AddInputResult, AddInputResultTrait, CircuitData, CircuitElement as CE, CircuitInput as CI, + CircuitInputs, CircuitModulus, CircuitOutputsTrait, EvalCircuitResult, EvalCircuitTrait, + IntoCircuitInputValue, add_circuit_input, circuit_add, circuit_inverse, circuit_mul, + circuit_sub, u384, +}; + +#[inline(always)] +pub fn main() { + // CONSTANT stack + let in0 = CE::> {}; // 0x3 + + // INPUT stack + let (in1, in2) = (CE::> {}, CE::> {}); + let t0 = circuit_mul(in1, in1); + let t1 = circuit_mul(in0, t0); + let t2 = circuit_add(in2, in2); + let t3 = circuit_inverse(t2); + let t4 = circuit_mul(t1, t3); + let t5 = circuit_mul(t4, t4); + let t6 = circuit_sub(t5, in1); + let t7 = circuit_sub(t6, in1); + let t8 = circuit_sub(in1, t7); + let t9 = circuit_mul(t4, t8); + let t10 = circuit_sub(t9, in2); + let t11 = circuit_sub(t10, in2); + let t12 = circuit_sub(t7, in1); + let t13 = circuit_inverse(t12); + let t14 = circuit_mul(t11, t13); + let t15 = circuit_mul(t14, t14); + let t16 = circuit_sub(t15, t7); + let t17 = circuit_sub(t16, in1); + let t18 = circuit_sub(t7, t17); + let t19 = circuit_mul(t14, t18); + let t20 = circuit_sub(t19, t10); + let t21 = circuit_mul(t17, t17); + let t22 = circuit_mul(in0, t21); + let t23 = circuit_add(t20, t20); + let t24 = circuit_inverse(t23); + let t25 = circuit_mul(t22, t24); + let t26 = circuit_mul(t25, t25); + let t27 = circuit_sub(t26, t17); + let t28 = circuit_sub(t27, t17); + let t29 = circuit_sub(t17, t28); + let t30 = circuit_mul(t25, t29); + let t31 = circuit_sub(t30, t20); + let t32 = circuit_mul(t28, t28); + let t33 = circuit_mul(in0, t32); + let t34 = circuit_add(t31, t31); + let t35 = circuit_inverse(t34); + let t36 = circuit_mul(t33, t35); + let t37 = circuit_mul(t36, t36); + let t38 = circuit_sub(t37, t28); + let t39 = circuit_sub(t38, t28); + let t40 = circuit_sub(t28, t39); + let t41 = circuit_mul(t36, t40); + let t42 = circuit_sub(t41, t31); + let t43 = circuit_sub(t42, in2); + let t44 = circuit_sub(t39, in1); + let t45 = circuit_inverse(t44); + let t46 = circuit_mul(t43, t45); + let t47 = circuit_mul(t46, t46); + let t48 = circuit_sub(t47, t39); + let t49 = circuit_sub(t48, in1); + let t50 = circuit_sub(t39, t49); + let t51 = circuit_mul(t46, t50); + let t52 = circuit_sub(t51, t42); + let t53 = circuit_mul(t49, t49); + let t54 = circuit_mul(in0, t53); + let t55 = circuit_add(t52, t52); + let t56 = circuit_inverse(t55); + let t57 = circuit_mul(t54, t56); + let t58 = circuit_mul(t57, t57); + let t59 = circuit_sub(t58, t49); + let t60 = circuit_sub(t59, t49); + let t61 = circuit_sub(t49, t60); + let t62 = circuit_mul(t57, t61); + let t63 = circuit_sub(t62, t52); + let t64 = circuit_mul(t60, t60); + let t65 = circuit_mul(in0, t64); + let t66 = circuit_add(t63, t63); + let t67 = circuit_inverse(t66); + let t68 = circuit_mul(t65, t67); + let t69 = circuit_mul(t68, t68); + let t70 = circuit_sub(t69, t60); + let t71 = circuit_sub(t70, t60); + let t72 = circuit_sub(t60, t71); + let t73 = circuit_mul(t68, t72); + let t74 = circuit_sub(t73, t63); + let t75 = circuit_mul(t71, t71); + let t76 = circuit_mul(in0, t75); + let t77 = circuit_add(t74, t74); + let t78 = circuit_inverse(t77); + let t79 = circuit_mul(t76, t78); + let t80 = circuit_mul(t79, t79); + let t81 = circuit_sub(t80, t71); + let t82 = circuit_sub(t81, t71); + let t83 = circuit_sub(t71, t82); + let t84 = circuit_mul(t79, t83); + let t85 = circuit_sub(t84, t74); + let t86 = circuit_sub(t85, in2); + let t87 = circuit_sub(t82, in1); + let t88 = circuit_inverse(t87); + let t89 = circuit_mul(t86, t88); + let t90 = circuit_mul(t89, t89); + let t91 = circuit_sub(t90, t82); + let t92 = circuit_sub(t91, in1); + let t93 = circuit_sub(t82, t92); + let t94 = circuit_mul(t89, t93); + let t95 = circuit_sub(t94, t85); + let t96 = circuit_mul(t92, t92); + let t97 = circuit_mul(in0, t96); + let t98 = circuit_add(t95, t95); + let t99 = circuit_inverse(t98); + let t100 = circuit_mul(t97, t99); + let t101 = circuit_mul(t100, t100); + let t102 = circuit_sub(t101, t92); + let t103 = circuit_sub(t102, t92); + let t104 = circuit_sub(t92, t103); + let t105 = circuit_mul(t100, t104); + let t106 = circuit_sub(t105, t95); + let t107 = circuit_mul(t103, t103); + let t108 = circuit_mul(in0, t107); + let t109 = circuit_add(t106, t106); + let t110 = circuit_inverse(t109); + let t111 = circuit_mul(t108, t110); + let t112 = circuit_mul(t111, t111); + let t113 = circuit_sub(t112, t103); + let t114 = circuit_sub(t113, t103); + let t115 = circuit_sub(t103, t114); + let t116 = circuit_mul(t111, t115); + let t117 = circuit_sub(t116, t106); + let t118 = circuit_mul(t114, t114); + let t119 = circuit_mul(in0, t118); + let t120 = circuit_add(t117, t117); + let t121 = circuit_inverse(t120); + let t122 = circuit_mul(t119, t121); + let t123 = circuit_mul(t122, t122); + let t124 = circuit_sub(t123, t114); + let t125 = circuit_sub(t124, t114); + let t126 = circuit_sub(t114, t125); + let t127 = circuit_mul(t122, t126); + let t128 = circuit_sub(t127, t117); + let t129 = circuit_mul(t125, t125); + let t130 = circuit_mul(in0, t129); + let t131 = circuit_add(t128, t128); + let t132 = circuit_inverse(t131); + let t133 = circuit_mul(t130, t132); + let t134 = circuit_mul(t133, t133); + let t135 = circuit_sub(t134, t125); + let t136 = circuit_sub(t135, t125); + let t137 = circuit_sub(t125, t136); + let t138 = circuit_mul(t133, t137); + let t139 = circuit_sub(t138, t128); + let t140 = circuit_mul(t136, t136); + let t141 = circuit_mul(in0, t140); + let t142 = circuit_add(t139, t139); + let t143 = circuit_inverse(t142); + let t144 = circuit_mul(t141, t143); + let t145 = circuit_mul(t144, t144); + let t146 = circuit_sub(t145, t136); + let t147 = circuit_sub(t146, t136); + let t148 = circuit_sub(t136, t147); + let t149 = circuit_mul(t144, t148); + let t150 = circuit_sub(t149, t139); + let t151 = circuit_mul(t147, t147); + let t152 = circuit_mul(in0, t151); + let t153 = circuit_add(t150, t150); + let t154 = circuit_inverse(t153); + let t155 = circuit_mul(t152, t154); + let t156 = circuit_mul(t155, t155); + let t157 = circuit_sub(t156, t147); + let t158 = circuit_sub(t157, t147); + let t159 = circuit_sub(t147, t158); + let t160 = circuit_mul(t155, t159); + let t161 = circuit_sub(t160, t150); + let t162 = circuit_mul(t158, t158); + let t163 = circuit_mul(in0, t162); + let t164 = circuit_add(t161, t161); + let t165 = circuit_inverse(t164); + let t166 = circuit_mul(t163, t165); + let t167 = circuit_mul(t166, t166); + let t168 = circuit_sub(t167, t158); + let t169 = circuit_sub(t168, t158); + let t170 = circuit_sub(t158, t169); + let t171 = circuit_mul(t166, t170); + let t172 = circuit_sub(t171, t161); + let t173 = circuit_mul(t169, t169); + let t174 = circuit_mul(in0, t173); + let t175 = circuit_add(t172, t172); + let t176 = circuit_inverse(t175); + let t177 = circuit_mul(t174, t176); + let t178 = circuit_mul(t177, t177); + let t179 = circuit_sub(t178, t169); + let t180 = circuit_sub(t179, t169); + let t181 = circuit_sub(t169, t180); + let t182 = circuit_mul(t177, t181); + let t183 = circuit_sub(t182, t172); + let t184 = circuit_mul(t180, t180); + let t185 = circuit_mul(in0, t184); + let t186 = circuit_add(t183, t183); + let t187 = circuit_inverse(t186); + let t188 = circuit_mul(t185, t187); + let t189 = circuit_mul(t188, t188); + let t190 = circuit_sub(t189, t180); + let t191 = circuit_sub(t190, t180); + let t192 = circuit_sub(t180, t191); + let t193 = circuit_mul(t188, t192); + let t194 = circuit_sub(t193, t183); + let t195 = circuit_sub(t194, in2); + let t196 = circuit_sub(t191, in1); + let t197 = circuit_inverse(t196); + let t198 = circuit_mul(t195, t197); + let t199 = circuit_mul(t198, t198); + let t200 = circuit_sub(t199, t191); + let t201 = circuit_sub(t200, in1); + let t202 = circuit_sub(t191, t201); + let t203 = circuit_mul(t198, t202); + let t204 = circuit_sub(t203, t194); + let t205 = circuit_mul(t201, t201); + let t206 = circuit_mul(in0, t205); + let t207 = circuit_add(t204, t204); + let t208 = circuit_inverse(t207); + let t209 = circuit_mul(t206, t208); + let t210 = circuit_mul(t209, t209); + let t211 = circuit_sub(t210, t201); + let t212 = circuit_sub(t211, t201); + let t213 = circuit_sub(t201, t212); + let t214 = circuit_mul(t209, t213); + let t215 = circuit_sub(t214, t204); + let t216 = circuit_mul(t212, t212); + let t217 = circuit_mul(in0, t216); + let t218 = circuit_add(t215, t215); + let t219 = circuit_inverse(t218); + let t220 = circuit_mul(t217, t219); + let t221 = circuit_mul(t220, t220); + let t222 = circuit_sub(t221, t212); + let t223 = circuit_sub(t222, t212); + let t224 = circuit_sub(t212, t223); + let t225 = circuit_mul(t220, t224); + let t226 = circuit_sub(t225, t215); + let t227 = circuit_mul(t223, t223); + let t228 = circuit_mul(in0, t227); + let t229 = circuit_add(t226, t226); + let t230 = circuit_inverse(t229); + let t231 = circuit_mul(t228, t230); + let t232 = circuit_mul(t231, t231); + let t233 = circuit_sub(t232, t223); + let t234 = circuit_sub(t233, t223); + let t235 = circuit_sub(t223, t234); + let t236 = circuit_mul(t231, t235); + let t237 = circuit_sub(t236, t226); + let t238 = circuit_mul(t234, t234); + let t239 = circuit_mul(in0, t238); + let t240 = circuit_add(t237, t237); + let t241 = circuit_inverse(t240); + let t242 = circuit_mul(t239, t241); + let t243 = circuit_mul(t242, t242); + let t244 = circuit_sub(t243, t234); + let t245 = circuit_sub(t244, t234); + let t246 = circuit_sub(t234, t245); + let t247 = circuit_mul(t242, t246); + let t248 = circuit_sub(t247, t237); + let t249 = circuit_mul(t245, t245); + let t250 = circuit_mul(in0, t249); + let t251 = circuit_add(t248, t248); + let t252 = circuit_inverse(t251); + let t253 = circuit_mul(t250, t252); + let t254 = circuit_mul(t253, t253); + let t255 = circuit_sub(t254, t245); + let t256 = circuit_sub(t255, t245); + let t257 = circuit_sub(t245, t256); + let t258 = circuit_mul(t253, t257); + let t259 = circuit_sub(t258, t248); + let t260 = circuit_mul(t256, t256); + let t261 = circuit_mul(in0, t260); + let t262 = circuit_add(t259, t259); + let t263 = circuit_inverse(t262); + let t264 = circuit_mul(t261, t263); + let t265 = circuit_mul(t264, t264); + let t266 = circuit_sub(t265, t256); + let t267 = circuit_sub(t266, t256); + let t268 = circuit_sub(t256, t267); + let t269 = circuit_mul(t264, t268); + let t270 = circuit_sub(t269, t259); + let t271 = circuit_mul(t267, t267); + let t272 = circuit_mul(in0, t271); + let t273 = circuit_add(t270, t270); + let t274 = circuit_inverse(t273); + let t275 = circuit_mul(t272, t274); + let t276 = circuit_mul(t275, t275); + let t277 = circuit_sub(t276, t267); + let t278 = circuit_sub(t277, t267); + let t279 = circuit_sub(t267, t278); + let t280 = circuit_mul(t275, t279); + let t281 = circuit_sub(t280, t270); + let t282 = circuit_mul(t278, t278); + let t283 = circuit_mul(in0, t282); + let t284 = circuit_add(t281, t281); + let t285 = circuit_inverse(t284); + let t286 = circuit_mul(t283, t285); + let t287 = circuit_mul(t286, t286); + let t288 = circuit_sub(t287, t278); + let t289 = circuit_sub(t288, t278); + let t290 = circuit_sub(t278, t289); + let t291 = circuit_mul(t286, t290); + let t292 = circuit_sub(t291, t281); + let t293 = circuit_mul(t289, t289); + let t294 = circuit_mul(in0, t293); + let t295 = circuit_add(t292, t292); + let t296 = circuit_inverse(t295); + let t297 = circuit_mul(t294, t296); + let t298 = circuit_mul(t297, t297); + let t299 = circuit_sub(t298, t289); + let t300 = circuit_sub(t299, t289); + let t301 = circuit_sub(t289, t300); + let t302 = circuit_mul(t297, t301); + let t303 = circuit_sub(t302, t292); + let t304 = circuit_mul(t300, t300); + let t305 = circuit_mul(in0, t304); + let t306 = circuit_add(t303, t303); + let t307 = circuit_inverse(t306); + let t308 = circuit_mul(t305, t307); + let t309 = circuit_mul(t308, t308); + let t310 = circuit_sub(t309, t300); + let t311 = circuit_sub(t310, t300); + let t312 = circuit_sub(t300, t311); + let t313 = circuit_mul(t308, t312); + let t314 = circuit_sub(t313, t303); + let t315 = circuit_mul(t311, t311); + let t316 = circuit_mul(in0, t315); + let t317 = circuit_add(t314, t314); + let t318 = circuit_inverse(t317); + let t319 = circuit_mul(t316, t318); + let t320 = circuit_mul(t319, t319); + let t321 = circuit_sub(t320, t311); + let t322 = circuit_sub(t321, t311); + let t323 = circuit_sub(t311, t322); + let t324 = circuit_mul(t319, t323); + let t325 = circuit_sub(t324, t314); + let t326 = circuit_mul(t322, t322); + let t327 = circuit_mul(in0, t326); + let t328 = circuit_add(t325, t325); + let t329 = circuit_inverse(t328); + let t330 = circuit_mul(t327, t329); + let t331 = circuit_mul(t330, t330); + let t332 = circuit_sub(t331, t322); + let t333 = circuit_sub(t332, t322); + let t334 = circuit_sub(t322, t333); + let t335 = circuit_mul(t330, t334); + let t336 = circuit_sub(t335, t325); + let t337 = circuit_mul(t333, t333); + let t338 = circuit_mul(in0, t337); + let t339 = circuit_add(t336, t336); + let t340 = circuit_inverse(t339); + let t341 = circuit_mul(t338, t340); + let t342 = circuit_mul(t341, t341); + let t343 = circuit_sub(t342, t333); + let t344 = circuit_sub(t343, t333); + let t345 = circuit_sub(t333, t344); + let t346 = circuit_mul(t341, t345); + let t347 = circuit_sub(t346, t336); + let t348 = circuit_mul(t344, t344); + let t349 = circuit_mul(in0, t348); + let t350 = circuit_add(t347, t347); + let t351 = circuit_inverse(t350); + let t352 = circuit_mul(t349, t351); + let t353 = circuit_mul(t352, t352); + let t354 = circuit_sub(t353, t344); + let t355 = circuit_sub(t354, t344); + let t356 = circuit_sub(t344, t355); + let t357 = circuit_mul(t352, t356); + let t358 = circuit_sub(t357, t347); + let t359 = circuit_mul(t355, t355); + let t360 = circuit_mul(in0, t359); + let t361 = circuit_add(t358, t358); + let t362 = circuit_inverse(t361); + let t363 = circuit_mul(t360, t362); + let t364 = circuit_mul(t363, t363); + let t365 = circuit_sub(t364, t355); + let t366 = circuit_sub(t365, t355); + let t367 = circuit_sub(t355, t366); + let t368 = circuit_mul(t363, t367); + let t369 = circuit_sub(t368, t358); + let t370 = circuit_mul(t366, t366); + let t371 = circuit_mul(in0, t370); + let t372 = circuit_add(t369, t369); + let t373 = circuit_inverse(t372); + let t374 = circuit_mul(t371, t373); + let t375 = circuit_mul(t374, t374); + let t376 = circuit_sub(t375, t366); + let t377 = circuit_sub(t376, t366); + let t378 = circuit_sub(t366, t377); + let t379 = circuit_mul(t374, t378); + let t380 = circuit_sub(t379, t369); + let t381 = circuit_mul(t377, t377); + let t382 = circuit_mul(in0, t381); + let t383 = circuit_add(t380, t380); + let t384 = circuit_inverse(t383); + let t385 = circuit_mul(t382, t384); + let t386 = circuit_mul(t385, t385); + let t387 = circuit_sub(t386, t377); + let t388 = circuit_sub(t387, t377); + let t389 = circuit_sub(t377, t388); + let t390 = circuit_mul(t385, t389); + let t391 = circuit_sub(t390, t380); + let t392 = circuit_mul(t388, t388); + let t393 = circuit_mul(in0, t392); + let t394 = circuit_add(t391, t391); + let t395 = circuit_inverse(t394); + let t396 = circuit_mul(t393, t395); + let t397 = circuit_mul(t396, t396); + let t398 = circuit_sub(t397, t388); + let t399 = circuit_sub(t398, t388); + let t400 = circuit_sub(t388, t399); + let t401 = circuit_mul(t396, t400); + let t402 = circuit_sub(t401, t391); + let t403 = circuit_mul(t399, t399); + let t404 = circuit_mul(in0, t403); + let t405 = circuit_add(t402, t402); + let t406 = circuit_inverse(t405); + let t407 = circuit_mul(t404, t406); + let t408 = circuit_mul(t407, t407); + let t409 = circuit_sub(t408, t399); + let t410 = circuit_sub(t409, t399); + let t411 = circuit_sub(t399, t410); + let t412 = circuit_mul(t407, t411); + let t413 = circuit_sub(t412, t402); + let t414 = circuit_mul(t410, t410); + let t415 = circuit_mul(in0, t414); + let t416 = circuit_add(t413, t413); + let t417 = circuit_inverse(t416); + let t418 = circuit_mul(t415, t417); + let t419 = circuit_mul(t418, t418); + let t420 = circuit_sub(t419, t410); + let t421 = circuit_sub(t420, t410); + let t422 = circuit_sub(t410, t421); + let t423 = circuit_mul(t418, t422); + let t424 = circuit_sub(t423, t413); + let t425 = circuit_mul(t421, t421); + let t426 = circuit_mul(in0, t425); + let t427 = circuit_add(t424, t424); + let t428 = circuit_inverse(t427); + let t429 = circuit_mul(t426, t428); + let t430 = circuit_mul(t429, t429); + let t431 = circuit_sub(t430, t421); + let t432 = circuit_sub(t431, t421); + let t433 = circuit_sub(t421, t432); + let t434 = circuit_mul(t429, t433); + let t435 = circuit_sub(t434, t424); + let t436 = circuit_mul(t432, t432); + let t437 = circuit_mul(in0, t436); + let t438 = circuit_add(t435, t435); + let t439 = circuit_inverse(t438); + let t440 = circuit_mul(t437, t439); + let t441 = circuit_mul(t440, t440); + let t442 = circuit_sub(t441, t432); + let t443 = circuit_sub(t442, t432); + let t444 = circuit_sub(t432, t443); + let t445 = circuit_mul(t440, t444); + let t446 = circuit_sub(t445, t435); + let t447 = circuit_mul(t443, t443); + let t448 = circuit_mul(in0, t447); + let t449 = circuit_add(t446, t446); + let t450 = circuit_inverse(t449); + let t451 = circuit_mul(t448, t450); + let t452 = circuit_mul(t451, t451); + let t453 = circuit_sub(t452, t443); + let t454 = circuit_sub(t453, t443); + let t455 = circuit_sub(t443, t454); + let t456 = circuit_mul(t451, t455); + let t457 = circuit_sub(t456, t446); + let t458 = circuit_mul(t454, t454); + let t459 = circuit_mul(in0, t458); + let t460 = circuit_add(t457, t457); + let t461 = circuit_inverse(t460); + let t462 = circuit_mul(t459, t461); + let t463 = circuit_mul(t462, t462); + let t464 = circuit_sub(t463, t454); + let t465 = circuit_sub(t464, t454); + let t466 = circuit_sub(t454, t465); + let t467 = circuit_mul(t462, t466); + let t468 = circuit_sub(t467, t457); + let t469 = circuit_mul(t465, t465); + let t470 = circuit_mul(in0, t469); + let t471 = circuit_add(t468, t468); + let t472 = circuit_inverse(t471); + let t473 = circuit_mul(t470, t472); + let t474 = circuit_mul(t473, t473); + let t475 = circuit_sub(t474, t465); + let t476 = circuit_sub(t475, t465); + let t477 = circuit_sub(t465, t476); + let t478 = circuit_mul(t473, t477); + let t479 = circuit_sub(t478, t468); + let t480 = circuit_mul(t476, t476); + let t481 = circuit_mul(in0, t480); + let t482 = circuit_add(t479, t479); + let t483 = circuit_inverse(t482); + let t484 = circuit_mul(t481, t483); + let t485 = circuit_mul(t484, t484); + let t486 = circuit_sub(t485, t476); + let t487 = circuit_sub(t486, t476); + let t488 = circuit_sub(t476, t487); + let t489 = circuit_mul(t484, t488); + let t490 = circuit_sub(t489, t479); + let t491 = circuit_mul(t487, t487); + let t492 = circuit_mul(in0, t491); + let t493 = circuit_add(t490, t490); + let t494 = circuit_inverse(t493); + let t495 = circuit_mul(t492, t494); + let t496 = circuit_mul(t495, t495); + let t497 = circuit_sub(t496, t487); + let t498 = circuit_sub(t497, t487); + let t499 = circuit_sub(t487, t498); + let t500 = circuit_mul(t495, t499); + let t501 = circuit_sub(t500, t490); + let t502 = circuit_mul(t498, t498); + let t503 = circuit_mul(in0, t502); + let t504 = circuit_add(t501, t501); + let t505 = circuit_inverse(t504); + let t506 = circuit_mul(t503, t505); + let t507 = circuit_mul(t506, t506); + let t508 = circuit_sub(t507, t498); + let t509 = circuit_sub(t508, t498); + let t510 = circuit_sub(t498, t509); + let t511 = circuit_mul(t506, t510); + let t512 = circuit_sub(t511, t501); + let t513 = circuit_mul(t509, t509); + let t514 = circuit_mul(in0, t513); + let t515 = circuit_add(t512, t512); + let t516 = circuit_inverse(t515); + let t517 = circuit_mul(t514, t516); + let t518 = circuit_mul(t517, t517); + let t519 = circuit_sub(t518, t509); + let t520 = circuit_sub(t519, t509); + let t521 = circuit_sub(t509, t520); + let t522 = circuit_mul(t517, t521); + let t523 = circuit_sub(t522, t512); + let t524 = circuit_mul(t520, t520); + let t525 = circuit_mul(in0, t524); + let t526 = circuit_add(t523, t523); + let t527 = circuit_inverse(t526); + let t528 = circuit_mul(t525, t527); + let t529 = circuit_mul(t528, t528); + let t530 = circuit_sub(t529, t520); + let t531 = circuit_sub(t530, t520); + let t532 = circuit_sub(t520, t531); + let t533 = circuit_mul(t528, t532); + let t534 = circuit_sub(t533, t523); + let t535 = circuit_mul(t531, t531); + let t536 = circuit_mul(in0, t535); + let t537 = circuit_add(t534, t534); + let t538 = circuit_inverse(t537); + let t539 = circuit_mul(t536, t538); + let t540 = circuit_mul(t539, t539); + let t541 = circuit_sub(t540, t531); + let t542 = circuit_sub(t541, t531); + let t543 = circuit_sub(t531, t542); + let t544 = circuit_mul(t539, t543); + let t545 = circuit_sub(t544, t534); + let t546 = circuit_mul(t542, t542); + let t547 = circuit_mul(in0, t546); + let t548 = circuit_add(t545, t545); + let t549 = circuit_inverse(t548); + let t550 = circuit_mul(t547, t549); + let t551 = circuit_mul(t550, t550); + let t552 = circuit_sub(t551, t542); + let t553 = circuit_sub(t552, t542); + let t554 = circuit_sub(t542, t553); + let t555 = circuit_mul(t550, t554); + let t556 = circuit_sub(t555, t545); + let t557 = circuit_sub(t556, in2); + let t558 = circuit_sub(t553, in1); + let t559 = circuit_inverse(t558); + let t560 = circuit_mul(t557, t559); + let t561 = circuit_mul(t560, t560); + let t562 = circuit_sub(t561, t553); + let t563 = circuit_sub(t562, in1); + let t564 = circuit_sub(t553, t563); + let t565 = circuit_mul(t560, t564); + let t566 = circuit_sub(t565, t556); + let t567 = circuit_mul(t563, t563); + let t568 = circuit_mul(in0, t567); + let t569 = circuit_add(t566, t566); + let t570 = circuit_inverse(t569); + let t571 = circuit_mul(t568, t570); + let t572 = circuit_mul(t571, t571); + let t573 = circuit_sub(t572, t563); + let t574 = circuit_sub(t573, t563); + let t575 = circuit_sub(t563, t574); + let t576 = circuit_mul(t571, t575); + let t577 = circuit_sub(t576, t566); + let t578 = circuit_mul(t574, t574); + let t579 = circuit_mul(in0, t578); + let t580 = circuit_add(t577, t577); + let t581 = circuit_inverse(t580); + let t582 = circuit_mul(t579, t581); + let t583 = circuit_mul(t582, t582); + let t584 = circuit_sub(t583, t574); + let t585 = circuit_sub(t584, t574); + let t586 = circuit_sub(t574, t585); + let t587 = circuit_mul(t582, t586); + let t588 = circuit_sub(t587, t577); + let t589 = circuit_mul(t585, t585); + let t590 = circuit_mul(in0, t589); + let t591 = circuit_add(t588, t588); + let t592 = circuit_inverse(t591); + let t593 = circuit_mul(t590, t592); + let t594 = circuit_mul(t593, t593); + let t595 = circuit_sub(t594, t585); + let t596 = circuit_sub(t595, t585); + let t597 = circuit_sub(t585, t596); + let t598 = circuit_mul(t593, t597); + let t599 = circuit_sub(t598, t588); + let t600 = circuit_mul(t596, t596); + let t601 = circuit_mul(in0, t600); + let t602 = circuit_add(t599, t599); + let t603 = circuit_inverse(t602); + let t604 = circuit_mul(t601, t603); + let t605 = circuit_mul(t604, t604); + let t606 = circuit_sub(t605, t596); + let t607 = circuit_sub(t606, t596); + let t608 = circuit_sub(t596, t607); + let t609 = circuit_mul(t604, t608); + let t610 = circuit_sub(t609, t599); + let t611 = circuit_mul(t607, t607); + let t612 = circuit_mul(in0, t611); + let t613 = circuit_add(t610, t610); + let t614 = circuit_inverse(t613); + let t615 = circuit_mul(t612, t614); + let t616 = circuit_mul(t615, t615); + let t617 = circuit_sub(t616, t607); + let t618 = circuit_sub(t617, t607); + let t619 = circuit_sub(t607, t618); + let t620 = circuit_mul(t615, t619); + let t621 = circuit_sub(t620, t610); + let t622 = circuit_mul(t618, t618); + let t623 = circuit_mul(in0, t622); + let t624 = circuit_add(t621, t621); + let t625 = circuit_inverse(t624); + let t626 = circuit_mul(t623, t625); + let t627 = circuit_mul(t626, t626); + let t628 = circuit_sub(t627, t618); + let t629 = circuit_sub(t628, t618); + let t630 = circuit_sub(t618, t629); + let t631 = circuit_mul(t626, t630); + let t632 = circuit_sub(t631, t621); + let t633 = circuit_mul(t629, t629); + let t634 = circuit_mul(in0, t633); + let t635 = circuit_add(t632, t632); + let t636 = circuit_inverse(t635); + let t637 = circuit_mul(t634, t636); + let t638 = circuit_mul(t637, t637); + let t639 = circuit_sub(t638, t629); + let t640 = circuit_sub(t639, t629); + let t641 = circuit_sub(t629, t640); + let t642 = circuit_mul(t637, t641); + let t643 = circuit_sub(t642, t632); + let t644 = circuit_mul(t640, t640); + let t645 = circuit_mul(in0, t644); + let t646 = circuit_add(t643, t643); + let t647 = circuit_inverse(t646); + let t648 = circuit_mul(t645, t647); + let t649 = circuit_mul(t648, t648); + let t650 = circuit_sub(t649, t640); + let t651 = circuit_sub(t650, t640); + let t652 = circuit_sub(t640, t651); + let t653 = circuit_mul(t648, t652); + let t654 = circuit_sub(t653, t643); + let t655 = circuit_mul(t651, t651); + let t656 = circuit_mul(in0, t655); + let t657 = circuit_add(t654, t654); + let t658 = circuit_inverse(t657); + let t659 = circuit_mul(t656, t658); + let t660 = circuit_mul(t659, t659); + let t661 = circuit_sub(t660, t651); + let t662 = circuit_sub(t661, t651); + let t663 = circuit_sub(t651, t662); + let t664 = circuit_mul(t659, t663); + let t665 = circuit_sub(t664, t654); + let t666 = circuit_mul(t662, t662); + let t667 = circuit_mul(in0, t666); + let t668 = circuit_add(t665, t665); + let t669 = circuit_inverse(t668); + let t670 = circuit_mul(t667, t669); + let t671 = circuit_mul(t670, t670); + let t672 = circuit_sub(t671, t662); + let t673 = circuit_sub(t672, t662); + let t674 = circuit_sub(t662, t673); + let t675 = circuit_mul(t670, t674); + let t676 = circuit_sub(t675, t665); + let t677 = circuit_mul(t673, t673); + let t678 = circuit_mul(in0, t677); + let t679 = circuit_add(t676, t676); + let t680 = circuit_inverse(t679); + let t681 = circuit_mul(t678, t680); + let t682 = circuit_mul(t681, t681); + let t683 = circuit_sub(t682, t673); + let t684 = circuit_sub(t683, t673); + let t685 = circuit_sub(t673, t684); + let t686 = circuit_mul(t681, t685); + let t687 = circuit_sub(t686, t676); + let t688 = circuit_mul(t684, t684); + let t689 = circuit_mul(in0, t688); + let t690 = circuit_add(t687, t687); + let t691 = circuit_inverse(t690); + let t692 = circuit_mul(t689, t691); + let t693 = circuit_mul(t692, t692); + let t694 = circuit_sub(t693, t684); + let t695 = circuit_sub(t694, t684); + let t696 = circuit_sub(t684, t695); + let t697 = circuit_mul(t692, t696); + let t698 = circuit_sub(t697, t687); + let t699 = circuit_mul(t695, t695); + let t700 = circuit_mul(in0, t699); + let t701 = circuit_add(t698, t698); + let t702 = circuit_inverse(t701); + let t703 = circuit_mul(t700, t702); + let t704 = circuit_mul(t703, t703); + let t705 = circuit_sub(t704, t695); + let t706 = circuit_sub(t705, t695); + let t707 = circuit_sub(t695, t706); + let t708 = circuit_mul(t703, t707); + let t709 = circuit_sub(t708, t698); + let t710 = circuit_mul(t706, t706); + let t711 = circuit_mul(in0, t710); + let t712 = circuit_add(t709, t709); + let t713 = circuit_inverse(t712); + let t714 = circuit_mul(t711, t713); + let t715 = circuit_mul(t714, t714); + let t716 = circuit_sub(t715, t706); + let t717 = circuit_sub(t716, t706); + let t718 = circuit_sub(t706, t717); + let t719 = circuit_mul(t714, t718); + let t720 = circuit_sub(t719, t709); + let t721 = circuit_mul(t717, t717); + let t722 = circuit_mul(in0, t721); + let t723 = circuit_add(t720, t720); + let t724 = circuit_inverse(t723); + let t725 = circuit_mul(t722, t724); + let t726 = circuit_mul(t725, t725); + let t727 = circuit_sub(t726, t717); + let t728 = circuit_sub(t727, t717); + let t729 = circuit_sub(t717, t728); + let t730 = circuit_mul(t725, t729); + let t731 = circuit_sub(t730, t720); + let t732 = circuit_mul(t728, t728); + let t733 = circuit_mul(in0, t732); + let t734 = circuit_add(t731, t731); + let t735 = circuit_inverse(t734); + let t736 = circuit_mul(t733, t735); + let t737 = circuit_mul(t736, t736); + let t738 = circuit_sub(t737, t728); + let t739 = circuit_sub(t738, t728); + let t740 = circuit_sub(t728, t739); + let t741 = circuit_mul(t736, t740); + let t742 = circuit_sub(t741, t731); + let t743 = circuit_sub(in2, t742); + let t744 = circuit_sub(in1, t739); + let t745 = circuit_inverse(t744); + let t746 = circuit_mul(t743, t745); + let t747 = circuit_mul(t746, t746); + let t748 = circuit_sub(t747, in1); + let t749 = circuit_sub(t748, t739); + let t750 = circuit_sub(in1, t749); + let t751 = circuit_mul(t746, t750); + let t752 = circuit_sub(t751, in2); + + let modulus = TryInto::<_, CircuitModulus>::try_into([17, 14, 14, 14]).unwrap(); + + let outputs = (t752,) + .new_inputs() + .next([9, 2, 9, 3]) + .next([5, 7, 0, 8]) + .next([1, 2, 3, 4]) + .done() + .eval(modulus) + .unwrap(); + let u384_0 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + let mut accumulator = u384_0; + + accumulator = outputs.get_output(t0); + accumulator = outputs.get_output(t2); + accumulator = outputs.get_output(t3); + accumulator = outputs.get_output(t4); + accumulator = outputs.get_output(t5); + accumulator = outputs.get_output(t6); + accumulator = outputs.get_output(t7); + accumulator = outputs.get_output(t8); + accumulator = outputs.get_output(t9); + accumulator = outputs.get_output(t10); + accumulator = outputs.get_output(t11); + accumulator = outputs.get_output(t12); + accumulator = outputs.get_output(t13); + accumulator = outputs.get_output(t14); + accumulator = outputs.get_output(t15); + accumulator = outputs.get_output(t16); + accumulator = outputs.get_output(t17); + accumulator = outputs.get_output(t18); + accumulator = outputs.get_output(t19); + accumulator = outputs.get_output(t20); + accumulator = outputs.get_output(t21); + accumulator = outputs.get_output(t22); + accumulator = outputs.get_output(t23); + accumulator = outputs.get_output(t24); + accumulator = outputs.get_output(t25); + accumulator = outputs.get_output(t26); + accumulator = outputs.get_output(t27); + accumulator = outputs.get_output(t28); + accumulator = outputs.get_output(t29); + accumulator = outputs.get_output(t30); + accumulator = outputs.get_output(t31); + accumulator = outputs.get_output(t32); + accumulator = outputs.get_output(t33); + accumulator = outputs.get_output(t34); + accumulator = outputs.get_output(t35); + accumulator = outputs.get_output(t36); + accumulator = outputs.get_output(t37); + accumulator = outputs.get_output(t38); + accumulator = outputs.get_output(t39); + accumulator = outputs.get_output(t40); + accumulator = outputs.get_output(t41); + accumulator = outputs.get_output(t42); + accumulator = outputs.get_output(t43); + accumulator = outputs.get_output(t44); + accumulator = outputs.get_output(t45); + accumulator = outputs.get_output(t46); + accumulator = outputs.get_output(t47); + accumulator = outputs.get_output(t48); + accumulator = outputs.get_output(t49); + accumulator = outputs.get_output(t50); + accumulator = outputs.get_output(t51); + accumulator = outputs.get_output(t52); + accumulator = outputs.get_output(t53); + accumulator = outputs.get_output(t54); + accumulator = outputs.get_output(t55); + accumulator = outputs.get_output(t56); + accumulator = outputs.get_output(t57); + accumulator = outputs.get_output(t58); + accumulator = outputs.get_output(t59); + accumulator = outputs.get_output(t60); + accumulator = outputs.get_output(t61); + accumulator = outputs.get_output(t62); + accumulator = outputs.get_output(t63); + accumulator = outputs.get_output(t64); + accumulator = outputs.get_output(t65); + accumulator = outputs.get_output(t66); + accumulator = outputs.get_output(t67); + accumulator = outputs.get_output(t68); + accumulator = outputs.get_output(t69); + accumulator = outputs.get_output(t70); + accumulator = outputs.get_output(t71); + accumulator = outputs.get_output(t72); + accumulator = outputs.get_output(t73); + accumulator = outputs.get_output(t74); + accumulator = outputs.get_output(t75); + accumulator = outputs.get_output(t76); + accumulator = outputs.get_output(t77); + accumulator = outputs.get_output(t78); + accumulator = outputs.get_output(t79); + accumulator = outputs.get_output(t80); + accumulator = outputs.get_output(t81); + accumulator = outputs.get_output(t82); + accumulator = outputs.get_output(t83); + accumulator = outputs.get_output(t84); + accumulator = outputs.get_output(t85); + accumulator = outputs.get_output(t86); + accumulator = outputs.get_output(t87); + accumulator = outputs.get_output(t88); + accumulator = outputs.get_output(t89); + accumulator = outputs.get_output(t90); + accumulator = outputs.get_output(t91); + accumulator = outputs.get_output(t92); + accumulator = outputs.get_output(t93); + accumulator = outputs.get_output(t94); + accumulator = outputs.get_output(t95); + accumulator = outputs.get_output(t96); + accumulator = outputs.get_output(t97); + accumulator = outputs.get_output(t98); + accumulator = outputs.get_output(t99); + accumulator = outputs.get_output(t100); + accumulator = outputs.get_output(t101); + accumulator = outputs.get_output(t102); + accumulator = outputs.get_output(t103); + accumulator = outputs.get_output(t104); + accumulator = outputs.get_output(t105); + accumulator = outputs.get_output(t106); + accumulator = outputs.get_output(t107); + accumulator = outputs.get_output(t108); + accumulator = outputs.get_output(t109); + accumulator = outputs.get_output(t110); + accumulator = outputs.get_output(t111); + accumulator = outputs.get_output(t112); + accumulator = outputs.get_output(t113); + accumulator = outputs.get_output(t114); + accumulator = outputs.get_output(t115); + accumulator = outputs.get_output(t116); + accumulator = outputs.get_output(t117); + accumulator = outputs.get_output(t118); + accumulator = outputs.get_output(t119); + accumulator = outputs.get_output(t120); + accumulator = outputs.get_output(t121); + accumulator = outputs.get_output(t122); + accumulator = outputs.get_output(t123); + accumulator = outputs.get_output(t124); + accumulator = outputs.get_output(t125); + accumulator = outputs.get_output(t126); + accumulator = outputs.get_output(t127); + accumulator = outputs.get_output(t128); + accumulator = outputs.get_output(t129); + accumulator = outputs.get_output(t130); + accumulator = outputs.get_output(t131); + accumulator = outputs.get_output(t132); + accumulator = outputs.get_output(t133); + accumulator = outputs.get_output(t134); + accumulator = outputs.get_output(t135); + accumulator = outputs.get_output(t136); + accumulator = outputs.get_output(t137); + accumulator = outputs.get_output(t138); + accumulator = outputs.get_output(t139); + accumulator = outputs.get_output(t140); + accumulator = outputs.get_output(t141); + accumulator = outputs.get_output(t142); + accumulator = outputs.get_output(t143); + accumulator = outputs.get_output(t144); + accumulator = outputs.get_output(t145); + accumulator = outputs.get_output(t146); + accumulator = outputs.get_output(t147); + accumulator = outputs.get_output(t148); + accumulator = outputs.get_output(t149); + accumulator = outputs.get_output(t150); + accumulator = outputs.get_output(t151); + accumulator = outputs.get_output(t152); + accumulator = outputs.get_output(t153); + accumulator = outputs.get_output(t154); + accumulator = outputs.get_output(t155); + accumulator = outputs.get_output(t156); + accumulator = outputs.get_output(t157); + accumulator = outputs.get_output(t158); + accumulator = outputs.get_output(t159); + accumulator = outputs.get_output(t160); + accumulator = outputs.get_output(t161); + accumulator = outputs.get_output(t162); + accumulator = outputs.get_output(t163); + accumulator = outputs.get_output(t164); + accumulator = outputs.get_output(t165); + accumulator = outputs.get_output(t166); + accumulator = outputs.get_output(t167); + accumulator = outputs.get_output(t168); + accumulator = outputs.get_output(t169); + accumulator = outputs.get_output(t170); + accumulator = outputs.get_output(t171); + accumulator = outputs.get_output(t172); + accumulator = outputs.get_output(t173); + accumulator = outputs.get_output(t174); + accumulator = outputs.get_output(t175); + accumulator = outputs.get_output(t176); + accumulator = outputs.get_output(t177); + accumulator = outputs.get_output(t178); + accumulator = outputs.get_output(t179); + accumulator = outputs.get_output(t180); + accumulator = outputs.get_output(t181); + accumulator = outputs.get_output(t182); + accumulator = outputs.get_output(t183); + accumulator = outputs.get_output(t184); + accumulator = outputs.get_output(t185); + accumulator = outputs.get_output(t186); + accumulator = outputs.get_output(t187); + accumulator = outputs.get_output(t188); + accumulator = outputs.get_output(t189); + accumulator = outputs.get_output(t190); + accumulator = outputs.get_output(t191); + accumulator = outputs.get_output(t192); + accumulator = outputs.get_output(t193); + accumulator = outputs.get_output(t194); + accumulator = outputs.get_output(t195); + accumulator = outputs.get_output(t196); + accumulator = outputs.get_output(t197); + accumulator = outputs.get_output(t198); + accumulator = outputs.get_output(t199); + accumulator = outputs.get_output(t200); + accumulator = outputs.get_output(t201); + accumulator = outputs.get_output(t202); + accumulator = outputs.get_output(t203); + accumulator = outputs.get_output(t204); + accumulator = outputs.get_output(t205); + accumulator = outputs.get_output(t206); + accumulator = outputs.get_output(t207); + accumulator = outputs.get_output(t208); + accumulator = outputs.get_output(t209); + accumulator = outputs.get_output(t210); + accumulator = outputs.get_output(t211); + accumulator = outputs.get_output(t212); + accumulator = outputs.get_output(t213); + accumulator = outputs.get_output(t214); + accumulator = outputs.get_output(t215); + accumulator = outputs.get_output(t216); + accumulator = outputs.get_output(t217); + accumulator = outputs.get_output(t218); + accumulator = outputs.get_output(t219); + accumulator = outputs.get_output(t220); + accumulator = outputs.get_output(t221); + accumulator = outputs.get_output(t222); + accumulator = outputs.get_output(t223); + accumulator = outputs.get_output(t224); + accumulator = outputs.get_output(t225); + accumulator = outputs.get_output(t226); + accumulator = outputs.get_output(t227); + accumulator = outputs.get_output(t228); + accumulator = outputs.get_output(t229); + accumulator = outputs.get_output(t230); + accumulator = outputs.get_output(t231); + accumulator = outputs.get_output(t232); + accumulator = outputs.get_output(t233); + accumulator = outputs.get_output(t234); + accumulator = outputs.get_output(t235); + accumulator = outputs.get_output(t236); + accumulator = outputs.get_output(t237); + accumulator = outputs.get_output(t238); + accumulator = outputs.get_output(t239); + accumulator = outputs.get_output(t240); + accumulator = outputs.get_output(t241); + accumulator = outputs.get_output(t242); + accumulator = outputs.get_output(t243); + accumulator = outputs.get_output(t244); + accumulator = outputs.get_output(t245); + accumulator = outputs.get_output(t246); + accumulator = outputs.get_output(t247); + accumulator = outputs.get_output(t248); + accumulator = outputs.get_output(t249); + accumulator = outputs.get_output(t250); + accumulator = outputs.get_output(t251); + accumulator = outputs.get_output(t252); + accumulator = outputs.get_output(t253); + accumulator = outputs.get_output(t254); + accumulator = outputs.get_output(t255); + accumulator = outputs.get_output(t256); + accumulator = outputs.get_output(t257); + accumulator = outputs.get_output(t258); + accumulator = outputs.get_output(t259); + accumulator = outputs.get_output(t260); + accumulator = outputs.get_output(t261); + accumulator = outputs.get_output(t262); + accumulator = outputs.get_output(t263); + accumulator = outputs.get_output(t264); + accumulator = outputs.get_output(t265); + accumulator = outputs.get_output(t266); + accumulator = outputs.get_output(t267); + accumulator = outputs.get_output(t268); + accumulator = outputs.get_output(t269); + accumulator = outputs.get_output(t270); + accumulator = outputs.get_output(t271); + accumulator = outputs.get_output(t272); + accumulator = outputs.get_output(t273); + accumulator = outputs.get_output(t274); + accumulator = outputs.get_output(t275); + accumulator = outputs.get_output(t276); + accumulator = outputs.get_output(t277); + accumulator = outputs.get_output(t278); + accumulator = outputs.get_output(t279); + accumulator = outputs.get_output(t280); + accumulator = outputs.get_output(t281); + accumulator = outputs.get_output(t282); + accumulator = outputs.get_output(t283); + accumulator = outputs.get_output(t284); + accumulator = outputs.get_output(t285); + accumulator = outputs.get_output(t286); + accumulator = outputs.get_output(t287); + accumulator = outputs.get_output(t288); + accumulator = outputs.get_output(t289); + accumulator = outputs.get_output(t290); + accumulator = outputs.get_output(t291); + accumulator = outputs.get_output(t292); + accumulator = outputs.get_output(t293); + accumulator = outputs.get_output(t294); + accumulator = outputs.get_output(t295); + accumulator = outputs.get_output(t296); + accumulator = outputs.get_output(t297); + accumulator = outputs.get_output(t298); + accumulator = outputs.get_output(t299); + accumulator = outputs.get_output(t300); + accumulator = outputs.get_output(t301); + accumulator = outputs.get_output(t302); + accumulator = outputs.get_output(t303); + accumulator = outputs.get_output(t304); + accumulator = outputs.get_output(t305); + accumulator = outputs.get_output(t306); + accumulator = outputs.get_output(t307); + accumulator = outputs.get_output(t308); + accumulator = outputs.get_output(t309); + accumulator = outputs.get_output(t310); + accumulator = outputs.get_output(t311); + accumulator = outputs.get_output(t312); + accumulator = outputs.get_output(t313); + accumulator = outputs.get_output(t314); + accumulator = outputs.get_output(t315); + accumulator = outputs.get_output(t316); + accumulator = outputs.get_output(t317); + accumulator = outputs.get_output(t318); + accumulator = outputs.get_output(t319); + accumulator = outputs.get_output(t320); + accumulator = outputs.get_output(t321); + accumulator = outputs.get_output(t322); + accumulator = outputs.get_output(t323); + accumulator = outputs.get_output(t324); + accumulator = outputs.get_output(t325); + accumulator = outputs.get_output(t326); + accumulator = outputs.get_output(t327); + accumulator = outputs.get_output(t328); + accumulator = outputs.get_output(t329); + accumulator = outputs.get_output(t330); + accumulator = outputs.get_output(t331); + accumulator = outputs.get_output(t332); + accumulator = outputs.get_output(t333); + accumulator = outputs.get_output(t334); + accumulator = outputs.get_output(t335); + accumulator = outputs.get_output(t336); + accumulator = outputs.get_output(t337); + accumulator = outputs.get_output(t338); + accumulator = outputs.get_output(t339); + accumulator = outputs.get_output(t340); + accumulator = outputs.get_output(t341); + accumulator = outputs.get_output(t342); + accumulator = outputs.get_output(t343); + accumulator = outputs.get_output(t344); + accumulator = outputs.get_output(t345); + accumulator = outputs.get_output(t346); + accumulator = outputs.get_output(t347); + accumulator = outputs.get_output(t348); + accumulator = outputs.get_output(t349); + accumulator = outputs.get_output(t350); + accumulator = outputs.get_output(t351); + accumulator = outputs.get_output(t352); + accumulator = outputs.get_output(t353); + accumulator = outputs.get_output(t354); + accumulator = outputs.get_output(t355); + accumulator = outputs.get_output(t356); + accumulator = outputs.get_output(t357); + accumulator = outputs.get_output(t358); + accumulator = outputs.get_output(t359); + accumulator = outputs.get_output(t360); + accumulator = outputs.get_output(t361); + accumulator = outputs.get_output(t362); + accumulator = outputs.get_output(t363); + accumulator = outputs.get_output(t364); + accumulator = outputs.get_output(t365); + accumulator = outputs.get_output(t366); + accumulator = outputs.get_output(t367); + accumulator = outputs.get_output(t368); + accumulator = outputs.get_output(t369); + accumulator = outputs.get_output(t370); + accumulator = outputs.get_output(t371); + accumulator = outputs.get_output(t372); + accumulator = outputs.get_output(t373); + accumulator = outputs.get_output(t374); + accumulator = outputs.get_output(t375); + accumulator = outputs.get_output(t376); + accumulator = outputs.get_output(t377); + accumulator = outputs.get_output(t378); + accumulator = outputs.get_output(t379); + accumulator = outputs.get_output(t380); + accumulator = outputs.get_output(t381); + accumulator = outputs.get_output(t382); + accumulator = outputs.get_output(t383); + accumulator = outputs.get_output(t384); + accumulator = outputs.get_output(t385); + accumulator = outputs.get_output(t386); + accumulator = outputs.get_output(t387); + accumulator = outputs.get_output(t388); + accumulator = outputs.get_output(t389); + accumulator = outputs.get_output(t390); + accumulator = outputs.get_output(t391); + accumulator = outputs.get_output(t392); + accumulator = outputs.get_output(t393); + accumulator = outputs.get_output(t394); + accumulator = outputs.get_output(t395); + accumulator = outputs.get_output(t396); + accumulator = outputs.get_output(t397); + accumulator = outputs.get_output(t398); + accumulator = outputs.get_output(t399); + accumulator = outputs.get_output(t400); + accumulator = outputs.get_output(t401); + accumulator = outputs.get_output(t402); + accumulator = outputs.get_output(t403); + accumulator = outputs.get_output(t404); + accumulator = outputs.get_output(t405); + accumulator = outputs.get_output(t406); + accumulator = outputs.get_output(t407); + accumulator = outputs.get_output(t408); + accumulator = outputs.get_output(t409); + accumulator = outputs.get_output(t410); + accumulator = outputs.get_output(t411); + accumulator = outputs.get_output(t412); + accumulator = outputs.get_output(t413); + accumulator = outputs.get_output(t414); + accumulator = outputs.get_output(t415); + accumulator = outputs.get_output(t416); + accumulator = outputs.get_output(t417); + accumulator = outputs.get_output(t418); + accumulator = outputs.get_output(t419); + accumulator = outputs.get_output(t420); + accumulator = outputs.get_output(t421); + accumulator = outputs.get_output(t422); + accumulator = outputs.get_output(t423); + accumulator = outputs.get_output(t424); + accumulator = outputs.get_output(t425); + accumulator = outputs.get_output(t426); + accumulator = outputs.get_output(t427); + accumulator = outputs.get_output(t428); + accumulator = outputs.get_output(t429); + accumulator = outputs.get_output(t430); + accumulator = outputs.get_output(t431); + accumulator = outputs.get_output(t432); + accumulator = outputs.get_output(t433); + accumulator = outputs.get_output(t434); + accumulator = outputs.get_output(t435); + accumulator = outputs.get_output(t436); + accumulator = outputs.get_output(t437); + accumulator = outputs.get_output(t438); + accumulator = outputs.get_output(t439); + accumulator = outputs.get_output(t440); + accumulator = outputs.get_output(t441); + accumulator = outputs.get_output(t442); + accumulator = outputs.get_output(t443); + accumulator = outputs.get_output(t444); + accumulator = outputs.get_output(t445); + accumulator = outputs.get_output(t446); + accumulator = outputs.get_output(t447); + accumulator = outputs.get_output(t448); + accumulator = outputs.get_output(t449); + accumulator = outputs.get_output(t450); + accumulator = outputs.get_output(t451); + accumulator = outputs.get_output(t452); + accumulator = outputs.get_output(t453); + accumulator = outputs.get_output(t454); + accumulator = outputs.get_output(t455); + accumulator = outputs.get_output(t456); + accumulator = outputs.get_output(t457); + accumulator = outputs.get_output(t458); + accumulator = outputs.get_output(t459); + accumulator = outputs.get_output(t460); + accumulator = outputs.get_output(t461); + accumulator = outputs.get_output(t462); + accumulator = outputs.get_output(t463); + accumulator = outputs.get_output(t464); + accumulator = outputs.get_output(t465); + accumulator = outputs.get_output(t466); + accumulator = outputs.get_output(t467); + accumulator = outputs.get_output(t468); + accumulator = outputs.get_output(t469); + accumulator = outputs.get_output(t470); + accumulator = outputs.get_output(t471); + accumulator = outputs.get_output(t472); + accumulator = outputs.get_output(t473); + accumulator = outputs.get_output(t474); + accumulator = outputs.get_output(t475); + accumulator = outputs.get_output(t476); + accumulator = outputs.get_output(t477); + accumulator = outputs.get_output(t478); + accumulator = outputs.get_output(t479); + accumulator = outputs.get_output(t480); + accumulator = outputs.get_output(t481); + accumulator = outputs.get_output(t482); + accumulator = outputs.get_output(t483); + accumulator = outputs.get_output(t484); + accumulator = outputs.get_output(t485); + accumulator = outputs.get_output(t486); + accumulator = outputs.get_output(t487); + accumulator = outputs.get_output(t488); + accumulator = outputs.get_output(t489); + accumulator = outputs.get_output(t490); + accumulator = outputs.get_output(t491); + accumulator = outputs.get_output(t492); + accumulator = outputs.get_output(t493); + accumulator = outputs.get_output(t494); + accumulator = outputs.get_output(t495); + accumulator = outputs.get_output(t496); + accumulator = outputs.get_output(t497); + accumulator = outputs.get_output(t498); + accumulator = outputs.get_output(t499); + accumulator = outputs.get_output(t500); + accumulator = outputs.get_output(t501); + accumulator = outputs.get_output(t502); + accumulator = outputs.get_output(t503); + accumulator = outputs.get_output(t504); + accumulator = outputs.get_output(t505); + accumulator = outputs.get_output(t506); + accumulator = outputs.get_output(t507); + accumulator = outputs.get_output(t508); + accumulator = outputs.get_output(t509); + accumulator = outputs.get_output(t510); + accumulator = outputs.get_output(t511); + accumulator = outputs.get_output(t512); + accumulator = outputs.get_output(t513); + accumulator = outputs.get_output(t514); + accumulator = outputs.get_output(t515); + accumulator = outputs.get_output(t516); + accumulator = outputs.get_output(t517); + accumulator = outputs.get_output(t518); + accumulator = outputs.get_output(t519); + accumulator = outputs.get_output(t520); + accumulator = outputs.get_output(t521); + accumulator = outputs.get_output(t522); + accumulator = outputs.get_output(t523); + accumulator = outputs.get_output(t524); + accumulator = outputs.get_output(t525); + accumulator = outputs.get_output(t526); + accumulator = outputs.get_output(t527); + accumulator = outputs.get_output(t528); + accumulator = outputs.get_output(t529); + accumulator = outputs.get_output(t530); + accumulator = outputs.get_output(t531); + accumulator = outputs.get_output(t532); + accumulator = outputs.get_output(t533); + accumulator = outputs.get_output(t534); + accumulator = outputs.get_output(t535); + accumulator = outputs.get_output(t536); + accumulator = outputs.get_output(t537); + accumulator = outputs.get_output(t538); + accumulator = outputs.get_output(t539); + accumulator = outputs.get_output(t540); + accumulator = outputs.get_output(t541); + accumulator = outputs.get_output(t542); + accumulator = outputs.get_output(t543); + accumulator = outputs.get_output(t544); + accumulator = outputs.get_output(t545); + accumulator = outputs.get_output(t546); + accumulator = outputs.get_output(t547); + accumulator = outputs.get_output(t548); + accumulator = outputs.get_output(t549); + accumulator = outputs.get_output(t550); + accumulator = outputs.get_output(t551); + accumulator = outputs.get_output(t552); + accumulator = outputs.get_output(t553); + accumulator = outputs.get_output(t554); + accumulator = outputs.get_output(t555); + accumulator = outputs.get_output(t556); + accumulator = outputs.get_output(t557); + accumulator = outputs.get_output(t558); + accumulator = outputs.get_output(t559); + accumulator = outputs.get_output(t560); + accumulator = outputs.get_output(t561); + accumulator = outputs.get_output(t562); + accumulator = outputs.get_output(t563); + accumulator = outputs.get_output(t564); + accumulator = outputs.get_output(t565); + accumulator = outputs.get_output(t566); + accumulator = outputs.get_output(t567); + accumulator = outputs.get_output(t568); + accumulator = outputs.get_output(t569); + accumulator = outputs.get_output(t570); + accumulator = outputs.get_output(t571); + accumulator = outputs.get_output(t572); + accumulator = outputs.get_output(t573); + accumulator = outputs.get_output(t574); + accumulator = outputs.get_output(t575); + accumulator = outputs.get_output(t576); + accumulator = outputs.get_output(t577); + accumulator = outputs.get_output(t578); + accumulator = outputs.get_output(t579); + accumulator = outputs.get_output(t580); + accumulator = outputs.get_output(t581); + accumulator = outputs.get_output(t582); + accumulator = outputs.get_output(t583); + accumulator = outputs.get_output(t584); + accumulator = outputs.get_output(t585); + accumulator = outputs.get_output(t586); + accumulator = outputs.get_output(t587); + accumulator = outputs.get_output(t588); + accumulator = outputs.get_output(t589); + accumulator = outputs.get_output(t590); + accumulator = outputs.get_output(t591); + accumulator = outputs.get_output(t592); + accumulator = outputs.get_output(t593); + accumulator = outputs.get_output(t594); + accumulator = outputs.get_output(t595); + accumulator = outputs.get_output(t596); + accumulator = outputs.get_output(t597); + accumulator = outputs.get_output(t598); + accumulator = outputs.get_output(t599); + accumulator = outputs.get_output(t600); + accumulator = outputs.get_output(t601); + accumulator = outputs.get_output(t602); + accumulator = outputs.get_output(t603); + accumulator = outputs.get_output(t604); + accumulator = outputs.get_output(t605); + accumulator = outputs.get_output(t606); + accumulator = outputs.get_output(t607); + accumulator = outputs.get_output(t608); + accumulator = outputs.get_output(t609); + accumulator = outputs.get_output(t610); + accumulator = outputs.get_output(t611); + accumulator = outputs.get_output(t612); + accumulator = outputs.get_output(t613); + accumulator = outputs.get_output(t614); + accumulator = outputs.get_output(t615); + accumulator = outputs.get_output(t616); + accumulator = outputs.get_output(t617); + accumulator = outputs.get_output(t618); + accumulator = outputs.get_output(t619); + accumulator = outputs.get_output(t620); + accumulator = outputs.get_output(t621); + accumulator = outputs.get_output(t622); + accumulator = outputs.get_output(t623); + accumulator = outputs.get_output(t624); + accumulator = outputs.get_output(t625); + accumulator = outputs.get_output(t626); + accumulator = outputs.get_output(t627); + accumulator = outputs.get_output(t628); + accumulator = outputs.get_output(t629); + accumulator = outputs.get_output(t630); + accumulator = outputs.get_output(t631); + accumulator = outputs.get_output(t632); + accumulator = outputs.get_output(t633); + accumulator = outputs.get_output(t634); + accumulator = outputs.get_output(t635); + accumulator = outputs.get_output(t636); + accumulator = outputs.get_output(t637); + accumulator = outputs.get_output(t638); + accumulator = outputs.get_output(t639); + accumulator = outputs.get_output(t640); + accumulator = outputs.get_output(t641); + accumulator = outputs.get_output(t642); + accumulator = outputs.get_output(t643); + accumulator = outputs.get_output(t644); + accumulator = outputs.get_output(t645); + accumulator = outputs.get_output(t646); + accumulator = outputs.get_output(t647); + accumulator = outputs.get_output(t648); + accumulator = outputs.get_output(t649); + accumulator = outputs.get_output(t650); + accumulator = outputs.get_output(t651); + accumulator = outputs.get_output(t652); + accumulator = outputs.get_output(t653); + accumulator = outputs.get_output(t654); + accumulator = outputs.get_output(t655); + accumulator = outputs.get_output(t656); + accumulator = outputs.get_output(t657); + accumulator = outputs.get_output(t658); + accumulator = outputs.get_output(t659); + accumulator = outputs.get_output(t660); + accumulator = outputs.get_output(t661); + accumulator = outputs.get_output(t662); + accumulator = outputs.get_output(t663); + accumulator = outputs.get_output(t664); + accumulator = outputs.get_output(t665); + accumulator = outputs.get_output(t666); + accumulator = outputs.get_output(t667); + accumulator = outputs.get_output(t668); + accumulator = outputs.get_output(t669); + accumulator = outputs.get_output(t670); + accumulator = outputs.get_output(t671); + accumulator = outputs.get_output(t672); + accumulator = outputs.get_output(t673); + accumulator = outputs.get_output(t674); + accumulator = outputs.get_output(t675); + accumulator = outputs.get_output(t676); + accumulator = outputs.get_output(t677); + accumulator = outputs.get_output(t678); + accumulator = outputs.get_output(t679); + accumulator = outputs.get_output(t680); + accumulator = outputs.get_output(t681); + accumulator = outputs.get_output(t682); + accumulator = outputs.get_output(t683); + accumulator = outputs.get_output(t684); + accumulator = outputs.get_output(t685); + accumulator = outputs.get_output(t686); + accumulator = outputs.get_output(t687); + accumulator = outputs.get_output(t688); + accumulator = outputs.get_output(t689); + accumulator = outputs.get_output(t690); + accumulator = outputs.get_output(t691); + accumulator = outputs.get_output(t692); + accumulator = outputs.get_output(t693); + accumulator = outputs.get_output(t694); + accumulator = outputs.get_output(t695); + accumulator = outputs.get_output(t696); + accumulator = outputs.get_output(t697); + accumulator = outputs.get_output(t698); + accumulator = outputs.get_output(t699); + accumulator = outputs.get_output(t700); + accumulator = outputs.get_output(t701); + accumulator = outputs.get_output(t702); + accumulator = outputs.get_output(t703); + accumulator = outputs.get_output(t704); + accumulator = outputs.get_output(t705); + accumulator = outputs.get_output(t706); + accumulator = outputs.get_output(t707); + accumulator = outputs.get_output(t708); + accumulator = outputs.get_output(t709); + accumulator = outputs.get_output(t710); + accumulator = outputs.get_output(t711); + accumulator = outputs.get_output(t712); + accumulator = outputs.get_output(t713); + accumulator = outputs.get_output(t714); + accumulator = outputs.get_output(t715); + accumulator = outputs.get_output(t716); + accumulator = outputs.get_output(t717); + accumulator = outputs.get_output(t718); + accumulator = outputs.get_output(t719); + accumulator = outputs.get_output(t720); + accumulator = outputs.get_output(t721); + accumulator = outputs.get_output(t722); + accumulator = outputs.get_output(t723); + accumulator = outputs.get_output(t724); + accumulator = outputs.get_output(t725); + accumulator = outputs.get_output(t726); + accumulator = outputs.get_output(t727); + accumulator = outputs.get_output(t728); + accumulator = outputs.get_output(t729); + accumulator = outputs.get_output(t730); + accumulator = outputs.get_output(t731); + accumulator = outputs.get_output(t732); + accumulator = outputs.get_output(t733); + accumulator = outputs.get_output(t734); + accumulator = outputs.get_output(t735); + accumulator = outputs.get_output(t736); + accumulator = outputs.get_output(t737); + accumulator = outputs.get_output(t738); + accumulator = outputs.get_output(t739); + accumulator = outputs.get_output(t740); + accumulator = outputs.get_output(t741); + accumulator = outputs.get_output(t742); + accumulator = outputs.get_output(t743); + accumulator = outputs.get_output(t744); + accumulator = outputs.get_output(t745); + accumulator = outputs.get_output(t746); + accumulator = outputs.get_output(t747); + accumulator = outputs.get_output(t748); + accumulator = outputs.get_output(t749); + accumulator = outputs.get_output(t750); + accumulator = outputs.get_output(t751); + accumulator = outputs.get_output(t752); + + assert!(accumulator != u384_0); +}