From 1ab9e30d339cfd7a80f333e408c367c1f8bf49f8 Mon Sep 17 00:00:00 2001 From: ledwards2225 <98505400+ledwards2225@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:10:17 -0700 Subject: [PATCH] chore: move decider PK allocation to methods (#10670) Just moves the poly allocation logic in the DeciderPK into methods to make the constructor a bit easier to digest --- .../execution_trace/mega_execution_trace.hpp | 2 +- .../execution_trace/ultra_execution_trace.hpp | 2 +- .../ultra_honk/decider_proving_key.cpp | 144 +++++++++++++- .../ultra_honk/decider_proving_key.hpp | 178 +++--------------- 4 files changed, 170 insertions(+), 156 deletions(-) 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 a24d4131a93..de98846ab47 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 @@ -59,7 +59,7 @@ template struct MegaTraceBlockData { }; } - auto get_gate_blocks() + auto get_gate_blocks() const { return RefArray{ busread, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, lookup 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 92a2c5f8d6b..ccf81b1645c 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 @@ -31,7 +31,7 @@ template struct UltraTraceBlockData { lookup, poseidon2_external, poseidon2_internal, overflow }; } - auto get_gate_blocks() + auto get_gate_blocks() const { return RefArray{ arithmetic, delta_range, elliptic, aux, lookup, poseidon2_external, poseidon2_internal }; } 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 e82b2ccacf9..246c6263200 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -30,6 +30,142 @@ template size_t DeciderProvingKey_::compute_dyadi return circuit.get_circuit_subgroup_size(total_num_gates); } +template void DeciderProvingKey_::allocate_wires() +{ + PROFILE_THIS_NAME("allocate_wires"); + + for (auto& wire : proving_key.polynomials.get_wires()) { + wire = Polynomial::shiftable(proving_key.circuit_size); + } +} + +template void DeciderProvingKey_::allocate_permutation_argument_polynomials() +{ + PROFILE_THIS_NAME("allocate_permutation_argument_polynomials"); + + for (auto& sigma : proving_key.polynomials.get_sigmas()) { + sigma = Polynomial(proving_key.circuit_size); + } + for (auto& id : proving_key.polynomials.get_ids()) { + id = Polynomial(proving_key.circuit_size); + } + proving_key.polynomials.z_perm = Polynomial::shiftable(proving_key.circuit_size); +} + +template void DeciderProvingKey_::allocate_lagrange_polynomials() +{ + PROFILE_THIS_NAME("allocate_lagrange_polynomials"); + + // First and last lagrange polynomials (in the full circuit size) + proving_key.polynomials.lagrange_first = Polynomial( + /* size=*/1, /*virtual size=*/dyadic_circuit_size, /*start_index=*/0); + + // Even though lagrange_last has a single non-zero element, we cannot set its size to 0 as different + // keys being folded might have lagrange_last set at different indexes and folding does not work + // correctly unless the polynomial is allocated in the correct range to accomodate this + proving_key.polynomials.lagrange_last = Polynomial( + /* size=*/dyadic_circuit_size, /*virtual size=*/dyadic_circuit_size, /*start_index=*/0); +} + +template void DeciderProvingKey_::allocate_selectors(const Circuit& circuit) +{ + PROFILE_THIS_NAME("allocate_selectors"); + + // Define gate selectors over the block they are isolated to + for (auto [selector, block] : + zip_view(proving_key.polynomials.get_gate_selectors(), circuit.blocks.get_gate_blocks())) { + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/914): q_arith is currently used + // in aux block. + if (&block == &circuit.blocks.arithmetic) { + size_t arith_size = circuit.blocks.aux.trace_offset - circuit.blocks.arithmetic.trace_offset + + circuit.blocks.aux.get_fixed_size(is_structured); + selector = Polynomial(arith_size, proving_key.circuit_size, circuit.blocks.arithmetic.trace_offset); + } else { + selector = Polynomial(block.get_fixed_size(is_structured), proving_key.circuit_size, block.trace_offset); + } + } + + // Set the other non-gate selector polynomials (e.g. q_l, q_r, q_m etc.) to full size + for (auto& selector : proving_key.polynomials.get_non_gate_selectors()) { + selector = Polynomial(proving_key.circuit_size); + } +} + +template +void DeciderProvingKey_::allocate_table_lookup_polynomials(const Circuit& circuit) +{ + PROFILE_THIS_NAME("allocate_table_lookup_polynomials"); + + const size_t max_tables_size = std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 1); + size_t table_offset = dyadic_circuit_size - max_tables_size; + ASSERT(dyadic_circuit_size > max_tables_size); + + // Allocate the polynomials containing the actual table data + if constexpr (IsUltraFlavor) { + for (auto& poly : proving_key.polynomials.get_tables()) { + poly = Polynomial(max_tables_size, dyadic_circuit_size, table_offset); + } + } + + // Allocate the read counts and tags polynomials + proving_key.polynomials.lookup_read_counts = Polynomial(max_tables_size, dyadic_circuit_size, table_offset); + proving_key.polynomials.lookup_read_tags = Polynomial(max_tables_size, dyadic_circuit_size, table_offset); + ZoneScopedN("allocating lookup and databus inverses"); + + // Allocate the log derivative lookup argument inverse polynomial + const size_t lookup_offset = static_cast(circuit.blocks.lookup.trace_offset); + const size_t lookup_inverses_start = std::min(lookup_offset, table_offset); + const size_t lookup_inverses_end = + std::min(dyadic_circuit_size, + std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), + table_offset + MAX_LOOKUP_TABLES_SIZE)); + proving_key.polynomials.lookup_inverses = + Polynomial(lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); +} + +template +void DeciderProvingKey_::allocate_ecc_op_polynomials(const Circuit& circuit) + requires IsMegaFlavor +{ + PROFILE_THIS_NAME("allocate_ecc_op_polynomials"); + + // Allocate the ecc op wires and selector + const size_t ecc_op_block_size = circuit.blocks.ecc_op.get_fixed_size(is_structured); + const size_t op_wire_offset = circuit.blocks.ecc_op.trace_offset; + for (auto& wire : proving_key.polynomials.get_ecc_op_wires()) { + wire = Polynomial(ecc_op_block_size, proving_key.circuit_size, op_wire_offset); + } + proving_key.polynomials.lagrange_ecc_op = Polynomial(ecc_op_block_size, proving_key.circuit_size, op_wire_offset); +} + +template +void DeciderProvingKey_::allocate_databus_polynomials(const Circuit& circuit) + requires HasDataBus +{ + proving_key.polynomials.calldata = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.calldata_read_counts = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.calldata_read_tags = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.secondary_calldata = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.secondary_calldata_read_counts = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.secondary_calldata_read_tags = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.return_data = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.return_data_read_counts = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + proving_key.polynomials.return_data_read_tags = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + + proving_key.polynomials.databus_id = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); + + // Allocate log derivative lookup argument inverse polynomials + const size_t q_busread_end = + circuit.blocks.busread.trace_offset + circuit.blocks.busread.get_fixed_size(is_structured); + proving_key.polynomials.calldata_inverses = + Polynomial(std::max(circuit.get_calldata().size(), q_busread_end), dyadic_circuit_size); + proving_key.polynomials.secondary_calldata_inverses = + Polynomial(std::max(circuit.get_secondary_calldata().size(), q_busread_end), dyadic_circuit_size); + proving_key.polynomials.return_data_inverses = + Polynomial(std::max(circuit.get_return_data().size(), q_busread_end), dyadic_circuit_size); +} + /** * @brief * @details @@ -39,7 +175,7 @@ template size_t DeciderProvingKey_::compute_dyadi */ template void DeciderProvingKey_::construct_databus_polynomials(Circuit& circuit) - requires IsMegaFlavor + requires HasDataBus { auto& calldata_poly = proving_key.polynomials.calldata; auto& calldata_read_counts = proving_key.polynomials.calldata_read_counts; @@ -51,9 +187,9 @@ void DeciderProvingKey_::construct_databus_polynomials(Circuit& circuit) auto& return_data_read_counts = proving_key.polynomials.return_data_read_counts; auto& return_data_read_tags = proving_key.polynomials.return_data_read_tags; - auto calldata = circuit.get_calldata(); - auto secondary_calldata = circuit.get_secondary_calldata(); - auto return_data = circuit.get_return_data(); + const auto& calldata = circuit.get_calldata(); + const auto& secondary_calldata = circuit.get_secondary_calldata(); + const auto& return_data = circuit.get_return_data(); // Note: We do not utilize a zero row for databus columns for (size_t idx = 0; idx < calldata.size(); ++idx) { 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 b96540d13a8..0fdfbfe7e16 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -98,8 +98,8 @@ template class DeciderProvingKey_ { if constexpr (IsMegaFlavor) { circuit.op_queue->append_nonzero_ops(); } + vinfo("allocating polynomials object in proving key..."); { - PROFILE_THIS_NAME("allocating proving key"); proving_key = ProvingKey(dyadic_circuit_size, circuit.public_inputs.size(), commitment_key); @@ -109,161 +109,24 @@ template class DeciderProvingKey_ { if ((IsMegaFlavor && !is_structured) || (is_structured && circuit.blocks.has_overflow)) { // Allocate full size polynomials proving_key.polynomials = typename Flavor::ProverPolynomials(dyadic_circuit_size); - vinfo("allocated polynomials object in proving key"); } else { // Allocate only a correct amount of memory for each polynomial - // Allocate the wires and selectors polynomials - { - PROFILE_THIS_NAME("allocating wires"); - - for (auto& wire : proving_key.polynomials.get_wires()) { - wire = Polynomial::shiftable(proving_key.circuit_size); - } - } - { - PROFILE_THIS_NAME("allocating gate selectors"); - - // Define gate selectors over the block they are isolated to - for (auto [selector, block] : - zip_view(proving_key.polynomials.get_gate_selectors(), circuit.blocks.get_gate_blocks())) { - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/914): q_arith is currently used - // in aux block. - if (&block == &circuit.blocks.arithmetic) { - size_t arith_size = circuit.blocks.aux.trace_offset - - circuit.blocks.arithmetic.trace_offset + - circuit.blocks.aux.get_fixed_size(is_structured); - selector = Polynomial( - arith_size, proving_key.circuit_size, circuit.blocks.arithmetic.trace_offset); - } else { - selector = Polynomial( - block.get_fixed_size(is_structured), proving_key.circuit_size, block.trace_offset); - } - } - } - { - PROFILE_THIS_NAME("allocating non-gate selectors"); + allocate_wires(); - // Set the other non-gate selector polynomials to full size - for (auto& selector : proving_key.polynomials.get_non_gate_selectors()) { - selector = Polynomial(proving_key.circuit_size); - } - } - if constexpr (IsMegaFlavor) { - PROFILE_THIS_NAME("allocating ecc op wires and selector"); - - // Allocate the ecc op wires and selector - const size_t ecc_op_block_size = circuit.blocks.ecc_op.get_fixed_size(is_structured); - const size_t op_wire_offset = Flavor::has_zero_row ? 1 : 0; - for (auto& wire : proving_key.polynomials.get_ecc_op_wires()) { - wire = Polynomial(ecc_op_block_size, proving_key.circuit_size, op_wire_offset); - } - proving_key.polynomials.lagrange_ecc_op = - Polynomial(ecc_op_block_size, proving_key.circuit_size, op_wire_offset); - } + allocate_permutation_argument_polynomials(); - if constexpr (HasDataBus) { - proving_key.polynomials.calldata = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.calldata_read_counts = - Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.calldata_read_tags = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.secondary_calldata = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.secondary_calldata_read_counts = - Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.secondary_calldata_read_tags = - Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.return_data = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.return_data_read_counts = - Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - proving_key.polynomials.return_data_read_tags = - Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - - proving_key.polynomials.databus_id = Polynomial(MAX_DATABUS_SIZE, proving_key.circuit_size); - } - const size_t max_tables_size = - std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 1); - size_t table_offset = dyadic_circuit_size - max_tables_size; - { - PROFILE_THIS_NAME("allocating table polynomials"); - - ASSERT(dyadic_circuit_size > max_tables_size); - - // Allocate the table polynomials - if constexpr (IsUltraFlavor) { - for (auto& poly : proving_key.polynomials.get_tables()) { - poly = Polynomial(max_tables_size, dyadic_circuit_size, table_offset); - } - } - } - { - PROFILE_THIS_NAME("allocating sigmas and ids"); - - for (auto& sigma : proving_key.polynomials.get_sigmas()) { - sigma = Polynomial(proving_key.circuit_size); - } - for (auto& id : proving_key.polynomials.get_ids()) { - id = Polynomial(proving_key.circuit_size); - } - } - { - ZoneScopedN("allocating lookup read counts and tags"); - // Allocate the read counts and tags polynomials - proving_key.polynomials.lookup_read_counts = - Polynomial(max_tables_size, dyadic_circuit_size, table_offset); - proving_key.polynomials.lookup_read_tags = - Polynomial(max_tables_size, dyadic_circuit_size, table_offset); - } - { - ZoneScopedN("allocating lookup and databus inverses"); - // Allocate the lookup_inverses polynomial - const size_t lookup_offset = static_cast(circuit.blocks.lookup.trace_offset); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts - // at top of trace - const size_t table_offset = - dyadic_circuit_size - - std::min(dyadic_circuit_size - 1, static_cast(MAX_LOOKUP_TABLES_SIZE)); - const size_t lookup_inverses_start = std::min(lookup_offset, table_offset); - const size_t lookup_inverses_end = - std::min(dyadic_circuit_size, - std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), - table_offset + MAX_LOOKUP_TABLES_SIZE)); - proving_key.polynomials.lookup_inverses = Polynomial( - lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); - if constexpr (HasDataBus) { - const size_t q_busread_end = - circuit.blocks.busread.trace_offset + circuit.blocks.busread.get_fixed_size(is_structured); - // Allocate the databus inverse polynomials - proving_key.polynomials.calldata_inverses = - Polynomial(std::max(circuit.get_calldata().size(), q_busread_end), dyadic_circuit_size); - proving_key.polynomials.secondary_calldata_inverses = Polynomial( - std::max(circuit.get_secondary_calldata().size(), q_busread_end), dyadic_circuit_size); - proving_key.polynomials.return_data_inverses = - Polynomial(std::max(circuit.get_return_data().size(), q_busread_end), dyadic_circuit_size); - } - } - { - PROFILE_THIS_NAME("constructing z_perm"); + allocate_selectors(circuit); - // Allocate the z_perm polynomial - vinfo("constructing z_perm..."); - proving_key.polynomials.z_perm = Polynomial::shiftable(proving_key.circuit_size); - vinfo("done constructing z_perm."); - } + allocate_table_lookup_polynomials(circuit); - { - PROFILE_THIS_NAME("allocating lagrange polynomials"); + allocate_lagrange_polynomials(); - // First and last lagrange polynomials (in the full circuit size) - proving_key.polynomials.lagrange_first = Polynomial( - /* size=*/1, /*virtual size=*/dyadic_circuit_size, /*start_idx=*/0); - - // Even though lagrange_last has a single non-zero element, we cannot set its size to 0 as different - // keys being folded might have lagrange_last set at different indexes and folding does not work - // correctly unless the polynomial is allocated in the correct range to accomodate this - proving_key.polynomials.lagrange_last = Polynomial( - /* size=*/dyadic_circuit_size, /*virtual size=*/dyadic_circuit_size, /*start_idx=*/0); + if constexpr (IsMegaFlavor) { + allocate_ecc_op_polynomials(circuit); + } + if constexpr (HasDataBus) { + allocate_databus_polynomials(circuit); } } - vinfo("allocated polynomials object in proving key"); // We can finally set the shifted polynomials now that all of the to_be_shifted polynomials are // defined. proving_key.polynomials.set_shifted(); // Ensure shifted wires are set correctly @@ -272,7 +135,6 @@ template class DeciderProvingKey_ { // Construct and add to proving key the wire, selector and copy constraint polynomials vinfo("populating trace..."); Trace::populate(circuit, proving_key, is_structured); - vinfo("done populating trace."); { PROFILE_THIS_NAME("constructing prover instance after trace populate"); @@ -339,6 +201,22 @@ template class DeciderProvingKey_ { size_t compute_dyadic_size(Circuit&); + void allocate_wires(); + + void allocate_permutation_argument_polynomials(); + + void allocate_lagrange_polynomials(); + + void allocate_selectors(const Circuit&); + + void allocate_table_lookup_polynomials(const Circuit&); + + void allocate_ecc_op_polynomials(const Circuit&) + requires IsMegaFlavor; + + void allocate_databus_polynomials(const Circuit&) + requires HasDataBus; + /** * @brief Compute dyadic size based on a structured trace with fixed block size * @@ -346,7 +224,7 @@ template class DeciderProvingKey_ { size_t compute_structured_dyadic_size(Circuit& circuit) { return circuit.blocks.get_structured_dyadic_size(); } void construct_databus_polynomials(Circuit&) - requires IsMegaFlavor; + requires HasDataBus; static void move_structured_trace_overflow_to_overflow_block(Circuit& circuit); };