diff --git a/barretenberg/cpp/src/barretenberg/benchmark/mega_memory_bench/mega_memory.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/mega_memory_bench/mega_memory.bench.cpp index c5497d01b97a..caa451cfce2c 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/mega_memory_bench/mega_memory.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/mega_memory_bench/mega_memory.bench.cpp @@ -295,14 +295,7 @@ void fill_trace(State& state, TraceSettings settings) fill_lookup_block(builder); { - // finalize doesn't populate public inputs block, so copy to verify that the block is being filled well. - // otherwise the pk construction will overflow the block - // alternative: add to finalize or add a flag to check whether PIs have already been populated - auto builder_copy = builder; - builder_copy.finalize_circuit(/* ensure_nonzero */ false); - DeciderProvingKey::Trace::populate_public_inputs_block(builder_copy); - - for (const auto [label, block] : zip_view(builder_copy.blocks.get_labels(), builder_copy.blocks.get())) { + for (const auto [label, block] : zip_view(builder.blocks.get_labels(), builder.blocks.get())) { bool overfilled = block.size() >= block.get_fixed_size(); if (overfilled) { vinfo(label, " overfilled"); diff --git a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp index b02d82664d2b..37c3e468da35 100644 --- a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp +++ b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp @@ -703,7 +703,7 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change) // The below part detects any changes in the join-split circuit constexpr size_t DYADIC_CIRCUIT_SIZE = 1 << 16; - constexpr uint256_t CIRCUIT_HASH("0x48687216f00a81d2a0f64f0a10cce056fce2ad13c47f8329229eb3712d3f7566"); + constexpr uint256_t CIRCUIT_HASH("0x103eeb052dd7c2f8ebf531bdfadb7d3cee0ab95371289f6d507beaa24b210fba"); const uint256_t circuit_hash = circuit.hash_circuit(); // circuit is finalized now diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp index e1d31a9fac1c..42b0eb09ec0d 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp @@ -220,6 +220,16 @@ class MegaExecutionTraceBlocks : public MegaTraceBlockData { info(""); } + // Get cumulative size of all blocks + size_t get_total_content_size() + { + size_t total_size(0); + for (const auto& block : this->get()) { + total_size += block.size(); + } + return total_size; + } + size_t get_structured_dyadic_size() const { size_t total_size = 1; // start at 1 because the 0th row is unused for selectors for Honk diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp index 0bed250dc39c..a29b70798992 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp @@ -125,6 +125,16 @@ class UltraExecutionTraceBlocks : public UltraTraceBlockData { info("overflow :\t", this->overflow.size()); } + // Get cumulative size of all blocks + size_t get_total_content_size() + { + size_t total_size(0); + for (const auto& block : this->get()) { + total_size += block.size(); + } + return total_size; + } + size_t get_structured_dyadic_size() { size_t total_size = 1; // start at 1 because the 0th row is unused for selectors for Honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp index 572fc9590a09..763d2bfc3a16 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp @@ -52,6 +52,7 @@ void UltraCircuitBuilder_::finalize_circuit(const bool ensure_no process_RAM_arrays(); process_range_lists(); #endif + populate_public_inputs_block(); circuit_finalized = true; } else { // Gates added after first call to finalize will not be processed since finalization is only performed once @@ -1794,6 +1795,24 @@ std::array UltraCircuitBuilder_::evaluate_non_nativ return std::array{ lo_1_idx, hi_3_idx }; } +/** + * @brief Copy the public input idx data into the public inputs trace block + * @note + */ +template void UltraCircuitBuilder_::populate_public_inputs_block() +{ + PROFILE_THIS_NAME("populate_public_inputs_block"); + + // Update the public inputs block + for (const auto& idx : this->public_inputs) { + // first two wires get a copy of the public inputs + blocks.pub_inputs.populate_wires(idx, idx, this->zero_idx, this->zero_idx); + for (auto& selector : this->blocks.pub_inputs.selectors) { + selector.emplace_back(0); + } + } +} + /** * @brief Called in `compute_proving_key` when finalizing circuit. * Iterates over the cached_non_native_field_multiplication objects, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp index d03d2a34caab..6fd2525607f7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp @@ -332,6 +332,8 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase ipa_proof; + void populate_public_inputs_block(); + void process_non_native_field_multiplications(); UltraCircuitBuilder_(const size_t size_hint = 0) : CircuitBuilderBase(size_hint) diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp index bd44c7cebc85..9948d5887775 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp @@ -8,25 +8,6 @@ #include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" namespace bb { -template void TraceToPolynomials::populate_public_inputs_block(Builder& builder) -{ - PROFILE_THIS_NAME("populate_public_inputs_block"); - - // Update the public inputs block - for (const auto& idx : builder.public_inputs) { - for (size_t wire_idx = 0; wire_idx < NUM_WIRES; ++wire_idx) { - if (wire_idx < 2) { // first two wires get a copy of the public inputs - builder.blocks.pub_inputs.wires[wire_idx].emplace_back(idx); - } else { // the remaining wires get zeros - builder.blocks.pub_inputs.wires[wire_idx].emplace_back(builder.zero_idx); - } - } - for (auto& selector : builder.blocks.pub_inputs.selectors) { - selector.emplace_back(0); - } - } -} - template void TraceToPolynomials::populate(Builder& builder, typename Flavor::ProvingKey& proving_key, @@ -89,11 +70,6 @@ typename TraceToPolynomials::TraceData TraceToPolynomials::const PROFILE_THIS_NAME("construct_trace_data"); - if constexpr (IsPlonkFlavor) { - // Complete the public inputs execution trace block from builder.public_inputs - populate_public_inputs_block(builder); - } - TraceData trace_data{ builder, proving_key }; uint32_t offset = Flavor::has_zero_row ? 1 : 0; // Offset at which to place each block in the trace polynomials diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.hpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.hpp index 46dc4dbb9a21..c52590e731ad 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.hpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.hpp @@ -78,14 +78,6 @@ template class TraceToPolynomials { */ static void populate(Builder& builder, ProvingKey&, bool is_structured = false); - /** - * @brief Populate the public inputs block - * @details The first two wires are a copy of the public inputs and the other wires and all selectors are zero - * - * @param circuit - */ - static void populate_public_inputs_block(Builder& builder); - private: /** * @brief Add the memory records indicating which rows correspond to RAM/ROM reads/writes diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 0e97f5dd05a7..2b9560c74a47 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -17,10 +17,7 @@ template size_t DeciderProvingKey_::compute_dyadi const size_t min_size_due_to_lookups = circuit.get_tables_size(); // minimum size of execution trace due to everything else - size_t min_size_of_execution_trace = circuit.public_inputs.size() + circuit.num_gates; - if constexpr (IsMegaFlavor) { - min_size_of_execution_trace += circuit.blocks.ecc_op.size(); - } + size_t min_size_of_execution_trace = circuit.blocks.get_total_content_size(); // The number of gates is the maximum required by the lookup argument or everything else, plus an optional zero row // to allow for shifts. @@ -238,6 +235,7 @@ void DeciderProvingKey_::construct_databus_polynomials(Circuit& circuit) */ template void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_block(Circuit& circuit) + requires IsMegaFlavor { auto& blocks = circuit.blocks; auto& overflow_block = circuit.blocks.overflow; @@ -253,9 +251,19 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc uint32_t fixed_block_size = block.get_fixed_size(); if (block_size > fixed_block_size && block != overflow_block) { // Disallow overflow in blocks that are not expected to be used by App circuits - ASSERT(!block.is_pub_inputs); - if constexpr (IsMegaFlavor) { - ASSERT(block != blocks.ecc_op); + if (block.is_pub_inputs) { + info("WARNING: Number of public inputs (", + block_size, + ") cannot exceed capacity specified in structured trace: ", + fixed_block_size); + ASSERT(false); + } + if (block == blocks.ecc_op) { + info("WARNING: Number of ecc op gates (", + block_size, + ") cannot exceed capacity specified in structured trace: ", + fixed_block_size); + ASSERT(false); } // Set has_overflow to true if at least one block exceeds its capacity @@ -265,7 +273,6 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc // the block containing RAM/ROM gates overflows, the indices of the corresponding gates in the memory // records need to be updated to reflect their new position in the overflow block if (block.has_ram_rom) { - uint32_t overflow_cur_idx = overflow_block.trace_offset + static_cast(overflow_block.size()); overflow_cur_idx -= block.trace_offset; // we'll add block.trace_offset to everything later uint32_t offset = overflow_cur_idx + 1; // +1 accounts for duplication of final gate @@ -316,12 +323,7 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc // Set the fixed size of the overflow block to its current size if (overflow_block.size() > overflow_block.get_fixed_size()) { - info("WARNING: Structured trace overflowed beyond the prescribed fixed overflow size. This is valid in the " - "context of one-off VK/proof generation but not in the IVC setting. \nPrescribed overflow size: ", - overflow_block.get_fixed_size(), - ". \nActual overflow size: ", - overflow_block.size(), - "\n"); + info("WARNING: Structured trace overflow mechanism in use. Performance may be degraded!"); overflow_block.fixed_size = static_cast(overflow_block.size()); blocks.summarize(); } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index 6e500bba50e5..e2da9902b9bb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -81,10 +81,7 @@ template class DeciderProvingKey_ { ". Log dyadic circuit size: ", numeric::get_msb(dyadic_circuit_size), "."); - - // Complete the public inputs execution trace block from circuit.public_inputs - Trace::populate_public_inputs_block(circuit); - circuit.blocks.compute_offsets(is_structured); + circuit.blocks.compute_offsets(is_structured); // compute offset of each block within the trace // Find index of last non-trivial wire value in the trace for (auto& block : circuit.blocks.get()) { @@ -227,7 +224,8 @@ template class DeciderProvingKey_ { void construct_databus_polynomials(Circuit&) requires HasDataBus; - static void move_structured_trace_overflow_to_overflow_block(Circuit& circuit); + static void move_structured_trace_overflow_to_overflow_block(Circuit& circuit) + requires IsMegaFlavor; }; } // namespace bb