diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index 8ecb9e376ce4..bf2f8b5274e4 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -36,23 +36,27 @@ template void compute_concatenated_polynomials(typename Flavor const size_t MINI_CIRCUIT_SIZE = targets[0].size() / Flavor::CONCATENATION_GROUP_SIZE; ASSERT(MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE == targets[0].size()); // A function that produces 1 concatenated polynomial - // TODO(#756): This can be rewritten to use more cores. Currently uses at maximum the number of concatenated - // polynomials (4 in Goblin Translator) - auto ordering_function = [&](size_t i) { + + // Goblin Translator uses concatenated polynomials in the permutation argument. These polynomials contain the same + // coefficients as other shorter polynomials, but we don't have to commit to them due to reusing commitments of + // shorter polynomials and updating our PCS to open using them. But the prover still needs the concatenated + // polynomials. This function constructs a chunk of the polynomial. + auto ordering_function = [&](size_t index) { + // Get the index of the concatenated polynomial + size_t i = index / concatenation_groups[0].size(); + // Get the index of the original polynomial + size_t j = index % concatenation_groups[0].size(); auto my_group = concatenation_groups[i]; auto& current_target = targets[i]; - // For each polynomial in group - for (size_t j = 0; j < my_group.size(); j++) { - auto starting_write_offset = current_target.begin(); - auto finishing_read_offset = my_group[j].begin(); - std::advance(starting_write_offset, j * MINI_CIRCUIT_SIZE); - std::advance(finishing_read_offset, MINI_CIRCUIT_SIZE); - // Copy into appropriate position in the concatenated polynomial - std::copy(my_group[j].begin(), finishing_read_offset, starting_write_offset); - } + auto starting_write_offset = current_target.begin(); + auto finishing_read_offset = my_group[j].begin(); + std::advance(starting_write_offset, j * MINI_CIRCUIT_SIZE); + std::advance(finishing_read_offset, MINI_CIRCUIT_SIZE); + // Copy into appropriate position in the concatenated polynomial + std::copy(my_group[j].begin(), finishing_read_offset, starting_write_offset); }; - parallel_for(concatenation_groups.size(), ordering_function); + parallel_for(concatenation_groups.size() * concatenation_groups[0].size(), ordering_function); } /** diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp index e79c88500629..519f1a4e1196 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp @@ -62,6 +62,15 @@ template class GoblinTranslatorDecompositionRelationImpl { 3 // decomposition of z2 into 2 limbs subrelation }; + /** + * @brief Returns true if the contribution from all subrelations for the provided inputs is identically zero + * + */ + template inline static bool skip(const AllEntities& in) + { + return in.lagrange_odd_in_minicircuit.is_zero(); + } + /** * @brief Expression for decomposition of various values into smaller limbs or microlimbs. * @details This relation enforces three types of subrelations: diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp index d4d927ab4ee6..3d0805af27c0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp @@ -13,6 +13,11 @@ template class GoblinTranslatorOpcodeConstraintRelationImpl { 7 // opcode constraint relation }; + /** + * @brief Returns true if the contribution from all subrelations for the provided inputs is identically zero + * + */ + template inline static bool skip(const AllEntities& in) { return in.op.is_zero(); } /** * @brief Expression for enforcing the value of the Opcode to be {0,1,2,3,4,8} * @details This relation enforces the opcode to be one of described values. Since we don't care about even @@ -53,6 +58,19 @@ template class GoblinTranslatorAccumulatorTransferRelationImpl { }; + /** + * @brief Returns true if the contribution from all subrelations for the provided inputs is identically zero + * + * @details This has a negligible chance of failing in sumcheck (not in the first round) because effectively + * transfrom original coefficients into a random linear combination. But checking each individually is noticeably + * slower. + * + */ + template inline static bool skip(const AllEntities& in) + { + return (in.lagrange_even_in_minicircuit + in.lagrange_second_to_last_in_minicircuit + in.lagrange_second) + .is_zero(); + } /** * @brief Relation enforcing non-arithmetic transitions of accumulator (value that is tracking the batched * evaluation of polynomials in non-native field) diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp index f2e988319d64..dc94e814ad3d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp @@ -15,6 +15,14 @@ template class GoblinTranslatorNonNativeFieldRelationImpl { 3 // Prime subrelation (checks result in native field) }; + /** + * @brief Returns true if the contribution from all subrelations for the provided inputs is identically zero + * + */ + template inline static bool skip(const AllEntities& in) + { + return in.lagrange_odd_in_minicircuit.is_zero(); + } /** * @brief Expression for the computation of Goblin Translator accumulator in integers through 68-bit limbs and * native field (prime) limb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp index 52776acbe42d..9fe6babcf77a 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp @@ -35,9 +35,11 @@ void GoblinTranslatorProver::compute_witness(CircuitBuilder& circuit_builder) // Populate the wire polynomials from the wire vectors in the circuit constructor. Note: In goblin translator wires // come as is, since they have to reflect the structure of polynomials in the first 4 wires, which we've commited to for (auto [wire_poly, wire] : zip_view(key->polynomials.get_wires(), circuit_builder.wires)) { - for (size_t i = 0; i < circuit_builder.num_gates; ++i) { - wire_poly[i] = circuit_builder.get_variable(wire[i]); - } + run_loop_in_parallel(circuit_builder.num_gates, [&](size_t start, size_t end) { + for (size_t i = start; i < end; i++) { + wire_poly[i] = circuit_builder.get_variable(wire[i]); + } + }); } // We construct concatenated versions of range constraint polynomials, where several polynomials are concatenated