Skip to content

Commit 164245b

Browse files
committed
feat(bb): consider structured polynomials when constructing partially evaluated multivariates
1 parent 9f57048 commit 164245b

File tree

12 files changed

+873
-75
lines changed

12 files changed

+873
-75
lines changed

avm-transpiler/Cargo.lock

+765-33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp

+24-16
Original file line numberDiff line numberDiff line change
@@ -383,22 +383,6 @@ class ECCVMFlavor {
383383
using Base::Base;
384384
};
385385

386-
/**
387-
* @brief A container for storing the partially evaluated multivariates produced by sumcheck.
388-
*/
389-
class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial> {
390-
391-
public:
392-
PartiallyEvaluatedMultivariates() = default;
393-
PartiallyEvaluatedMultivariates(const size_t circuit_size)
394-
{
395-
// Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2)
396-
for (auto& poly : this->get_all()) {
397-
poly = Polynomial(circuit_size / 2);
398-
}
399-
}
400-
};
401-
402386
/**
403387
* @brief A container for univariates used during sumcheck.
404388
*/
@@ -714,6 +698,30 @@ class ECCVMFlavor {
714698
}
715699
};
716700

701+
/**
702+
* @brief A container for storing the partially evaluated multivariates produced by sumcheck.
703+
*/
704+
class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial> {
705+
706+
public:
707+
PartiallyEvaluatedMultivariates() = default;
708+
PartiallyEvaluatedMultivariates(const size_t circuit_size)
709+
{
710+
// Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2)
711+
for (auto& poly : this->get_all()) {
712+
poly = Polynomial(circuit_size / 2);
713+
}
714+
}
715+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size)
716+
{
717+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
718+
size_t halved_circuit_size = circuit_size / 2;
719+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
720+
poly = Polynomial(desired_size, halved_circuit_size);
721+
}
722+
}
723+
};
724+
717725
/**
718726
* @brief The proving key is responsible for storing the polynomials used by the prover.
719727
*

barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,14 @@ class MegaFlavor {
629629
poly = Polynomial(circuit_size / 2);
630630
}
631631
}
632+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size)
633+
{
634+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
635+
size_t halved_circuit_size = circuit_size / 2;
636+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
637+
poly = Polynomial(desired_size, halved_circuit_size);
638+
}
639+
}
632640
};
633641

634642
/**
@@ -915,4 +923,4 @@ class MegaFlavor {
915923
};
916924
};
917925

918-
} // namespace bb
926+
} // namespace bb

barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,6 @@ class UltraFlavor {
496496
PartiallyEvaluatedMultivariates() = default;
497497
PartiallyEvaluatedMultivariates(const size_t circuit_size)
498498
{
499-
500499
PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor");
501500

502501
// Storage is only needed after the first partial evaluation, hence polynomials of
@@ -505,6 +504,16 @@ class UltraFlavor {
505504
poly = Polynomial(circuit_size / 2);
506505
}
507506
}
507+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size)
508+
{
509+
PROFILE_THIS_NAME("PartiallyEvaluatedMultivariates constructor");
510+
511+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
512+
size_t halved_circuit_size = circuit_size / 2;
513+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
514+
poly = Polynomial(desired_size, halved_circuit_size);
515+
}
516+
}
508517
};
509518

510519
/**

barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp

+25-22
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,7 @@ template <typename Flavor> class SumcheckProver {
171171
: multivariate_n(multivariate_n)
172172
, multivariate_d(numeric::get_msb(multivariate_n))
173173
, transcript(transcript)
174-
, round(multivariate_n)
175-
, partially_evaluated_polynomials(multivariate_n){};
174+
, round(multivariate_n){};
176175

177176
/**
178177
* @brief Non-ZK version: Compute round univariate, place it in transcript, compute challenge, partially evaluate.
@@ -189,17 +188,19 @@ template <typename Flavor> class SumcheckProver {
189188
const RelationSeparator alpha,
190189
const std::vector<FF>& gate_challenges)
191190
{
192-
193191
bb::GateSeparatorPolynomial<FF> gate_separators(gate_challenges, multivariate_d);
194192

195193
multivariate_challenge.reserve(multivariate_d);
196194
// In the first round, we compute the first univariate polynomial and populate the book-keeping table of
197195
// #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK,
198196
// compute_univariate also takes into account the zk_sumcheck_data.
199197
auto round_univariate = round.compute_univariate(full_polynomials, relation_parameters, gate_separators, alpha);
198+
// Initialize the partially evaluated polynomials which will be used in the following rounds.
199+
// This will use the information in the structured full polynomials to save memory if possible.
200+
partially_evaluated_polynomials = PartiallyEvaluatedMultivariates(full_polynomials, multivariate_n);
201+
200202
vinfo("starting sumcheck rounds...");
201203
{
202-
203204
PROFILE_THIS_NAME("rest of sumcheck round 1");
204205

205206
// Place the evaluations of the round univariate into transcript.
@@ -210,11 +211,10 @@ template <typename Flavor> class SumcheckProver {
210211
partially_evaluate(full_polynomials, multivariate_n, round_challenge);
211212
gate_separators.partially_evaluate(round_challenge);
212213
round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and
213-
// release memory? // All but final round
214-
// We operate on partially_evaluated_polynomials in place.
214+
// release memory? // All but final round
215+
// We operate on partially_evaluated_polynomials in place.
215216
}
216217
for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) {
217-
218218
PROFILE_THIS_NAME("sumcheck loop");
219219

220220
// Write the round univariate to the transcript
@@ -296,9 +296,12 @@ template <typename Flavor> class SumcheckProver {
296296
alpha,
297297
zk_sumcheck_data,
298298
row_disabling_polynomial);
299+
// Initialize the partially evaluated polynomials which will be used in the following rounds.
300+
// This will use the information in the structured full polynomials to save memory if possible.
301+
partially_evaluated_polynomials = PartiallyEvaluatedMultivariates(full_polynomials, multivariate_n);
302+
299303
vinfo("starting sumcheck rounds...");
300304
{
301-
302305
PROFILE_THIS_NAME("rest of sumcheck round 1");
303306

304307
if constexpr (!IsGrumpkinFlavor<Flavor>) {
@@ -451,7 +454,8 @@ template <typename Flavor> class SumcheckProver {
451454
// after the first round, operate in place on partially_evaluated_polynomials
452455
parallel_for(poly_view.size(), [&](size_t j) {
453456
for (size_t i = 0; i < round_size; i += 2) {
454-
pep_view[j].at(i >> 1) = poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i]);
457+
pep_view[j].set_if_valid_index(
458+
i >> 1, poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i]));
455459
}
456460
});
457461
};
@@ -466,23 +470,23 @@ template <typename Flavor> class SumcheckProver {
466470
// after the first round, operate in place on partially_evaluated_polynomials
467471
parallel_for(polynomials.size(), [&](size_t j) {
468472
for (size_t i = 0; i < round_size; i += 2) {
469-
pep_view[j].at(i >> 1) =
470-
polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]);
473+
pep_view[j].set_if_valid_index(
474+
i >> 1, polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]));
471475
}
472476
});
473477
};
474478

475479
/**
476-
* @brief This method takes the book-keeping table containing partially evaluated prover polynomials and creates a
477-
* vector containing the evaluations of all prover polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$.
478-
* For ZK Flavors: this method takes the book-keeping table containing partially evaluated prover polynomials
479-
and creates a vector containing the evaluations of all witness polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$
480-
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
481-
polynomials that are sent in clear.
482-
*
483-
* @param partially_evaluated_polynomials
484-
* @param multivariate_evaluations
485-
*/
480+
* @brief This method takes the book-keeping table containing partially evaluated prover polynomials and creates a
481+
* vector containing the evaluations of all prover polynomials at the point \f$ (u_0, \ldots, u_{d-1} )\f$.
482+
* For ZK Flavors: this method takes the book-keeping table containing partially evaluated prover polynomials
483+
* and creates a vector containing the evaluations of all witness polynomials at the point \f$ (u_0, \ldots, u_{d-1}
484+
* )\f$ masked by the terms \f$ \texttt{eval_masking_scalars}_j\cdot \sum u_i(1-u_i)\f$ and the evaluations of all
485+
* non-witness polynomials that are sent in clear.
486+
*
487+
* @param partially_evaluated_polynomials
488+
* @param multivariate_evaluations
489+
*/
486490
ClaimedEvaluations extract_claimed_evaluations(PartiallyEvaluatedMultivariates& partially_evaluated_polynomials)
487491
{
488492
ClaimedEvaluations multivariate_evaluations;
@@ -513,7 +517,6 @@ polynomials that are sent in clear.
513517
std::vector<bb::Polynomial<FF>>& round_univariates,
514518
std::vector<std::array<FF, 3>>& round_univariate_evaluations)
515519
{
516-
517520
const std::string idx = std::to_string(round_idx);
518521

519522
// Transform to monomial form and commit to it

barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ class TranslatorFlavor {
741741
poly = Polynomial(circuit_size / 2);
742742
}
743743
}
744+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size)
745+
{
746+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
747+
size_t halved_circuit_size = circuit_size / 2;
748+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
749+
poly = Polynomial(desired_size, halved_circuit_size);
750+
}
751+
}
744752
};
745753

