11#pragma once
2+ #include " barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp"
23#include " barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp"
34#include < list>
45#include < set>
910#include < vector>
1011
1112namespace cdg {
12-
13- using UltraBlock = bb::UltraTraceBlock;
1413/* *
1514 * We've added a new feature to the static analyzer that tracks which gates contain each variable.
1615 * This is helpful for removing false-positive variables from the analyzer by using gate selectors
@@ -49,6 +48,19 @@ struct KeyEquals {
4948 }
5049};
5150
51+ struct ConnectedComponent {
52+ std::vector<uint32_t > variable_indices;
53+ bool is_range_list_cc;
54+ bool is_finalize_cc;
55+ ConnectedComponent () = default ;
56+ ConnectedComponent (const std::vector<uint32_t >& vector)
57+ : variable_indices(vector)
58+ , is_range_list_cc(false )
59+ , is_finalize_cc(false ) {};
60+ size_t size () const { return variable_indices.size (); }
61+ const std::vector<uint32_t >& vars () const { return variable_indices; }
62+ };
63+
5264/*
5365 * This class describes an arithmetic circuit as an undirected graph, where vertices are variables from the circuit.
5466 * Edges describe connections between variables through gates. We want to find variables that weren't properly
@@ -57,133 +69,91 @@ struct KeyEquals {
5769 * variable wasn't constrained properly. If the number of connected components > 1, it means that there were some missed
5870 * connections between variables.
5971 */
60- template <typename FF> class StaticAnalyzer_ {
72+ template <typename FF, typename CircuitBuilder > class StaticAnalyzer_ {
6173 public:
6274 StaticAnalyzer_ () = default ;
6375 StaticAnalyzer_ (const StaticAnalyzer_& other) = delete ;
6476 StaticAnalyzer_ (StaticAnalyzer_&& other) = delete ;
6577 StaticAnalyzer_& operator =(const StaticAnalyzer_& other) = delete ;
6678 StaticAnalyzer_&& operator =(StaticAnalyzer_&& other) = delete ;
67- StaticAnalyzer_ (bb::UltraCircuitBuilder& ultra_circuit_constructor , bool connect_variables = true );
79+ StaticAnalyzer_ (CircuitBuilder& circuit_builder , bool connect_variables = true );
6880
6981 /* *
7082 * @brief Convert a vector of variable indices to their real indices
71- * @param ultra_circuit_constructor The UltraCircuitBuilder instance
7283 * @param variable_indices The vector of variable indices to convert
7384 * @return std::vector<uint32_t> A vector of real variable indices
7485 */
75- std::vector<uint32_t > to_real (bb::UltraCircuitBuilder& ultra_circuit_constructor,
76- std::vector<uint32_t >& variable_indices)
86+ std::vector<uint32_t > to_real (std::vector<uint32_t >& variable_indices)
7787 {
7888 std::vector<uint32_t > real_variable_indices;
7989 real_variable_indices.reserve (variable_indices.size ());
8090 for (auto & variable_index : variable_indices) {
81- real_variable_indices.push_back (to_real (ultra_circuit_constructor, variable_index));
91+ real_variable_indices.push_back (to_real (variable_index));
8292 }
8393 return real_variable_indices;
8494 };
85-
86- uint32_t to_real (bb::UltraCircuitBuilder& ultra_circuit_constructor, const uint32_t & variable_index)
95+ uint32_t to_real (const uint32_t & variable_index) const
8796 {
88- return ultra_circuit_constructor .real_variable_index [variable_index];
89- };
90- size_t find_block_index (bb::UltraCircuitBuilder& ultra_builder, const UltraBlock & block);
97+ return circuit_builder .real_variable_index [variable_index];
98+ }
99+ size_t find_block_index (const auto & block);
91100 void process_gate_variables (std::vector<uint32_t >& gate_variables, size_t gate_index, size_t blk_idx);
92- std::unordered_map<uint32_t , size_t > get_variables_gate_counts () { return this ->variables_gate_counts ; };
93-
94- std::vector<std::vector<uint32_t >> get_arithmetic_gate_connected_component (
95- bb::UltraCircuitBuilder& ultra_circuit_builder, size_t index, size_t block_idx, UltraBlock& blk);
96- std::vector<uint32_t > get_elliptic_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
97- size_t index,
98- size_t block_idx,
99- UltraBlock& blk);
100- std::vector<uint32_t > get_plookup_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
101- size_t index,
102- size_t block_idx,
103- UltraBlock& blk);
104- std::vector<uint32_t > get_sort_constraint_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
105- size_t index,
106- size_t block_idx,
107- UltraBlock& blk);
108- std::vector<uint32_t > get_poseido2s_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
109- size_t index,
110- size_t block_idx,
111- UltraBlock& blk);
112- std::vector<uint32_t > get_memory_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
113- size_t index,
114- size_t block_idx,
115- UltraBlock& blk);
116- std::vector<uint32_t > get_non_native_field_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
117- size_t index,
118- size_t block_idx,
119- UltraBlock& blk);
120- std::vector<uint32_t > get_rom_table_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
121- const bb::RomTranscript& rom_array);
122- std::vector<uint32_t > get_ram_table_connected_component (bb::UltraCircuitBuilder& ultra_builder,
123- const bb::RamTranscript& ram_array);
101+ std::unordered_map<uint32_t , size_t > get_variables_gate_counts () const { return this ->variables_gate_counts ; };
102+
103+ void process_execution_trace ();
104+
105+ std::vector<std::vector<uint32_t >> get_arithmetic_gate_connected_component (size_t index,
106+ size_t block_idx,
107+ auto & blk);
108+ std::vector<uint32_t > get_elliptic_gate_connected_component (size_t index, size_t block_idx, auto & blk);
109+ std::vector<uint32_t > get_plookup_gate_connected_component (size_t index, size_t block_idx, auto & blk);
110+ std::vector<uint32_t > get_sort_constraint_connected_component (size_t index, size_t block_idx, auto & blk);
111+ std::vector<uint32_t > get_poseido2s_gate_connected_component (size_t index, size_t block_idx, auto & blk);
112+ std::vector<uint32_t > get_non_native_field_gate_connected_component (size_t index, size_t block_idx, auto & blk);
113+ std::vector<uint32_t > get_memory_gate_connected_component (size_t index, size_t block_idx, auto & blk);
114+ std::vector<uint32_t > get_rom_table_connected_component (const bb::RomTranscript& rom_array);
115+ std::vector<uint32_t > get_ram_table_connected_component (const bb::RamTranscript& ram_array);
116+ // functions for MegaCircuitBuilder
117+ std::vector<uint32_t > get_databus_connected_component (size_t index, size_t block_idx, auto & blk);
118+ std::vector<uint32_t > get_eccop_connected_component (size_t index, size_t block_idx, auto & blk);
119+ std::vector<uint32_t > get_eccop_part_connected_component (size_t index, size_t block_idx, auto & blk);
124120
125121 void add_new_edge (const uint32_t & first_variable_index, const uint32_t & second_variable_index);
126- std::vector<uint32_t > get_variable_adjacency_list (const uint32_t & variable_index)
127- {
128- return variable_adjacency_lists[variable_index];
129- };
130-
131122 void depth_first_search (const uint32_t & variable_index,
132123 std::unordered_set<uint32_t >& is_used,
133124 std::vector<uint32_t >& connected_component);
134- std::vector<std::vector<uint32_t >> find_connected_components ();
135-
136- std::vector<uint32_t > find_variables_with_degree_one ();
137- std::unordered_set<uint32_t > get_variables_in_one_gate ();
138-
139- bool find_arithmetic_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder,
140- const uint32_t & variable_idx);
141- bool find_elliptic_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_idx);
142- bool find_lookup_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_idx);
143-
144- size_t get_distance_between_variables (const uint32_t & first_variable_index, const uint32_t & second_variable_index);
125+ void mark_range_list_connected_components ();
126+ void mark_finalize_connected_components ();
127+ std::vector<ConnectedComponent> find_connected_components (bool return_all_connected_components = false );
145128 bool check_vertex_in_connected_component (const std::vector<uint32_t >& connected_component,
146129 const uint32_t & var_index);
147-
148- void connect_all_variables_in_vector (bb::UltraCircuitBuilder& ultra_circuit_builder,
149- const std::vector<uint32_t >& variables_vector);
150- bool check_is_not_constant_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_index);
130+ void connect_all_variables_in_vector (const std::vector<uint32_t >& variables_vector);
131+ bool check_is_not_constant_variable (const uint32_t & variable_index);
151132
152133 std::pair<std::vector<uint32_t >, size_t > get_connected_component_with_index (
153134 const std::vector<std::vector<uint32_t >>& connected_components, size_t index);
154135
155- std::unordered_set<uint32_t > get_variables_in_one_gate_without_range_constraints (
156- bb::UltraCircuitBuilder& ultra_circuit_builder);
157-
158- size_t process_current_decompose_chain (bb::UltraCircuitBuilder& ultra_circuit_constructor,
159- std::unordered_set<uint32_t >& variables_in_one_gate,
160- size_t index);
161- void process_current_plookup_gate (bb::UltraCircuitBuilder& ultra_circuit_builder, size_t gate_index);
162- void remove_unnecessary_decompose_variables (bb::UltraCircuitBuilder& ultra_circuit_builder,
163- std::unordered_set<uint32_t >& variables_in_on_gate,
164- const std::unordered_set<uint32_t >& decompose_variables);
165- void remove_unnecessary_plookup_variables (bb::UltraCircuitBuilder& ultra_circuit_builder);
166- void remove_unnecessary_range_constrains_variables (bb::UltraCircuitBuilder& ultra_builder);
167- std::unordered_set<uint32_t > show_variables_in_one_gate (bb::UltraCircuitBuilder& ultra_circuit_builder);
168-
169- void remove_unnecessary_aes_plookup_variables (std::unordered_set<uint32_t >& variables_in_one_gate,
170- bb::UltraCircuitBuilder& ultra_circuit_builder,
171- bb::plookup::BasicTableId& table_id,
172- size_t gate_index);
173- void remove_unnecessary_sha256_plookup_variables (std::unordered_set<uint32_t >& variables_in_one_gate,
174- bb::UltraCircuitBuilder& ultra_circuit_builder,
175- bb::plookup::BasicTableId& table_id,
176- size_t gate_index);
177- void remove_record_witness_variables (bb::UltraCircuitBuilder& ultra_builder);
178-
179- void print_graph ();
180- void print_connected_components ();
136+ size_t process_current_decompose_chain (size_t index);
137+ void process_current_plookup_gate (size_t gate_index);
138+ void remove_unnecessary_decompose_variables (const std::unordered_set<uint32_t >& decompose_variables);
139+ void remove_unnecessary_plookup_variables ();
140+ void remove_unnecessary_range_constrains_variables ();
141+ std::unordered_set<uint32_t > get_variables_in_one_gate ();
142+
143+ void remove_unnecessary_aes_plookup_variables (bb::plookup::BasicTableId& table_id, size_t gate_index);
144+ void remove_unnecessary_sha256_plookup_variables (bb::plookup::BasicTableId& table_id, size_t gate_index);
145+ void remove_record_witness_variables ();
146+
147+ void print_connected_components_info ();
181148 void print_variables_gate_counts ();
182- void print_variables_edge_counts ();
183- void print_variable_in_one_gate (bb::UltraCircuitBuilder& ultra_builder, const uint32_t real_idx);
149+ void print_variable_in_one_gate (const uint32_t real_idx);
184150 ~StaticAnalyzer_ () = default ;
185151
186152 private:
153+ // Store reference to the circuit builder
154+ CircuitBuilder& circuit_builder;
155+ bool connect_variables;
156+
187157 std::unordered_map<uint32_t , std::vector<uint32_t >>
188158 variable_adjacency_lists; // we use this data structure to contain information about variables and their
189159 // connections between each other
@@ -193,11 +163,17 @@ template <typename FF> class StaticAnalyzer_ {
193163 variables_degree; // we use this data structure to count, how many every variable have edges
194164 std::unordered_map<KeyPair, std::vector<size_t >, KeyHasher, KeyEquals>
195165 variable_gates; // we use this data structure to store gates and TraceBlocks for every variables, where static
196- // analyzer found them in the circuit.
166+ // analyzer finds them in the circuit.
197167 std::unordered_set<uint32_t > variables_in_one_gate;
198168 std::unordered_set<uint32_t > fixed_variables;
169+ std::vector<ConnectedComponent> connected_components;
170+ std::vector<ConnectedComponent>
171+ main_connected_components; // connected components without finalize blocks and range lists
199172};
200173
201- using StaticAnalyzer = StaticAnalyzer_<bb::fr>;
174+ // Type aliases for convenience
175+ using UltraStaticAnalyzer = StaticAnalyzer_<bb::fr, bb::UltraCircuitBuilder>;
176+ using MegaStaticAnalyzer = StaticAnalyzer_<bb::fr, bb::MegaCircuitBuilder>;
177+ using StaticAnalyzer = UltraStaticAnalyzer; // Default to Ultra for backward compatibility
202178
203179} // namespace cdg
0 commit comments