25 const size_t min_size_due_to_lookups = circuit.get_tables_size();
28 size_t min_size_of_execution_trace = circuit.blocks.get_total_content_size();
32 size_t total_num_gates =
33 NUM_DISABLED_ROWS_IN_SUMCHECK + num_zero_rows +
std::max(min_size_due_to_lookups, min_size_of_execution_trace);
36 return circuit.get_circuit_subgroup_size(total_num_gates);
81 for (
auto [selector, block] :
zip_view(polynomials.get_gate_selectors(), circuit.blocks.get_gate_blocks())) {
85 if (&block == &circuit.blocks.arithmetic) {
86 size_t arith_size = circuit.blocks.memory.trace_offset() - circuit.blocks.arithmetic.trace_offset() +
87 circuit.blocks.memory.get_fixed_size(is_structured);
88 selector =
Polynomial(arith_size, dyadic_size(), circuit.blocks.arithmetic.trace_offset());
90 selector =
Polynomial(block.get_fixed_size(is_structured), dyadic_size(), block.trace_offset());
95 for (
auto& selector : polynomials.get_non_gate_selectors()) {
103 BB_BENCH_NAME(
"allocate_table_lookup_and_lookup_read_polynomials");
105 size_t table_offset = circuit.blocks.lookup.trace_offset();
107 const size_t max_tables_size = dyadic_size() - table_offset;
112 for (
auto& poly : polynomials.get_tables()) {
113 poly =
Polynomial(max_tables_size, dyadic_size(), table_offset);
118 polynomials.lookup_read_counts =
Polynomial(max_tables_size, dyadic_size(), table_offset);
119 polynomials.lookup_read_tags =
Polynomial(max_tables_size, dyadic_size(), table_offset);
121 const size_t lookup_block_end =
122 static_cast<size_t>(circuit.blocks.lookup.trace_offset() + circuit.blocks.lookup.get_fixed_size(is_structured));
123 const auto tables_end = circuit.blocks.lookup.trace_offset() + max_tables_size;
127 const size_t lookup_inverses_start = table_offset;
128 const size_t lookup_inverses_end =
std::max(lookup_block_end, tables_end);
130 polynomials.lookup_inverses =
131 Polynomial(lookup_inverses_end - lookup_inverses_start, dyadic_size(), lookup_inverses_start);
152 BB_BENCH_NAME(
"allocate_databus_and_lookup_inverse_polynomials");
153 polynomials.calldata =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
154 polynomials.calldata_read_counts =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
155 polynomials.calldata_read_tags =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
156 polynomials.secondary_calldata =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
157 polynomials.secondary_calldata_read_counts =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
158 polynomials.secondary_calldata_read_tags =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
159 polynomials.return_data =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
160 polynomials.return_data_read_counts =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
161 polynomials.return_data_read_tags =
Polynomial(MAX_DATABUS_SIZE, dyadic_size());
164 const size_t q_busread_end =
165 circuit.blocks.busread.trace_offset() + circuit.blocks.busread.get_fixed_size(is_structured);
166 const size_t calldata_size = circuit.get_calldata().size();
167 const size_t secondary_calldata_size = circuit.get_secondary_calldata().size();
168 const size_t return_data_size = circuit.get_return_data().size();
171 std::max({ calldata_size, secondary_calldata_size, return_data_size, q_busread_end }), dyadic_size());
173 polynomials.calldata_inverses =
Polynomial(
std::max(calldata_size, q_busread_end), dyadic_size());
174 polynomials.secondary_calldata_inverses =
176 polynomials.return_data_inverses =
Polynomial(
std::max(return_data_size, q_busread_end), dyadic_size());
190 auto& calldata_poly = polynomials.calldata;
191 auto& calldata_read_counts = polynomials.calldata_read_counts;
192 auto& calldata_read_tags = polynomials.calldata_read_tags;
193 auto& secondary_calldata_poly = polynomials.secondary_calldata;
194 auto& secondary_calldata_read_counts = polynomials.secondary_calldata_read_counts;
195 auto& secondary_calldata_read_tags = polynomials.secondary_calldata_read_tags;
196 auto& return_data_poly = polynomials.return_data;
197 auto& return_data_read_counts = polynomials.return_data_read_counts;
198 auto& return_data_read_tags = polynomials.return_data_read_tags;
200 const auto&
calldata = circuit.get_calldata();
201 const auto& secondary_calldata = circuit.get_secondary_calldata();
202 const auto& return_data = circuit.get_return_data();
206 for (
size_t idx = 0; idx <
calldata.size(); ++idx) {
207 calldata_poly.at(idx) = circuit.get_variable(
calldata[idx]);
208 calldata_read_counts.at(idx) =
calldata.get_read_count(idx);
209 calldata_read_tags.at(idx) = calldata_read_counts[idx] > 0 ? 1 : 0;
211 for (
size_t idx = 0; idx < secondary_calldata.size(); ++idx) {
212 secondary_calldata_poly.at(idx) = circuit.get_variable(secondary_calldata[idx]);
213 secondary_calldata_read_counts.at(idx) = secondary_calldata.get_read_count(idx);
214 secondary_calldata_read_tags.at(idx) =
215 secondary_calldata_read_counts[idx] > 0 ? 1 : 0;
217 for (
size_t idx = 0; idx < return_data.size(); ++idx) {
218 return_data_poly.at(idx) = circuit.get_variable(return_data[idx]);
219 return_data_read_counts.at(idx) = return_data.get_read_count(idx);
220 return_data_read_tags.at(idx) = return_data_read_counts[idx] > 0 ? 1 : 0;
223 auto& databus_id = polynomials.databus_id;
225 for (
size_t i = 0; i < databus_id.size(); ++i) {
226 databus_id.at(i) = i;
250 auto& blocks = circuit.blocks;
251 auto& overflow_block = circuit.blocks.overflow;
254 blocks.has_overflow = (overflow_block.get_fixed_size() > 0);
256 blocks.compute_offsets(
true);
259 for (
auto& block : blocks.get()) {
260 size_t block_size = block.size();
261 uint32_t fixed_block_size = block.get_fixed_size();
262 if (block_size > fixed_block_size && block != overflow_block) {
264 if (&block == &blocks.pub_inputs) {
265 std::ostringstream oss;
266 oss <<
"WARNING: Number of public inputs (" << block_size
267 <<
") cannot exceed capacity specified in structured trace: " << fixed_block_size;
270 if (&block == &blocks.ecc_op) {
271 std::ostringstream oss;
272 oss <<
"WARNING: Number of ecc op gates (" << block_size
273 <<
") cannot exceed capacity specified in structured trace: " << fixed_block_size;
278 blocks.has_overflow =
true;
283 if (&block == &blocks.memory) {
284 uint32_t overflow_cur_idx =
285 overflow_block.trace_offset() +
static_cast<uint32_t
>(overflow_block.size());
286 overflow_cur_idx -= block.trace_offset();
287 uint32_t
offset = overflow_cur_idx + 1;
288 for (
auto& idx : circuit.memory_read_records) {
290 if (idx == fixed_block_size - 1) {
291 circuit.memory_read_records.push_back(overflow_cur_idx);
293 if (idx >= fixed_block_size) {
294 idx -= fixed_block_size;
298 for (
auto& idx : circuit.memory_write_records) {
300 if (idx == fixed_block_size - 1) {
301 circuit.memory_write_records.push_back(overflow_cur_idx);
303 if (idx >= fixed_block_size) {
304 idx -= fixed_block_size;
311 size_t overflow_start = fixed_block_size - 1;
312 size_t overflow_end = block_size;
313 for (
auto [wire, overflow_wire] :
zip_view(block.wires, overflow_block.wires)) {
314 for (
size_t i = overflow_start; i < overflow_end; ++i) {
315 overflow_wire.push_back(wire[i]);
317 wire.resize(fixed_block_size);
319 for (
auto [selector, overflow_selector] :
zip_view(block.get_selectors(), overflow_block.get_selectors())) {
320 for (
size_t i = overflow_start; i < overflow_end; ++i) {
321 overflow_selector.push_back(selector[i]);
323 selector.resize(fixed_block_size);
328 for (
auto& selector : block.get_gate_selectors()) {
330 selector.set_back(0);
336 if (overflow_block.size() > overflow_block.get_fixed_size()) {
337 info(
"WARNING: Structured trace overflow mechanism in use. Performance may be degraded!");
338 overflow_block.fixed_size =
static_cast<uint32_t
>(overflow_block.size());
351 uint32_t ram_rom_offset = circuit.blocks.memory.trace_offset();
352 memory_read_records.reserve(circuit.memory_read_records.size());
353 for (
auto& index : circuit.memory_read_records) {
354 memory_read_records.emplace_back(index + ram_rom_offset);
356 memory_write_records.reserve(circuit.memory_write_records.size());
357 for (
auto& index : circuit.memory_write_records) {
358 memory_write_records.emplace_back(index + ram_rom_offset);
365#ifdef STARKNET_GARAGA_FLAVORS