From dea0b420ec7745612a0ac943c31914221a89556c Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 17 Apr 2024 13:22:00 +0000 Subject: [PATCH 01/13] Parallelise pertubator --- .../protogalaxy/protogalaxy_prover.hpp | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 470d8f110b5..ee3fd0c08d0 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -209,14 +209,20 @@ template class ProtoGalaxyProver_ { auto prev_level_width = prev_level_coeffs.size(); // we need degree + 1 terms to represent the intermediate polynomials std::vector> level_coeffs(prev_level_width >> 1, std::vector(degree + 1, 0)); - for (size_t node = 0; node < prev_level_width; node += 2) { - auto parent = node >> 1; - std::copy(prev_level_coeffs[node].begin(), prev_level_coeffs[node].end(), level_coeffs[parent].begin()); - for (size_t d = 0; d < degree; d++) { - level_coeffs[parent][d] += prev_level_coeffs[node + 1][d] * betas[level]; - level_coeffs[parent][d + 1] += prev_level_coeffs[node + 1][d] * deltas[level]; - } - } + run_loop_in_parallel( + prev_level_width >> 1, + [&](size_t start, size_t end) { + for (size_t node = start << 1; node < end << 1; node += 2) { + auto parent = node >> 1; + std::copy( + prev_level_coeffs[node].begin(), prev_level_coeffs[node].end(), level_coeffs[parent].begin()); + for (size_t d = 0; d < degree; d++) { + level_coeffs[parent][d] += prev_level_coeffs[node + 1][d] * betas[level]; + level_coeffs[parent][d + 1] += prev_level_coeffs[node + 1][d] * deltas[level]; + } + } + }, + 8); return construct_coefficients_tree(betas, deltas, level_coeffs, level + 1); } @@ -236,11 +242,14 @@ template class ProtoGalaxyProver_ { { auto width = full_honk_evaluations.size(); std::vector> first_level_coeffs(width >> 1, std::vector(2, 0)); - for (size_t node = 0; node < width; node += 2) { - auto parent = node >> 1; - first_level_coeffs[parent][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; - first_level_coeffs[parent][1] = full_honk_evaluations[node + 1] * deltas[0]; - } + run_loop_in_parallel(width >> 1, [&](size_t start, size_t end) { + for (size_t node = start << 1; node < end << 1; node += 2) { + auto parent = node >> 1; + first_level_coeffs[parent][0] = + full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; + first_level_coeffs[parent][1] = full_honk_evaluations[node + 1] * deltas[0]; + } + }); return construct_coefficients_tree(betas, deltas, first_level_coeffs); } @@ -309,9 +318,10 @@ template class ProtoGalaxyProver_ { size_t common_instance_size = instances[0]->proving_key.circuit_size; pow_betas.compute_values(); // Determine number of threads for multithreading. - // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based - // on a specified minimum number of iterations per thread. This eventually leads to the use of a single thread. - // For now we use a power of 2 number of threads simply to ensure the round size is evenly divided. + // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available + // based on a specified minimum number of iterations per thread. This eventually leads to the use of a + // single thread. For now we use a power of 2 number of threads simply to ensure the round size is evenly + // divided. size_t max_num_threads = get_num_cpus_pow2(); // number of available threads (power of 2) size_t min_iterations_per_thread = 1 << 6; // min number of iterations for which we'll spin up a unique thread size_t desired_num_threads = common_instance_size / min_iterations_per_thread; @@ -340,9 +350,9 @@ template class ProtoGalaxyProver_ { FF pow_challenge = pow_betas[idx]; - // Accumulate the i-th row's univariate contribution. Note that the relation parameters passed to this - // function have already been folded. Moreover, linear-dependent relations that act over the entire - // execution trace rather than on rows, will not be multiplied by the pow challenge. + // Accumulate the i-th row's univariate contribution. Note that the relation parameters passed to + // this function have already been folded. Moreover, linear-dependent relations that act over the + // entire execution trace rather than on rows, will not be multiplied by the pow challenge. accumulate_relation_univariates( thread_univariate_accumulators[thread_idx], extended_univariates[thread_idx], @@ -362,7 +372,6 @@ template class ProtoGalaxyProver_ { static ExtendedUnivariateWithRandomization batch_over_relations(TupleOfTuplesOfUnivariates& univariate_accumulators, const CombinedRelationSeparator& alpha) { - // First relation does not get multiplied by a batching challenge auto result = std::get<0>(std::get<0>(univariate_accumulators)) .template extend_to(); From 9e89bfd437b1957269014070bd9851a8088743e3 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 17 Apr 2024 17:31:37 +0000 Subject: [PATCH 02/13] poc --- .../cpp/src/barretenberg/flavor/flavor.hpp | 20 +++++++ .../barretenberg/polynomials/univariate.hpp | 15 ++++- .../protogalaxy/protogalaxy_prover.hpp | 60 ++++++++++++++++--- .../barretenberg/relations/relation_types.hpp | 27 +++++++++ .../goblin_ultra_flavor.hpp | 4 ++ .../stdlib_circuit_builders/ultra_flavor.hpp | 3 + .../barretenberg/vm/generated/avm_flavor.hpp | 3 + 7 files changed, 122 insertions(+), 10 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index d2a847a0dbc..6be12a498ff 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -241,6 +241,26 @@ static constexpr auto create_protogalaxy_tuple_of_tuples_of_univariates() } } +/** + * @brief Recursive utility function to construct a container for the subrelation accumulators of Protogalaxy folding. + * @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of + * univariates whose size is equal to the number of subrelations of the relation. The length of a univariate in an inner + * tuple is determined by the corresponding subrelation length and the number of instances to be folded. + */ +template +static constexpr auto create_optimised_protogalaxy_tuple_of_tuples_of_univariates() +{ + if constexpr (Index >= std::tuple_size::value) { + return std::tuple<>{}; // Return empty when reach end of the tuple + } else { + using UnivariateTuple = typename std::tuple_element_t:: + template OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations; + return std::tuple_cat( + std::tuple{}, + create_optimised_protogalaxy_tuple_of_tuples_of_univariates()); + } +} + /** * @brief Recursive utility function to construct a container for the subrelation accumulators of sumcheck proving. * @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index aedc1353787..943f9be4201 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -271,7 +271,7 @@ template class Univariate * subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 = f(2) + Δ... * */ - template Univariate extend_to() const + template Univariate extend_to() const { const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; using Data = BarycentricData; @@ -282,11 +282,20 @@ template class Univariate std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin()); static constexpr Fr inverse_two = Fr(2).invert(); + // static_assert(!optimised || (LENGTH <= 2)); if constexpr (LENGTH == 2) { Fr delta = value_at(1) - value_at(0); static_assert(EXTENDED_LENGTH != 0); - for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { - result.value_at(idx + 1) = result.value_at(idx) + delta; + if constexpr (optimised) { + Fr current = result.value_at(1); + for (size_t idx = domain_end - 2; idx < EXTENDED_DOMAIN_END - 1; idx++) { + current += delta; + result.value_at(idx + 1) = current; + } + } else { + for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { + result.value_at(idx + 1) = result.value_at(idx) + delta; + } } return result; } else if constexpr (LENGTH == 3) { diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index ee3fd0c08d0..423cd67afda 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -49,15 +49,21 @@ template class ProtoGalaxyProver_ { // The length of ExtendedUnivariate is the largest length (==max_relation_degree + 1) of a univariate polynomial // obtained by composing a relation with folded instance + relation parameters . using ExtendedUnivariate = Univariate; + using OptimisedExtendedUnivariate = + Univariate; // Represents the total length of the combiner univariate, obtained by combining the already folded relations with // the folded relation batching challenge. using ExtendedUnivariateWithRandomization = Univariate; using ExtendedUnivariates = typename Flavor::template ProverUnivariates; + using OptimisedExtendedUnivariates = + typename Flavor::template ProverUnivariates; using TupleOfTuplesOfUnivariates = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates; + using OptimisedTupleOfTuplesOfUnivariates = + typename Flavor::template OptimisedProtogalaxyTupleOfTuplesOfUnivariates; using RelationEvaluations = typename Flavor::TupleOfArraysOfValues; static constexpr size_t NUM_SUBRELATIONS = ProverInstances::NUM_SUBRELATIONS; @@ -291,9 +297,27 @@ template class ProtoGalaxyProver_ { } } + /** + * @brief Prepare a univariate polynomial for relation execution in one step of the main loop in folded instance + * construction. + * @details For a fixed prover polynomial index, extract that polynomial from each instance in Instances. From each + * polynomial, extract the value at row_idx. Use these values to create a univariate polynomial, and then extend + * (i.e., compute additional evaluations at adjacent domain values) as needed. + * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/751) Optimize memory + */ + void optimised_extend_univariates(OptimisedExtendedUnivariates& extended_univariates, + const ProverInstances& instances, + const size_t row_idx) + { + auto base_univariates = instances.row_to_univariates(row_idx); + for (auto [extended_univariate, base_univariate] : zip_view(extended_univariates.get_all(), base_univariates)) { + extended_univariate = base_univariate.template extend_to(); + } + } + template - void accumulate_relation_univariates(TupleOfTuplesOfUnivariates& univariate_accumulators, - const ExtendedUnivariates& extended_univariates, + void accumulate_relation_univariates(OptimisedTupleOfTuplesOfUnivariates& univariate_accumulators, + const OptimisedExtendedUnivariates& extended_univariates, const Parameters& relation_parameters, const FF& scaling_factor) { @@ -329,14 +353,14 @@ template class ProtoGalaxyProver_ { num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1 size_t iterations_per_thread = common_instance_size / num_threads; // actual iterations per thread // Construct univariate accumulator containers; one per thread - std::vector thread_univariate_accumulators(num_threads); + std::vector thread_univariate_accumulators(num_threads); for (auto& accum : thread_univariate_accumulators) { // just normal relation lengths Utils::zero_univariates(accum); } // Construct extended univariates containers; one per thread - std::vector extended_univariates; + std::vector extended_univariates; extended_univariates.resize(num_threads); // Accumulate the contribution from each sub-relation @@ -346,7 +370,7 @@ template class ProtoGalaxyProver_ { for (size_t idx = start; idx < end; idx++) { // No need to initialise extended_univariates to 0, it's assigned to - extend_univariates(extended_univariates[thread_idx], instances, idx); + optimised_extend_univariates(extended_univariates[thread_idx], instances, idx); FF pow_challenge = pow_betas[idx]; @@ -360,15 +384,36 @@ template class ProtoGalaxyProver_ { pow_challenge); } }); - + OptimisedTupleOfTuplesOfUnivariates optimised_univariate_accumulators; + Utils::zero_univariates(optimised_univariate_accumulators); // Accumulate the per-thread univariate accumulators into a single set of accumulators for (auto& accumulators : thread_univariate_accumulators) { - Utils::add_nested_tuples(univariate_accumulators, accumulators); + Utils::add_nested_tuples(optimised_univariate_accumulators, accumulators); } + deoptimise_univariates(optimised_univariate_accumulators, univariate_accumulators); // Batch the univariate contributions from each sub-relation to obtain the round univariate return batch_over_relations(univariate_accumulators, instances.alphas); } + static void deoptimise_univariates(OptimisedTupleOfTuplesOfUnivariates& optimised_univariate_accumulators, + TupleOfTuplesOfUnivariates& univariate_accumulators + + ) + { + auto deoptimise = [&](auto& element) { + auto& optimised_element = std::get(std::get(optimised_univariate_accumulators)); + static_assert(std::remove_reference_t::LENGTH + (ProverInstances::NUM - 1) == + std::remove_reference_t::LENGTH); + element.evaluations[0] = optimised_element.evaluations[0]; + element.evaluations[1] = FF(0); + for (size_t i = 1; i < std::remove_reference_t::LENGTH; i++) { + element.evaluations[i + 1] = optimised_element.evaluations[i]; + } + }; + + Utils::template apply_to_tuple_of_tuples<0, 0>(univariate_accumulators, deoptimise); + } + static ExtendedUnivariateWithRandomization batch_over_relations(TupleOfTuplesOfUnivariates& univariate_accumulators, const CombinedRelationSeparator& alpha) { @@ -378,6 +423,7 @@ template class ProtoGalaxyProver_ { size_t idx = 0; auto scale_and_sum = [&](auto& element) { auto extended = element.template extend_to(); + // info("Relation ", outer_idx, ".", inner_idx, "[", 0, "] = ", extended.value_at(0)); extended *= alpha[idx]; result += extended; idx++; diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp index aa4ba8820b7..87f1cfdd0d0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp @@ -89,6 +89,28 @@ consteval std::array compute_composed_subrelation_part return SUBRELATION_PARTIAL_LENGTHS; }; +/** + * @brief Get the subrelation accumulators for the Protogalaxy combiner calculation. + * @details A subrelation of degree D, when evaluated on polynomials of degree N, gives a polynomial of degree D + * * N. In the context of Protogalaxy, N = NUM_INSTANCES-1. Hence, given a subrelation of length x, its + * evaluation on such polynomials will have degree (x-1) * (NUM_INSTANCES-1), and the length of this evaluation + * will be one greater than this. + * @tparam NUM_INSTANCES + * @tparam NUM_SUBRELATIONS + * @param SUBRELATION_PARTIAL_LENGTHS The array of subrelation lengths supplied by a relation. + * @return The transformed subrelation lenths + */ +template +consteval std::array compute_optimised_composed_subrelation_partial_lengths( + std::array SUBRELATION_PARTIAL_LENGTHS) +{ + std::transform(SUBRELATION_PARTIAL_LENGTHS.begin(), + SUBRELATION_PARTIAL_LENGTHS.end(), + SUBRELATION_PARTIAL_LENGTHS.begin(), + [](const size_t x) { return (x - 2) * (NUM_INSTANCES - 1) + 1; }); + return SUBRELATION_PARTIAL_LENGTHS; +}; + /** * @brief The templates defined herein facilitate sharing the relation arithmetic between the prover and the * verifier. @@ -149,6 +171,11 @@ template class Relation : public RelationImpl { template using ProtogalaxyTupleOfUnivariatesOverSubrelations = TupleOfUnivariates(SUBRELATION_TOTAL_LENGTHS)>; + template + using OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations = + TupleOfUnivariates( + SUBRELATION_TOTAL_LENGTHS)>; using SumcheckTupleOfUnivariatesOverSubrelations = TupleOfUnivariates; using SumcheckArrayOfValuesOverSubrelations = ArrayOfValues; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp index 677749016b5..d5f4b8a2c4e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp @@ -87,6 +87,10 @@ class GoblinUltraFlavor { template using ProtogalaxyTupleOfTuplesOfUnivariates = decltype(create_protogalaxy_tuple_of_tuples_of_univariates()); + + template + using OptimisedProtogalaxyTupleOfTuplesOfUnivariates = + decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates()); using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index bb40fe0c7ff..618dedcecb3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -75,6 +75,9 @@ class UltraFlavor { template using ProtogalaxyTupleOfTuplesOfUnivariates = decltype(create_protogalaxy_tuple_of_tuples_of_univariates()); + template + using OptimisedProtogalaxyTupleOfTuplesOfUnivariates = + decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates()); using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 1f16a50834d..23e33c7df7e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -160,6 +160,9 @@ class AvmFlavor { template using ProtogalaxyTupleOfTuplesOfUnivariates = decltype(create_protogalaxy_tuple_of_tuples_of_univariates()); + template + using OptimisedProtogalaxyTupleOfTuplesOfUnivariates = + decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates()); using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); From 84d908fb6fd53841a845c79e16a17a76b10f7132 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Thu, 18 Apr 2024 13:07:45 +0000 Subject: [PATCH 03/13] More generic, less efficient --- .../barretenberg/polynomials/univariate.hpp | 31 +++++++++---------- .../protogalaxy/protogalaxy_prover.hpp | 3 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 943f9be4201..044a4e97fde 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -271,9 +271,10 @@ template class Univariate * subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 = f(2) + Δ... * */ - template Univariate extend_to() const + template + Univariate extend_to() const { - const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; + const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start + NUM_SKIPPED_INDICES; using Data = BarycentricData; static_assert(EXTENDED_LENGTH >= LENGTH); @@ -282,22 +283,13 @@ template class Univariate std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin()); static constexpr Fr inverse_two = Fr(2).invert(); - // static_assert(!optimised || (LENGTH <= 2)); + static_assert(NUM_SKIPPED_INDICES < LENGTH); if constexpr (LENGTH == 2) { Fr delta = value_at(1) - value_at(0); static_assert(EXTENDED_LENGTH != 0); - if constexpr (optimised) { - Fr current = result.value_at(1); - for (size_t idx = domain_end - 2; idx < EXTENDED_DOMAIN_END - 1; idx++) { - current += delta; - result.value_at(idx + 1) = current; - } - } else { - for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { - result.value_at(idx + 1) = result.value_at(idx) + delta; - } + for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { + result.value_at(idx + 1) = result.value_at(idx) + delta; } - return result; } else if constexpr (LENGTH == 3) { // Based off https://hackmd.io/@aztec-network/SyR45cmOq?type=view // The technique used here is the same as the length == 3 case below. @@ -313,7 +305,6 @@ template class Univariate result.value_at(idx + 1) = result.value_at(idx) + extra; extra += a2; } - return result; } else if constexpr (LENGTH == 4) { static constexpr Fr inverse_six = Fr(6).invert(); // computed at compile time for efficiency @@ -377,7 +368,6 @@ template class Univariate linear_term += three_a_plus_two_b; } - return result; } else { for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) { result.value_at(k) = 0; @@ -390,8 +380,17 @@ template class Univariate // scale the sum by the the value of of B(x) result.value_at(k) *= Data::full_numerator_values[k]; } + } + if constexpr (NUM_SKIPPED_INDICES == 0) { return result; } + Univariate optimised_result; + optimised_result.value_at(0) = result.value_at(0); + + std::copy(std::next(result.begin(), 1 + NUM_SKIPPED_INDICES), + result.evaluations.end(), + std::next(optimised_result.begin(), 1)); + return optimised_result; } /** diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 423cd67afda..b908ce342f1 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -311,7 +311,8 @@ template class ProtoGalaxyProver_ { { auto base_univariates = instances.row_to_univariates(row_idx); for (auto [extended_univariate, base_univariate] : zip_view(extended_univariates.get_all(), base_univariates)) { - extended_univariate = base_univariate.template extend_to(); + extended_univariate = + base_univariate.template extend_to(); } } From 6c26d5392dd8bc032f461ae4f775df05cfca9fc2 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Mon, 22 Apr 2024 13:56:14 +0000 Subject: [PATCH 04/13] Parameters --- .../src/barretenberg/polynomials/univariate.hpp | 4 ++-- .../protogalaxy/protogalaxy_prover.hpp | 16 ++++++++++++---- .../barretenberg/sumcheck/instance/instances.hpp | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 044a4e97fde..4bab8790d05 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -387,9 +387,9 @@ template class Univariate Univariate optimised_result; optimised_result.value_at(0) = result.value_at(0); - std::copy(std::next(result.begin(), 1 + NUM_SKIPPED_INDICES), + std::copy(std::next(result.evaluations.begin(), 1 + NUM_SKIPPED_INDICES), result.evaluations.end(), - std::next(optimised_result.begin(), 1)); + std::next(optimised_result.evaluations.begin(), 1)); return optimised_result; } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index b908ce342f1..7c3d96ebaa5 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -381,7 +381,7 @@ template class ProtoGalaxyProver_ { accumulate_relation_univariates( thread_univariate_accumulators[thread_idx], extended_univariates[thread_idx], - instances.relation_parameters, // these parameters have already been folded + instances.optimised_relation_parameters, // these parameters have already been folded pow_challenge); } }); @@ -406,10 +406,13 @@ template class ProtoGalaxyProver_ { static_assert(std::remove_reference_t::LENGTH + (ProverInstances::NUM - 1) == std::remove_reference_t::LENGTH); element.evaluations[0] = optimised_element.evaluations[0]; - element.evaluations[1] = FF(0); + for (size_t i = 1; i < ProverInstances::NUM; i++) { + element.evaluations[i] = FF(0); + } for (size_t i = 1; i < std::remove_reference_t::LENGTH; i++) { - element.evaluations[i + 1] = optimised_element.evaluations[i]; + element.evaluations[i + ProverInstances::NUM - 1] = optimised_element.evaluations[i]; } + info("Element ", outer_idx, ".", inner_idx, "[", ":", "] = ", element); }; Utils::template apply_to_tuple_of_tuples<0, 0>(univariate_accumulators, deoptimise); @@ -488,7 +491,8 @@ template class ProtoGalaxyProver_ { { size_t param_idx = 0; auto to_fold = instances.relation_parameters.get_to_fold(); - for (auto& folded_parameter : to_fold) { + auto to_fold_optimised = instances.optimised_relation_parameters.get_to_fold(); + for (auto [folded_parameter, optimised_folded_parameter] : zip_view(to_fold, to_fold_optimised)) { Univariate tmp(0); size_t instance_idx = 0; for (auto& instance : instances) { @@ -496,6 +500,10 @@ template class ProtoGalaxyProver_ { instance_idx++; } folded_parameter = tmp.template extend_to(); + optimised_folded_parameter.value_at(0) = folded_parameter.value_at(0); + std::copy(std::next(folded_parameter.evaluations.begin(), ProverInstances::NUM), + folded_parameter.evaluations.end(), + std::next(optimised_folded_parameter.evaluations.begin(), 1)); param_idx++; } } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp index dcfc8883098..e436270a49c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp @@ -18,9 +18,11 @@ template struct ProverInstances_ { static constexpr size_t EXTENDED_LENGTH = (Flavor::MAX_TOTAL_RELATION_LENGTH - 1) * (NUM - 1) + 1; static constexpr size_t BATCHED_EXTENDED_LENGTH = (Flavor::MAX_TOTAL_RELATION_LENGTH - 1 + NUM - 1) * (NUM - 1) + 1; using RelationParameters = bb::RelationParameters>; + using OptimisedRelationParameters = bb::RelationParameters>; using RelationSeparator = std::array, NUM_SUBRELATIONS - 1>; ArrayType _data; RelationParameters relation_parameters; + OptimisedRelationParameters optimised_relation_parameters; RelationSeparator alphas; std::vector next_gate_challenges; From c739afa56f147c7c63ea2dd53af8cf97474833ea Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 24 Apr 2024 14:56:02 +0000 Subject: [PATCH 05/13] Different strategy --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 6 + .../barretenberg/polynomials/univariate.hpp | 188 ++++++++++-------- .../protogalaxy/protogalaxy_prover.hpp | 52 ++--- .../relations/nested_containers.hpp | 24 ++- .../barretenberg/relations/relation_types.hpp | 29 +-- .../goblin_ultra_flavor.hpp | 7 + .../stdlib_circuit_builders/ultra_flavor.hpp | 6 + .../sumcheck/instance/instances.hpp | 6 +- .../goblin_translator_flavor.hpp | 6 + .../barretenberg/vm/generated/avm_flavor.hpp | 6 + 10 files changed, 177 insertions(+), 153 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index c3c26a6ef70..3e315bf0d9a 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -401,6 +401,12 @@ class ECCVMFlavor { * @brief A container for univariates used during sumcheck. */ template using ProverUnivariates = AllEntities>; + /** + * @brief A container for univariates used during Protogalaxy folding and sumcheck. + * @details During folding and sumcheck, the prover evaluates the relations on these univariates. + */ + template + using OptimisedProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 4bab8790d05..edbb358a95c 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -13,17 +13,17 @@ namespace bb { * of the data in those univariates. We do that by taking a view of those elements and then, as needed, using this to * populate new containers. */ -template class UnivariateView; +template class UnivariateView; /** * @brief A univariate polynomial represented by its values on {domain_start, domain_start + 1,..., domain_end - 1}. For * memory efficiency purposes, we store the evaluations in an array starting from 0 and make the mapping to the right * domain under the hood. */ -template class Univariate { +template class Univariate { public: static constexpr size_t LENGTH = domain_end - domain_start; - using View = UnivariateView; + using View = UnivariateView; using value_type = Fr; // used to get the type of the elements consistently with std::array @@ -50,7 +50,7 @@ template class Univariate } } // Construct Univariate from UnivariateView - explicit Univariate(UnivariateView in) + explicit Univariate(UnivariateView in) : evaluations{} { for (size_t i = 0; i < in.evaluations.size(); ++i) { @@ -77,7 +77,7 @@ template class Univariate static Univariate get_random() { - auto output = Univariate(); + auto output = Univariate(); for (size_t i = 0; i != LENGTH; ++i) { output.value_at(i) = Fr::random_element(); } @@ -86,7 +86,7 @@ template class Univariate static Univariate zero() { - auto output = Univariate(); + auto output = Univariate(); for (size_t i = 0; i != LENGTH; ++i) { output.value_at(i) = Fr::zero(); } @@ -100,21 +100,25 @@ template class Univariate Univariate& operator+=(const Univariate& other) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] += other.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { evaluations[i] += other.evaluations[i]; } return *this; } Univariate& operator-=(const Univariate& other) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] -= other.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { + evaluations[i] -= other.evaluations[i]; } return *this; } Univariate& operator*=(const Univariate& other) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] *= other.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { evaluations[i] *= other.evaluations[i]; } return *this; @@ -135,8 +139,12 @@ template class Univariate Univariate operator-() const { Univariate res(*this); + size_t i = 0; for (auto& eval : res.evaluations) { - eval = -eval; + if (i == 0 || i >= (skip_count + 1)) { + eval = -eval; + } + i++; } return res; } @@ -151,23 +159,35 @@ template class Univariate // Operations between Univariate and scalar Univariate& operator+=(const Fr& scalar) { + size_t i = 0; for (auto& eval : evaluations) { - eval += scalar; + if (i == 0 || i >= (skip_count + 1)) { + eval += scalar; + } + i++; } return *this; } Univariate& operator-=(const Fr& scalar) { + size_t i = 0; for (auto& eval : evaluations) { - eval -= scalar; + if (i == 0 || i >= (skip_count + 1)) { + eval -= scalar; + } + i++; } return *this; } Univariate& operator*=(const Fr& scalar) { + size_t i = 0; for (auto& eval : evaluations) { - eval *= scalar; + if (i == 0 || i >= (skip_count + 1)) { + eval *= scalar; + } + i++; } return *this; } @@ -194,45 +214,48 @@ template class Univariate } // Operations between Univariate and UnivariateView - Univariate& operator+=(const UnivariateView& view) + Univariate& operator+=(const UnivariateView& view) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] += view.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { evaluations[i] += view.evaluations[i]; } return *this; } - Univariate& operator-=(const UnivariateView& view) + Univariate& operator-=(const UnivariateView& view) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] -= view.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { evaluations[i] -= view.evaluations[i]; } return *this; } - Univariate& operator*=(const UnivariateView& view) + Univariate& operator*=(const UnivariateView& view) { - for (size_t i = 0; i < LENGTH; ++i) { + evaluations[0] *= view.evaluations[0]; + for (size_t i = skip_count + 1; i < LENGTH; ++i) { evaluations[i] *= view.evaluations[i]; } return *this; } - Univariate operator+(const UnivariateView& view) const + Univariate operator+(const UnivariateView& view) const { Univariate res(*this); res += view; return res; } - Univariate operator-(const UnivariateView& view) const + Univariate operator-(const UnivariateView& view) const { Univariate res(*this); res -= view; return res; } - Univariate operator*(const UnivariateView& view) const + Univariate operator*(const UnivariateView& view) const { Univariate res(*this); res *= view; @@ -256,29 +279,31 @@ template class Univariate } /** - * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the evaluations - * {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by {f(domain_start),..., - * f(extended_domain_end -1)} + * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the + * evaluations {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by + * {f(domain_start),..., f(extended_domain_end -1)} * - * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently compute the - * needed values of f, we use the barycentric formula + * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently + * compute the needed values of f, we use the barycentric formula * - f(x) = B(x) Σ_{i=domain_start}^{domain_end-1} v_i / (d_i*(x-x_i)) * where * - B(x) = Π_{i=domain_start}^{domain_end-1} (x-x_i) - * - d_i = Π_{j ∈ {domain_start, ..., domain_end-1}, j≠i} (x_i-x_j) for i ∈ {domain_start, ..., domain_end-1} + * - d_i = Π_{j ∈ {domain_start, ..., domain_end-1}, j≠i} (x_i-x_j) for i ∈ {domain_start, ..., + * domain_end-1} * - * When the domain size is two, extending f = v0(1-X) + v1X to a new value involves just one addition and a - * subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 = f(2) + Δ... + * When the domain size is two, extending f = v0(1-X) + v1X to a new value involves just one addition + * and a subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 + * = f(2) + Δ... * */ template - Univariate extend_to() const + Univariate extend_to() const { - const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start + NUM_SKIPPED_INDICES; + const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; using Data = BarycentricData; static_assert(EXTENDED_LENGTH >= LENGTH); - Univariate result; + Univariate result; std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin()); @@ -315,8 +340,8 @@ template class Univariate // a*1 + b*1 + c*1 + d = f(1) // a*2^3 + b*2^2 + c*2 + d = f(2) // a*3^3 + b*3^2 + c*3 + d = f(3) - // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2), f(3)], where - // M is: + // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2), + // f(3)], where M is: // 0, 0, 0, 1 // 1, 1, 1, 1 // 2^3, 2^2, 2, 1 @@ -326,9 +351,9 @@ template class Univariate // 1, -5/2, 2, -1/2 // -11/6, 3, -3/2, 1/3 // 1, 0, 0, 0 - // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the end for each - // coefficient The resulting computation here does 18 field adds, 6 subtracts, 3 muls to compute a, b, c, - // and d. + // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the + // end for each coefficient The resulting computation here does 18 field adds, 6 subtracts, 3 + // muls to compute a, b, c, and d. Fr zero_times_3 = value_at(0) + value_at(0) + value_at(0); Fr zero_times_6 = zero_times_3 + zero_times_3; Fr zero_times_12 = zero_times_6 + zero_times_6; @@ -381,16 +406,7 @@ template class Univariate result.value_at(k) *= Data::full_numerator_values[k]; } } - if constexpr (NUM_SKIPPED_INDICES == 0) { - return result; - } - Univariate optimised_result; - optimised_result.value_at(0) = result.value_at(0); - - std::copy(std::next(result.evaluations.begin(), 1 + NUM_SKIPPED_INDICES), - result.evaluations.end(), - std::next(optimised_result.evaluations.begin(), 1)); - return optimised_result; + return result; } /** @@ -407,8 +423,8 @@ template class Univariate full_numerator_value *= u - i; } - // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against each of - // these (rather than to divide by something) for each barycentric evaluation + // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against + // each of these (rather than to divide by something) for each barycentric evaluation std::array denominator_inverses; for (size_t i = 0; i != LENGTH; ++i) { Fr inv = Data::lagrange_denominators[i]; @@ -451,7 +467,7 @@ inline void write(B& it, Univariate const& univari write(it, univariate.evaluations); } -template class UnivariateView { +template class UnivariateView { public: static constexpr size_t LENGTH = domain_end - domain_start; std::span evaluations; @@ -461,77 +477,84 @@ template class Univariate const Fr& value_at(size_t i) const { return evaluations[i]; }; template - explicit UnivariateView(const Univariate& univariate_in) + explicit UnivariateView(const Univariate& univariate_in) : evaluations(std::span(univariate_in.evaluations.data(), LENGTH)){}; - Univariate operator+(const UnivariateView& other) const + Univariate operator+(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator-(const UnivariateView& other) const + Univariate operator-(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } - Univariate operator-() const + Univariate operator-() const { - Univariate res(*this); + Univariate res(*this); + size_t i = 0; for (auto& eval : res.evaluations) { - eval = -eval; + if (i == 0 || i >= (skip_count + 1)) { + eval = -eval; + } + i++; } return res; } - Univariate operator*(const UnivariateView& other) const + Univariate operator*(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator*(const Univariate& other) const + Univariate operator*( + const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator+(const Univariate& other) const + Univariate operator+( + const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator+(const Fr& other) const + Univariate operator+(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator-(const Fr& other) const + Univariate operator-(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } - Univariate operator*(const Fr& other) const + Univariate operator*(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator-(const Univariate& other) const + Univariate operator-( + const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } @@ -554,8 +577,8 @@ template class Univariate }; /** - * @brief Create a sub-array of `elements` at the indices given in the template pack `Is`, converting them to the new - * type T. + * @brief Create a sub-array of `elements` at the indices given in the template pack `Is`, converting them + * to the new type T. * * @tparam T type to convert to * @tparam U type to convert from @@ -563,8 +586,8 @@ template class Univariate * @tparam Is list of indices we want in the returned array. When the second argument is called with * `std::make_index_sequence`, these will be `0, 1, ..., N-1`. * @param elements array to convert from - * @return std::array result array s.t. result[i] = T(elements[Is[i]]). By default, Is[i] = i when - * called with `std::make_index_sequence`. + * @return std::array result array s.t. result[i] = T(elements[Is[i]]). By default, Is[i] + * = i when called with `std::make_index_sequence`. */ template std::array array_to_array_aux(const std::array& elements, std::index_sequence) @@ -576,11 +599,12 @@ std::array array_to_array_aux(const std::array& elements * @brief Given an std::array, returns an std::array, by calling the (explicit) constructor T(U). * * @details https://stackoverflow.com/a/32175958 - * The main use case is to convert an array of `Univariate` into `UnivariateView`. The main use case would be to let - * Sumcheck decide the required degree of the relation evaluation, rather than hardcoding it inside the relation. The - * `_aux` version could also be used to create an array of only the polynomials required by the relation, and it could - * help us implement the optimization where we extend each edge only up to the maximum degree that is required over all - * relations (for example, `L_LAST` only needs degree 3). + * The main use case is to convert an array of `Univariate` into `UnivariateView`. The main use case would + * be to let Sumcheck decide the required degree of the relation evaluation, rather than hardcoding it + * inside the relation. The + * `_aux` version could also be used to create an array of only the polynomials required by the relation, + * and it could help us implement the optimization where we extend each edge only up to the maximum degree + * that is required over all relations (for example, `L_LAST` only needs degree 3). * * @tparam T Output type * @tparam U Input type (deduced from `elements`) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 7c3d96ebaa5..84b6ca8b23e 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -50,7 +50,10 @@ template class ProtoGalaxyProver_ { // obtained by composing a relation with folded instance + relation parameters . using ExtendedUnivariate = Univariate; using OptimisedExtendedUnivariate = - Univariate; + Univariate; // Represents the total length of the combiner univariate, obtained by combining the already folded relations with // the folded relation batching challenge. using ExtendedUnivariateWithRandomization = @@ -58,7 +61,7 @@ template class ProtoGalaxyProver_ { (Flavor::MAX_TOTAL_RELATION_LENGTH - 1 + ProverInstances::NUM - 1) * (ProverInstances::NUM - 1) + 1>; using ExtendedUnivariates = typename Flavor::template ProverUnivariates; using OptimisedExtendedUnivariates = - typename Flavor::template ProverUnivariates; + typename Flavor::template OptimisedProverUnivariates; using TupleOfTuplesOfUnivariates = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates; @@ -287,32 +290,14 @@ template class ProtoGalaxyProver_ { * (i.e., compute additional evaluations at adjacent domain values) as needed. * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/751) Optimize memory */ - void extend_univariates(ExtendedUnivariates& extended_univariates, + template + void extend_univariates(OptimisedExtendedUnivariates& extended_univariates, const ProverInstances& instances, const size_t row_idx) { - auto base_univariates = instances.row_to_univariates(row_idx); + auto base_univariates = instances.template row_to_univariates(row_idx); for (auto [extended_univariate, base_univariate] : zip_view(extended_univariates.get_all(), base_univariates)) { - extended_univariate = base_univariate.template extend_to(); - } - } - - /** - * @brief Prepare a univariate polynomial for relation execution in one step of the main loop in folded instance - * construction. - * @details For a fixed prover polynomial index, extract that polynomial from each instance in Instances. From each - * polynomial, extract the value at row_idx. Use these values to create a univariate polynomial, and then extend - * (i.e., compute additional evaluations at adjacent domain values) as needed. - * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/751) Optimize memory - */ - void optimised_extend_univariates(OptimisedExtendedUnivariates& extended_univariates, - const ProverInstances& instances, - const size_t row_idx) - { - auto base_univariates = instances.row_to_univariates(row_idx); - for (auto [extended_univariate, base_univariate] : zip_view(extended_univariates.get_all(), base_univariates)) { - extended_univariate = - base_univariate.template extend_to(); + extended_univariate = base_univariate.template extend_to(); } } @@ -371,7 +356,7 @@ template class ProtoGalaxyProver_ { for (size_t idx = start; idx < end; idx++) { // No need to initialise extended_univariates to 0, it's assigned to - optimised_extend_univariates(extended_univariates[thread_idx], instances, idx); + extend_univariates(extended_univariates[thread_idx], instances, idx); FF pow_challenge = pow_betas[idx]; @@ -391,31 +376,24 @@ template class ProtoGalaxyProver_ { for (auto& accumulators : thread_univariate_accumulators) { Utils::add_nested_tuples(optimised_univariate_accumulators, accumulators); } - deoptimise_univariates(optimised_univariate_accumulators, univariate_accumulators); + zero_skipped_indices(optimised_univariate_accumulators); // Batch the univariate contributions from each sub-relation to obtain the round univariate return batch_over_relations(univariate_accumulators, instances.alphas); } - static void deoptimise_univariates(OptimisedTupleOfTuplesOfUnivariates& optimised_univariate_accumulators, - TupleOfTuplesOfUnivariates& univariate_accumulators + static void zero_skipped_indices(OptimisedTupleOfTuplesOfUnivariates& optimised_univariate_accumulators ) { auto deoptimise = [&](auto& element) { - auto& optimised_element = std::get(std::get(optimised_univariate_accumulators)); - static_assert(std::remove_reference_t::LENGTH + (ProverInstances::NUM - 1) == - std::remove_reference_t::LENGTH); - element.evaluations[0] = optimised_element.evaluations[0]; + // auto& optimised_element = std::get(std::get(optimised_univariate_accumulators)); for (size_t i = 1; i < ProverInstances::NUM; i++) { element.evaluations[i] = FF(0); } - for (size_t i = 1; i < std::remove_reference_t::LENGTH; i++) { - element.evaluations[i + ProverInstances::NUM - 1] = optimised_element.evaluations[i]; - } - info("Element ", outer_idx, ".", inner_idx, "[", ":", "] = ", element); + // info("Element ", outer_idx, ".", inner_idx, "[", ":", "] = ", element); }; - Utils::template apply_to_tuple_of_tuples<0, 0>(univariate_accumulators, deoptimise); + Utils::template apply_to_tuple_of_tuples<0, 0>(optimised_univariate_accumulators, deoptimise); } static ExtendedUnivariateWithRandomization batch_over_relations(TupleOfTuplesOfUnivariates& univariate_accumulators, diff --git a/barretenberg/cpp/src/barretenberg/relations/nested_containers.hpp b/barretenberg/cpp/src/barretenberg/relations/nested_containers.hpp index 46f2d246303..36a522eb161 100644 --- a/barretenberg/cpp/src/barretenberg/relations/nested_containers.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/nested_containers.hpp @@ -10,30 +10,42 @@ namespace bb { * * @details Credit: https://stackoverflow.com/a/60440611 */ -template