746754
/**
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
if(NOT DISABLE_AZTEC_VM)
22
barretenberg_module(vm sumcheck stdlib_honk_verifier)
3-
endif()
3+
endif()

barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,14 @@ class AvmFlavor {
404404
public:
405405
PartiallyEvaluatedMultivariates() = default;
406406
PartiallyEvaluatedMultivariates(const size_t circuit_size);
407+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size)
408+
{
409+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
410+
size_t halved_circuit_size = circuit_size / 2;
411+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
412+
poly = Polynomial(desired_size, halved_circuit_size);
413+
}
414+
}
407415
};
408416

409417
/**

barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons
8585
}
8686
}
8787

88+
AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials,
89+
size_t circuit_size)
90+
{
91+
size_t halved_circuit_size = circuit_size / 2;
92+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
93+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
94+
poly = Polynomial(desired_size, halved_circuit_size);
95+
}
96+
}
97+
8898
AvmFlavor::ProvingKey::ProvingKey(const size_t circuit_size, const size_t num_public_inputs)
8999
: circuit_size(circuit_size)
90100
, log_circuit_size(numeric::get_msb(circuit_size))
@@ -111,4 +121,4 @@ std::vector<AvmFlavor::VerificationKey::FF> AvmFlavor::VerificationKey::to_field
111121
return elements;
112122
}
113123

114-
} // namespace bb::avm2
124+
} // namespace bb::avm2

barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ class AvmFlavor {
357357
public:
358358
PartiallyEvaluatedMultivariates() = default;
359359
PartiallyEvaluatedMultivariates(const size_t circuit_size);
360+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size);
360361
};
361362

362363
/**

bb-pilcom/bb-pil-backend/templates/flavor.cpp.hbs

+10
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(cons
8484
}
8585
}
8686

87+
AvmFlavor::PartiallyEvaluatedMultivariates::PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials,
88+
size_t circuit_size)
89+
{
90+
for (auto [poly, full_poly] : zip_view(get_all(), full_polynomials.get_all())) {
91+
size_t halved_circuit_size = circuit_size / 2;
92+
size_t desired_size = std::min(full_poly.size(), halved_circuit_size);
93+
poly = Polynomial(desired_size, halved_circuit_size);
94+
}
95+
}
96+
8797
AvmFlavor::ProvingKey::ProvingKey(const size_t circuit_size, const size_t num_public_inputs)
8898
: circuit_size(circuit_size)
8999
, log_circuit_size(numeric::get_msb(circuit_size))

bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ class AvmFlavor {
317317
public:
318318
PartiallyEvaluatedMultivariates() = default;
319319
PartiallyEvaluatedMultivariates(const size_t circuit_size);
320+
PartiallyEvaluatedMultivariates(const ProverPolynomials& full_polynomials, size_t circuit_size);
320321
};
321322

322323
/**

0 commit comments

Comments
 (0)