From 75e7bfd0a67ca8bbf4354e2ffe999a914d4d5d71 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 6 Mar 2025 15:49:04 +0000 Subject: [PATCH 1/5] done --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 40 +++++++++------- .../stdlib_circuit_builders/mega_flavor.hpp | 8 ++++ .../stdlib_circuit_builders/ultra_flavor.hpp | 10 +++- .../sumcheck/partial_evaluation.test.cpp | 5 ++ .../src/barretenberg/sumcheck/sumcheck.hpp | 47 ++++++++++--------- .../translator_vm/translator_flavor.hpp | 8 ++++ .../barretenberg/vm/avm/generated/flavor.hpp | 8 ++++ .../src/barretenberg/vm2/generated/flavor.cpp | 12 ++++- .../src/barretenberg/vm2/generated/flavor.hpp | 1 + .../bb-pil-backend/templates/flavor.cpp.hbs | 10 ++++ .../bb-pil-backend/templates/flavor.hpp.hbs | 1 + 11 files changed, 110 insertions(+), 40 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index f5900be3d18..32cbcb9a273 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -382,22 +382,6 @@ class ECCVMFlavor { using Base::Base; }; - /** - * @brief A container for storing the partially evaluated multivariates produced by sumcheck. - */ - class PartiallyEvaluatedMultivariates : public AllEntities { - - public: - PartiallyEvaluatedMultivariates() = default; - PartiallyEvaluatedMultivariates(const size_t circuit_size) - { - // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) - for (auto& poly : this->get_all()) { - poly = Polynomial(circuit_size / 2); - } - } - }; - /** * @brief A container for univariates used during sumcheck. */ @@ -713,6 +697,30 @@ class ECCVMFlavor { } }; + /** + * @brief A container for storing the partially evaluated multivariates produced by sumcheck. + */ + class PartiallyEvaluatedMultivariates : public AllEntities { + + public: + PartiallyEvaluatedMultivariates() = default; + PartiallyEvaluatedMultivariates(const size_t circuit_size) + { + // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) + for (auto& poly : this->get_all()) { + poly = Polynomial(circuit_size / 2); + } + } + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) + { + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } + } + }; + /** * @brief The proving key is responsible for storing the polynomials used by the prover. * diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 24d275b7ea5..652b11ddd8b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -631,6 +631,14 @@ class MegaFlavor { poly = Polynomial(circuit_size / 2); } } + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) + { + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } + } }; /** 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 85d817eea2b..64ff0a21919 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -496,7 +496,6 @@ class UltraFlavor { PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size) { - PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); // Storage is only needed after the first partial evaluation, hence polynomials of @@ -505,6 +504,15 @@ class UltraFlavor { poly = Polynomial(circuit_size / 2); } } + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) + { + PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } + } }; /** diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp index 0919b5aa46f..7b0fc4c6858 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp @@ -65,6 +65,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; + sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; @@ -102,6 +103,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; + sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; @@ -166,6 +168,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; // 6 FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 + sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; @@ -218,6 +221,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; + sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); @@ -287,6 +291,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) expected_q4[i] = v011[i] * (FF(1) - round_challenge_0) + v111[i] * round_challenge_0; } + sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto polynomial_get_all = sumcheck.partially_evaluated_polynomials.get_all(); for (size_t i = 0; i < 3; i++) { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index dd12305bc43..c4d0820b7ec 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -171,8 +171,7 @@ template class SumcheckProver { : multivariate_n(multivariate_n) , multivariate_d(numeric::get_msb(multivariate_n)) , transcript(transcript) - , round(multivariate_n) - , partially_evaluated_polynomials(multivariate_n){}; + , round(multivariate_n){}; /** * @brief Non-ZK version: Compute round univariate, place it in transcript, compute challenge, partially evaluate. @@ -189,7 +188,6 @@ template class SumcheckProver { const RelationSeparator alpha, const std::vector& gate_challenges) { - bb::GateSeparatorPolynomial gate_separators(gate_challenges, multivariate_d); multivariate_challenge.reserve(multivariate_d); @@ -197,9 +195,12 @@ template class SumcheckProver { // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK, // compute_univariate also takes into account the zk_sumcheck_data. auto round_univariate = round.compute_univariate(full_polynomials, relation_parameters, gate_separators, alpha); + // Initialize the partially evaluated polynomials which will be used in the following rounds. + // This will use the information in the structured full polynomials to save memory if possible. + partially_evaluated_polynomials = PartiallyEvaluatedMultivariates(full_polynomials, multivariate_n); + vinfo("starting sumcheck rounds..."); { - PROFILE_THIS_NAME("rest of sumcheck round 1"); // Place the evaluations of the round univariate into transcript. @@ -210,11 +211,10 @@ template class SumcheckProver { partially_evaluate(full_polynomials, multivariate_n, round_challenge); gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and - // release memory? // All but final round - // We operate on partially_evaluated_polynomials in place. + // release memory? // All but final round + // We operate on partially_evaluated_polynomials in place. } for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) { - PROFILE_THIS_NAME("sumcheck loop"); // Write the round univariate to the transcript @@ -296,9 +296,12 @@ template class SumcheckProver { alpha, zk_sumcheck_data, row_disabling_polynomial); + // Initialize the partially evaluated polynomials which will be used in the following rounds. + // This will use the information in the structured full polynomials to save memory if possible. + partially_evaluated_polynomials = PartiallyEvaluatedMultivariates(full_polynomials, multivariate_n); + vinfo("starting sumcheck rounds..."); { - PROFILE_THIS_NAME("rest of sumcheck round 1"); if constexpr (!IsGrumpkinFlavor) { @@ -451,7 +454,8 @@ template class SumcheckProver { // after the first round, operate in place on partially_evaluated_polynomials parallel_for(poly_view.size(), [&](size_t j) { for (size_t i = 0; i < round_size; i += 2) { - pep_view[j].at(i >> 1) = poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i]); + pep_view[j].set_if_valid_index( + i >> 1, poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i])); } }); }; @@ -466,23 +470,23 @@ template class SumcheckProver { // after the first round, operate in place on partially_evaluated_polynomials parallel_for(polynomials.size(), [&](size_t j) { for (size_t i = 0; i < round_size; i += 2) { - pep_view[j].at(i >> 1) = - polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]); + pep_view[j].set_if_valid_index( + i >> 1, polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i])); } }); }; /** - * @brief This method takes the book-keeping table containing partially evaluated prover polynomials and creates a - * vector containing the evaluations of all prover polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$. - * For ZK Flavors: this method takes the book-keeping table containing partially evaluated prover polynomials -and creates a vector containing the evaluations of all witness polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$ -masked by the terms \f$ \texttt{eval_masking_scalars}_j\cdot \sum u_i(1-u_i)\f$ and the evaluations of all non-witness -polynomials that are sent in clear. - * - * @param partially_evaluated_polynomials - * @param multivariate_evaluations - */ + * @brief This method takes the book-keeping table containing partially evaluated prover polynomials and creates a + * vector containing the evaluations of all prover polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$. + * For ZK Flavors: this method takes the book-keeping table containing partially evaluated prover polynomials + * and creates a vector containing the evaluations of all witness polynomials at the point \f$ (u_0, \ldots, u_{d-1} + * )\f$ masked by the terms \f$ \texttt{eval_masking_scalars}_j\cdot \sum u_i(1-u_i)\f$ and the evaluations of all + * non-witness polynomials that are sent in clear. + * + * @param partially_evaluated_polynomials + * @param multivariate_evaluations + */ ClaimedEvaluations extract_claimed_evaluations(PartiallyEvaluatedMultivariates& partially_evaluated_polynomials) { ClaimedEvaluations multivariate_evaluations; @@ -513,7 +517,6 @@ polynomials that are sent in clear. std::vector>& round_univariates, std::vector>& round_univariate_evaluations) { - const std::string idx = std::to_string(round_idx); // Transform to monomial form and commit to it diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 891db762e16..633c17a0792 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -740,6 +740,14 @@ class TranslatorFlavor { poly = Polynomial(circuit_size / 2); } } + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) + { + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } + } }; /** diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index d8beb9b415c..8ce5b2fddb4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -402,6 +402,14 @@ class AvmFlavor { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size); + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) + { + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } + } }; /** diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp index c9532339e2f..3fa6f66ef50 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp @@ -85,6 +85,16 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons } } +AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, + size_t circuit_size) +{ + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } +} + AvmFlavor::ProvingKey::ProvingKey(const size_t circuit_size, const size_t num_public_inputs) : circuit_size(circuit_size) , evaluation_domain(bb::EvaluationDomain(circuit_size, circuit_size)) @@ -114,4 +124,4 @@ std::vector AvmFlavor::VerificationKey::to_field return elements; } -} // namespace bb::avm2 \ No newline at end of file +} // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp index e0f417be8c6..c2bea317984 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp @@ -355,6 +355,7 @@ class AvmFlavor { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size); + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size); }; /** diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs index 2697dd00e8c..e66d8ceb2b1 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs @@ -84,6 +84,16 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons } } +AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, + size_t circuit_size) +{ + size_t halved_circuit_size = circuit_size / 2; + for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { + size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); + poly = Polynomial(desired_size, halved_circuit_size); + } +} + AvmFlavor::ProvingKey::ProvingKey(const size_t circuit_size, const size_t num_public_inputs) : circuit_size(circuit_size) , evaluation_domain(bb::EvaluationDomain(circuit_size, circuit_size)) diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs index 41478a97888..edd46a09a0e 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs @@ -315,6 +315,7 @@ class AvmFlavor { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size); + PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size); }; /** From 1cfb3c39949fb333502df74d879ce7240c78256f Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 6 Mar 2025 17:53:41 +0000 Subject: [PATCH 2/5] tighter bounds --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 4 +--- .../stdlib_circuit_builders/mega_flavor.hpp | 4 +--- .../stdlib_circuit_builders/ultra_flavor.hpp | 4 +--- .../src/barretenberg/sumcheck/sumcheck.hpp | 20 +++++++++---------- .../translator_vm/translator_flavor.hpp | 4 +--- .../barretenberg/vm/avm/generated/flavor.hpp | 4 +--- .../src/barretenberg/vm2/generated/flavor.cpp | 4 +--- .../bb-pil-backend/templates/flavor.cpp.hbs | 4 +--- 8 files changed, 17 insertions(+), 31 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 32cbcb9a273..c16db13d6da 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -713,10 +713,8 @@ class ECCVMFlavor { } PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 652b11ddd8b..6bcf612749f 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -633,10 +633,8 @@ class MegaFlavor { } PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } }; 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 64ff0a21919..f2da401311a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -507,10 +507,8 @@ class UltraFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index c4d0820b7ec..77a34f0077f 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -354,7 +354,7 @@ template class SumcheckProver { transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round - partially_evaluate(partially_evaluated_polynomials, round.round_size, round_challenge); + partially_evaluate(partially_evaluated_polynomials, round_idx, round_challenge); // Prepare evaluation masking and libra structures for the next round (for ZK Flavors) zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx); row_disabling_polynomial.update_evaluations(round_challenge, round_idx); @@ -444,18 +444,18 @@ template class SumcheckProver { * After the final update, i.e. when \f$ i = d-1 \f$, the upper row of the table contains the evaluations of Honk * polynomials at the challenge point \f$ (u_0,\ldots, u_{d-1}) \f$. * @param polynomials Honk polynomials at initialization; partially evaluated polynomials in subsequent rounds - * @param round_size \f$2^{d-i}\f$ + * @param round_index \f$d-i\f$ * @param round_challenge \f$u_i\f$ */ - void partially_evaluate(auto& polynomials, size_t round_size, FF round_challenge) + void partially_evaluate(auto& polynomials, size_t round_index, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); auto poly_view = polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(poly_view.size(), [&](size_t j) { - for (size_t i = 0; i < round_size; i += 2) { - pep_view[j].set_if_valid_index( - i >> 1, poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i])); + const auto& poly = poly_view[j]; + for (size_t i = 0; i < poly.end_index() / (1 << (round_index - 1)); i += 2) { + pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } }); }; @@ -464,14 +464,14 @@ template class SumcheckProver { * Specialization for array, see \ref bb::SumcheckProver::partially_evaluate "generic version". */ template - void partially_evaluate(std::array& polynomials, size_t round_size, FF round_challenge) + void partially_evaluate(std::array& polynomials, size_t round_index, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(polynomials.size(), [&](size_t j) { - for (size_t i = 0; i < round_size; i += 2) { - pep_view[j].set_if_valid_index( - i >> 1, polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i])); + const auto& poly = polynomials[j]; + for (size_t i = 0; i < poly.end_index() / (1 << (round_index - 1)); i += 2) { + pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } }); }; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 633c17a0792..388e6df3426 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -742,10 +742,8 @@ class TranslatorFlavor { } PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 8ce5b2fddb4..c39209f2ec2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -404,10 +404,8 @@ class AvmFlavor { PartiallyEvaluatedMultivariates(const size_t circuit_size); PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp index 3fa6f66ef50..f065cab3fa2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp @@ -88,10 +88,8 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs index e66d8ceb2b1..cdaa2a666e1 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs @@ -87,10 +87,8 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { - size_t halved_circuit_size = circuit_size / 2; for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - size_t desired_size = std::min(full_poly.end_index(), halved_circuit_size); - poly = Polynomial(desired_size, halved_circuit_size); + poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); } } From 05b86f2fa8c9c03a1c9e3acd75f548eaf4244187 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 6 Mar 2025 18:06:15 +0000 Subject: [PATCH 3/5] rollback --- barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp | 2 +- .../barretenberg/stdlib_circuit_builders/mega_flavor.hpp | 2 +- .../barretenberg/stdlib_circuit_builders/ultra_flavor.hpp | 2 +- barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp | 6 ++++-- .../src/barretenberg/translator_vm/translator_flavor.hpp | 2 +- .../cpp/src/barretenberg/vm/avm/generated/flavor.hpp | 2 +- barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp | 2 +- bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs | 2 +- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index c16db13d6da..81dc146b595 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -714,7 +714,7 @@ class ECCVMFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 6bcf612749f..688d7db29e6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -634,7 +634,7 @@ class MegaFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } }; 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 f2da401311a..407e0fc13e5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -508,7 +508,7 @@ class UltraFlavor { { PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 77a34f0077f..be02ded0694 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -454,7 +454,8 @@ template class SumcheckProver { // after the first round, operate in place on partially_evaluated_polynomials parallel_for(poly_view.size(), [&](size_t j) { const auto& poly = poly_view[j]; - for (size_t i = 0; i < poly.end_index() / (1 << (round_index - 1)); i += 2) { + size_t actual_end_index = (poly.end_index() + 1) / (1 << (round_index - 1)); + for (size_t i = 0; i < actual_end_index; i += 2) { pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } }); @@ -470,7 +471,8 @@ template class SumcheckProver { // after the first round, operate in place on partially_evaluated_polynomials parallel_for(polynomials.size(), [&](size_t j) { const auto& poly = polynomials[j]; - for (size_t i = 0; i < poly.end_index() / (1 << (round_index - 1)); i += 2) { + size_t actual_end_index = (poly.end_index() + 1) / (1 << (round_index - 1)); + for (size_t i = 0; i < actual_end_index; i += 2) { pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } }); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 388e6df3426..b9830a0bda0 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -743,7 +743,7 @@ class TranslatorFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index c39209f2ec2..81cae57681c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -405,7 +405,7 @@ class AvmFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp index f065cab3fa2..3178777890e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp @@ -89,7 +89,7 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial(full_poly.end_index() / 2, circuit_size / 2); } } diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs index cdaa2a666e1..5c686fff469 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs @@ -88,7 +88,7 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.size() / 2, circuit_size / 2, full_poly.start_index() / 2); + poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); } } From b39da0f84d7b872b2e4e04c07c99b45e0d941603 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 6 Mar 2025 22:59:08 +0000 Subject: [PATCH 4/5] annoying changes --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 3 +- .../barretenberg/numeric/bitop/division.hpp | 10 +++ .../stdlib_circuit_builders/mega_flavor.hpp | 3 +- .../stdlib_circuit_builders/ultra_flavor.hpp | 3 +- .../sumcheck/partial_evaluation.test.cpp | 61 +++++++++++-------- .../src/barretenberg/sumcheck/sumcheck.hpp | 25 ++++---- .../translator_vm/translator_flavor.hpp | 3 +- .../barretenberg/vm/avm/generated/flavor.hpp | 3 +- .../src/barretenberg/vm2/generated/flavor.cpp | 3 +- .../bb-pil-backend/templates/flavor.cpp.hbs | 3 +- 10 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 81dc146b595..606af3d3aae 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -8,6 +8,7 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/ecc_vm/ecc_bools_relation.hpp" @@ -714,7 +715,7 @@ class ECCVMFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp b/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp new file mode 100644 index 00000000000..5de90cfa5ac --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace bb::numeric { + +template constexpr inline T div_ceil(T a, T b) +{ + return (a + b - 1) / b; +} + +} // namespace bb::numeric diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 688d7db29e6..cfc95ecb41b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -5,6 +5,7 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/databus_lookup_relation.hpp" @@ -634,7 +635,7 @@ class MegaFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } }; 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 407e0fc13e5..f8be2405a4e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -4,6 +4,7 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/polynomials/barycentric.hpp" @@ -508,7 +509,7 @@ class UltraFlavor { { PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp index 7b0fc4c6858..22c7aecab0a 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp @@ -1,6 +1,7 @@ #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" +#include #include using namespace bb; @@ -43,6 +44,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) { using Flavor = TypeParam; using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; using Transcript = typename Flavor::Transcript; // values here are chosen to check another test @@ -54,9 +56,10 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF v01 = 0; FF v11 = 0; - std::array f0 = { v00, v10, v01, v11 }; + Polynomial f0(4); + f0.template copy_vector({ v00, v10, v01, v11 }); - auto full_polynomials = std::array, 1>({ f0 }); + auto full_polynomials = std::array({ f0 }); auto transcript = Transcript::prover_init_empty(); auto sumcheck = SumcheckProver(multivariate_n, transcript); @@ -66,7 +69,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], round_challenge_0); @@ -75,7 +78,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF round_challenge_1 = 2; FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -83,6 +86,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) { using Flavor = TypeParam; using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; using Transcript = typename Flavor::Transcript; const size_t multivariate_d(2); @@ -93,9 +97,10 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF v01 = FF::random_element(); FF v11 = FF::random_element(); - std::array f0 = { v00, v10, v01, v11 }; + Polynomial f0(4); + f0.template copy_vector({ v00, v10, v01, v11 }); - auto full_polynomials = std::array, 1>({ f0 }); + auto full_polynomials = std::array({ f0 }); auto transcript = Transcript::prover_init_empty(); auto sumcheck = SumcheckProver(multivariate_n, transcript); @@ -104,7 +109,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], expected_lo); @@ -112,7 +117,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF round_challenge_1 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -142,6 +147,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) { using Flavor = TypeParam; using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; using Transcript = typename Flavor::Transcript; const size_t multivariate_d(3); @@ -156,9 +162,10 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF v011 = 7; FF v111 = 8; - std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; + Polynomial f0(8); + f0.template copy_vector({ v000, v100, v010, v110, v001, v101, v011, v111 }); - auto full_polynomials = std::array, 1>({ f0 }); + auto full_polynomials = std::array({ f0 }); auto transcript = Transcript::prover_init_empty(); auto sumcheck = SumcheckProver(multivariate_n, transcript); @@ -169,7 +176,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], expected_q1); @@ -181,13 +188,13 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; // 6 FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; // 10 - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_lo); EXPECT_EQ(first_polynomial[1], expected_hi); FF round_challenge_2 = 3; FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; // 18 - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -195,6 +202,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) { using Flavor = TypeParam; using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; using Transcript = typename Flavor::Transcript; const size_t multivariate_d(3); @@ -209,9 +217,10 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) FF v011 = FF::random_element(); FF v111 = FF::random_element(); - std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; + Polynomial f0(8); + f0.template copy_vector({ v000, v100, v010, v110, v001, v101, v011, v111 }); - auto full_polynomials = std::array, 1>({ f0 }); + auto full_polynomials = std::array({ f0 }); auto transcript = Transcript::prover_init_empty(); auto sumcheck = SumcheckProver(multivariate_n, transcript); @@ -223,7 +232,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); EXPECT_EQ(first_polynomial[0], expected_q1); EXPECT_EQ(first_polynomial[1], expected_q2); @@ -234,13 +243,13 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_lo); EXPECT_EQ(first_polynomial[1], expected_hi); FF round_challenge_2 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -248,6 +257,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) { using Flavor = TypeParam; using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; using Transcript = typename Flavor::Transcript; const size_t multivariate_d(3); @@ -271,11 +281,12 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) v011[i] = FF::random_element(); v111[i] = FF::random_element(); } - std::array f0 = { v000[0], v100[0], v010[0], v110[0], v001[0], v101[0], v011[0], v111[0] }; - std::array f1 = { v000[1], v100[1], v010[1], v110[1], v001[1], v101[1], v011[1], v111[1] }; - std::array f2 = { v000[2], v100[2], v010[2], v110[2], v001[2], v101[2], v011[2], v111[2] }; + Polynomial f0(8), f1(8), f2(8); + f0.template copy_vector({ v000[0], v100[0], v010[0], v110[0], v001[0], v101[0], v011[0], v111[0] }); + f1.template copy_vector({ v000[1], v100[1], v010[1], v110[1], v001[1], v101[1], v011[1], v111[1] }); + f2.template copy_vector({ v000[2], v100[2], v010[2], v110[2], v001[2], v101[2], v011[2], v111[2] }); - auto full_polynomials = std::array, 3>{ f0, f1, f2 }; + auto full_polynomials = std::array{ f0, f1, f2 }; auto transcript = Transcript::prover_init_empty(); auto sumcheck = SumcheckProver(multivariate_n, transcript); @@ -292,7 +303,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) } sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); auto polynomial_get_all = sumcheck.partially_evaluated_polynomials.get_all(); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_q1[i]); @@ -308,7 +319,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) expected_lo[i] = expected_q1[i] * (FF(1) - round_challenge_1) + expected_q2[i] * round_challenge_1; expected_hi[i] = expected_q3[i] * (FF(1) - round_challenge_1) + expected_q4[i] * round_challenge_1; } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_lo[i]); EXPECT_EQ((polynomial_get_all[i])[1], expected_hi[i]); @@ -318,7 +329,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) for (size_t i = 0; i < 3; i++) { expected_val[i] = expected_lo[i] * (FF(1) - round_challenge_2) + expected_hi[i] * round_challenge_2; } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_val[i]); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index be02ded0694..de9c2a3d5f2 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" @@ -208,7 +209,7 @@ template class SumcheckProver { FF round_challenge = transcript->template get_challenge("Sumcheck:u_0"); multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round - partially_evaluate(full_polynomials, multivariate_n, round_challenge); + partially_evaluate(full_polynomials, 0, round_challenge); gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and // release memory? // All but final round @@ -224,8 +225,9 @@ template class SumcheckProver { transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate); FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); - // Prepare sumcheck book-keeping table for the next round - partially_evaluate(partially_evaluated_polynomials, round.round_size, round_challenge); + // Prepare sumcheck book-keeping table for the next round. + // We use "round_idx - 1" because the partially_evaluated_polynomials are already halved once. + partially_evaluate(partially_evaluated_polynomials, round_idx - 1, round_challenge); gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; } @@ -319,7 +321,7 @@ template class SumcheckProver { multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round - partially_evaluate(full_polynomials, multivariate_n, round_challenge); + partially_evaluate(full_polynomials, 0, round_challenge); // Prepare ZK Sumcheck data for the next round zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx); row_disabling_polynomial.update_evaluations(round_challenge, round_idx); @@ -353,8 +355,9 @@ template class SumcheckProver { const FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); - // Prepare sumcheck book-keeping table for the next round - partially_evaluate(partially_evaluated_polynomials, round_idx, round_challenge); + // Prepare sumcheck book-keeping table for the next round. + // We use "round_idx - 1" because the partially_evaluated_polynomials are already halved once. + partially_evaluate(partially_evaluated_polynomials, round_idx - 1, round_challenge); // Prepare evaluation masking and libra structures for the next round (for ZK Flavors) zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx); row_disabling_polynomial.update_evaluations(round_challenge, round_idx); @@ -444,17 +447,17 @@ template class SumcheckProver { * After the final update, i.e. when \f$ i = d-1 \f$, the upper row of the table contains the evaluations of Honk * polynomials at the challenge point \f$ (u_0,\ldots, u_{d-1}) \f$. * @param polynomials Honk polynomials at initialization; partially evaluated polynomials in subsequent rounds - * @param round_index \f$d-i\f$ + * @param halvings \f$i\f$ * @param round_challenge \f$u_i\f$ */ - void partially_evaluate(auto& polynomials, size_t round_index, FF round_challenge) + void partially_evaluate(auto& polynomials, size_t halvings, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); auto poly_view = polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(poly_view.size(), [&](size_t j) { const auto& poly = poly_view[j]; - size_t actual_end_index = (poly.end_index() + 1) / (1 << (round_index - 1)); + size_t actual_end_index = numeric::div_ceil(poly.end_index(), 1 << halvings); for (size_t i = 0; i < actual_end_index; i += 2) { pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } @@ -465,13 +468,13 @@ template class SumcheckProver { * Specialization for array, see \ref bb::SumcheckProver::partially_evaluate "generic version". */ template - void partially_evaluate(std::array& polynomials, size_t round_index, FF round_challenge) + void partially_evaluate(std::array& polynomials, size_t halvings, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(polynomials.size(), [&](size_t j) { const auto& poly = polynomials[j]; - size_t actual_end_index = (poly.end_index() + 1) / (1 << (round_index - 1)); + size_t actual_end_index = numeric::div_ceil(poly.end_index(), 1 << halvings); for (size_t i = 0; i < actual_end_index; i += 2) { pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index b9830a0bda0..249b33ca5cb 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -7,6 +7,7 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_parameters.hpp" @@ -743,7 +744,7 @@ class TranslatorFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 81cae57681c..144889ae534 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -4,6 +4,7 @@ #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/flavor/relation_definitions.hpp" +#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/univariate.hpp" @@ -405,7 +406,7 @@ class AvmFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp index 3178777890e..4e719d36941 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp @@ -1,5 +1,6 @@ // AUTOGENERATED FILE #include "flavor.hpp" +#include "barretenberg/numeric/bitop/division.hpp" namespace bb::avm2 { @@ -89,7 +90,7 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(full_poly.end_index() / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs index 5c686fff469..de851603a01 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs @@ -1,5 +1,6 @@ // AUTOGENERATED FILE #include "flavor.hpp" +#include "barretenberg/numeric/bitop/division.hpp" namespace bb::{{snakeCase name}} { @@ -88,7 +89,7 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial((full_poly.end_index() + 1) / 2, circuit_size / 2); + poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); } } From 89964cc158b06be9bfd0a3cb5f66ad227245ef0a Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Fri, 7 Mar 2025 17:09:29 +0000 Subject: [PATCH 5/5] rollback suggestions --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 4 +-- .../barretenberg/numeric/bitop/division.hpp | 10 ------ .../stdlib_circuit_builders/mega_flavor.hpp | 4 +-- .../stdlib_circuit_builders/ultra_flavor.hpp | 4 +-- .../sumcheck/partial_evaluation.test.cpp | 26 ++++++++-------- .../src/barretenberg/sumcheck/sumcheck.hpp | 31 +++++++++---------- .../translator_vm/translator_flavor.hpp | 5 +-- .../barretenberg/vm/avm/generated/flavor.hpp | 4 +-- .../src/barretenberg/vm2/generated/flavor.cpp | 4 +-- .../bb-pil-backend/templates/flavor.cpp.hbs | 4 +-- 10 files changed, 43 insertions(+), 53 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 606af3d3aae..8f1539d75e0 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -8,7 +8,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/ecc_vm/ecc_bools_relation.hpp" @@ -715,7 +714,8 @@ class ECCVMFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp b/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp deleted file mode 100644 index 5de90cfa5ac..00000000000 --- a/barretenberg/cpp/src/barretenberg/numeric/bitop/division.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace bb::numeric { - -template constexpr inline T div_ceil(T a, T b) -{ - return (a + b - 1) / b; -} - -} // namespace bb::numeric diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index cfc95ecb41b..38d5f81a8d4 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -5,7 +5,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/databus_lookup_relation.hpp" @@ -635,7 +634,8 @@ class MegaFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } }; 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 f8be2405a4e..ee337d56d27 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -4,7 +4,6 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/polynomials/barycentric.hpp" @@ -509,7 +508,8 @@ class UltraFlavor { { PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor"); for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp index 22c7aecab0a..28ae100eacc 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/partial_evaluation.test.cpp @@ -69,7 +69,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], round_challenge_0); @@ -78,7 +78,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) FF round_challenge_1 = 2; FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -109,7 +109,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], expected_lo); @@ -117,7 +117,7 @@ TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) FF round_challenge_1 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -176,7 +176,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; EXPECT_EQ(first_polynomial[0], expected_q1); @@ -188,13 +188,13 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; // 6 FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; // 10 - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_lo); EXPECT_EQ(first_polynomial[1], expected_hi); FF round_challenge_2 = 3; FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; // 18 - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -232,7 +232,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); auto& first_polynomial = sumcheck.partially_evaluated_polynomials.get_all()[0]; - sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); EXPECT_EQ(first_polynomial[0], expected_q1); EXPECT_EQ(first_polynomial[1], expected_q2); @@ -243,13 +243,13 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); EXPECT_EQ(first_polynomial[0], expected_lo); EXPECT_EQ(first_polynomial[1], expected_hi); FF round_challenge_2 = FF::random_element(); FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); EXPECT_EQ(first_polynomial[0], expected_val); } @@ -303,7 +303,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) } sumcheck.partially_evaluated_polynomials = typename Flavor::PartiallyEvaluatedMultivariates(multivariate_n); - sumcheck.partially_evaluate(full_polynomials, 0, round_challenge_0); + sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); auto polynomial_get_all = sumcheck.partially_evaluated_polynomials.get_all(); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_q1[i]); @@ -319,7 +319,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) expected_lo[i] = expected_q1[i] * (FF(1) - round_challenge_1) + expected_q2[i] * round_challenge_1; expected_hi[i] = expected_q3[i] * (FF(1) - round_challenge_1) + expected_q4[i] * round_challenge_1; } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 0, round_challenge_1); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_lo[i]); EXPECT_EQ((polynomial_get_all[i])[1], expected_hi[i]); @@ -329,7 +329,7 @@ TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) for (size_t i = 0; i < 3; i++) { expected_val[i] = expected_lo[i] * (FF(1) - round_challenge_2) + expected_hi[i] * round_challenge_2; } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, 1, round_challenge_2); + sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); for (size_t i = 0; i < 3; i++) { EXPECT_EQ((polynomial_get_all[i])[0], expected_val[i]); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index de9c2a3d5f2..23099a35593 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -1,5 +1,4 @@ #pragma once -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" @@ -209,7 +208,7 @@ template class SumcheckProver { FF round_challenge = transcript->template get_challenge("Sumcheck:u_0"); multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round - partially_evaluate(full_polynomials, 0, round_challenge); + partially_evaluate(full_polynomials, multivariate_n, round_challenge); gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and // release memory? // All but final round @@ -226,8 +225,7 @@ template class SumcheckProver { FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round. - // We use "round_idx - 1" because the partially_evaluated_polynomials are already halved once. - partially_evaluate(partially_evaluated_polynomials, round_idx - 1, round_challenge); + partially_evaluate(partially_evaluated_polynomials, multivariate_n >> round_idx, round_challenge); gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; } @@ -321,7 +319,7 @@ template class SumcheckProver { multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round - partially_evaluate(full_polynomials, 0, round_challenge); + partially_evaluate(full_polynomials, multivariate_n, round_challenge); // Prepare ZK Sumcheck data for the next round zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx); row_disabling_polynomial.update_evaluations(round_challenge, round_idx); @@ -356,8 +354,7 @@ template class SumcheckProver { transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); // Prepare sumcheck book-keeping table for the next round. - // We use "round_idx - 1" because the partially_evaluated_polynomials are already halved once. - partially_evaluate(partially_evaluated_polynomials, round_idx - 1, round_challenge); + partially_evaluate(partially_evaluated_polynomials, multivariate_n >> round_idx, round_challenge); // Prepare evaluation masking and libra structures for the next round (for ZK Flavors) zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx); row_disabling_polynomial.update_evaluations(round_challenge, round_idx); @@ -447,19 +444,20 @@ template class SumcheckProver { * After the final update, i.e. when \f$ i = d-1 \f$, the upper row of the table contains the evaluations of Honk * polynomials at the challenge point \f$ (u_0,\ldots, u_{d-1}) \f$. * @param polynomials Honk polynomials at initialization; partially evaluated polynomials in subsequent rounds - * @param halvings \f$i\f$ + * @param round_size \f$2^{d-i}\f$ * @param round_challenge \f$u_i\f$ */ - void partially_evaluate(auto& polynomials, size_t halvings, FF round_challenge) + void partially_evaluate(auto& polynomials, size_t round_size, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); auto poly_view = polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(poly_view.size(), [&](size_t j) { const auto& poly = poly_view[j]; - size_t actual_end_index = numeric::div_ceil(poly.end_index(), 1 << halvings); - for (size_t i = 0; i < actual_end_index; i += 2) { - pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); + // If the polynomial is shorter than the round size, we do a little optimization. + size_t limit = std::min(poly.end_index(), round_size); + for (size_t i = 0; i < limit; i += 2) { + pep_view[j].at(i >> 1) = poly[i] + round_challenge * (poly[i + 1] - poly[i]); } }); }; @@ -468,15 +466,16 @@ template class SumcheckProver { * Specialization for array, see \ref bb::SumcheckProver::partially_evaluate "generic version". */ template - void partially_evaluate(std::array& polynomials, size_t halvings, FF round_challenge) + void partially_evaluate(std::array& polynomials, size_t round_size, FF round_challenge) { auto pep_view = partially_evaluated_polynomials.get_all(); // after the first round, operate in place on partially_evaluated_polynomials parallel_for(polynomials.size(), [&](size_t j) { const auto& poly = polynomials[j]; - size_t actual_end_index = numeric::div_ceil(poly.end_index(), 1 << halvings); - for (size_t i = 0; i < actual_end_index; i += 2) { - pep_view[j].set_if_valid_index(i >> 1, poly[i] + round_challenge * (poly[i + 1] - poly[i])); + // If the polynomial is shorter than the round size, we do a little optimization. + size_t limit = std::min(poly.end_index(), round_size); + for (size_t i = 0; i < limit; i += 2) { + pep_view[j].at(i >> 1) = poly[i] + round_challenge * (poly[i + 1] - poly[i]); } }); }; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 249b33ca5cb..46ba964c39e 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -1,4 +1,5 @@ #pragma once + #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/common/ref_vector.hpp" @@ -7,7 +8,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_parameters.hpp" @@ -744,7 +744,8 @@ class TranslatorFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 144889ae534..5ff5fe73343 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -4,7 +4,6 @@ #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/flavor/relation_definitions.hpp" -#include "barretenberg/numeric/bitop/division.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/univariate.hpp" @@ -406,7 +405,8 @@ class AvmFlavor { PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp index 4e719d36941..b26746afac7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp @@ -1,6 +1,5 @@ // AUTOGENERATED FILE #include "flavor.hpp" -#include "barretenberg/numeric/bitop/division.hpp" namespace bb::avm2 { @@ -90,7 +89,8 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } } diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs index de851603a01..e9f0cc65ec4 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs @@ -1,6 +1,5 @@ // AUTOGENERATED FILE #include "flavor.hpp" -#include "barretenberg/numeric/bitop/division.hpp" namespace bb::{{snakeCase name}} { @@ -89,7 +88,8 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons size_t circuit_size) { for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) { - poly = Polynomial(numeric::div_ceil(full_poly.end_index(), 2), circuit_size / 2); + size_t desired_size = std::min(full_poly.end_index(), circuit_size / 2); + poly = Polynomial(desired_size, circuit_size / 2); } }