-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added a UnivariateMonomial representation to reduce field ops in protogalaxy+sumcheck #10401
Changes from 24 commits
1926c6b
3c96f4f
b38ff10
0922902
9c47d26
f0673e2
019d8aa
af2df21
ae4246e
a5d457e
1d0fbb0
e66e3d6
ec321d1
5c07a8a
32f9858
5d78d66
a3e47d9
911801f
2a0b185
da6b1a6
81315c7
160e842
e8d3508
4b9af43
21b8d22
3e1065b
12959ef
4e4aa74
f051728
a099809
159c1aa
2a627df
2b05b43
874e7ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
#include "barretenberg/common/assert.hpp" | ||
#include "barretenberg/common/serialize.hpp" | ||
#include "barretenberg/polynomials/barycentric.hpp" | ||
#include "barretenberg/polynomials/univariate_monomial.hpp" | ||
#include <span> | ||
|
||
namespace bb { | ||
|
@@ -30,6 +31,8 @@ template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_coun | |
static constexpr size_t LENGTH = domain_end - domain_start; | ||
static constexpr size_t SKIP_COUNT = skip_count; | ||
using View = UnivariateView<Fr, domain_end, domain_start, skip_count>; | ||
static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; | ||
using MonomialAccumulator = UnivariateMonomial<Fr, MONOMIAL_LENGTH, true>; | ||
|
||
using value_type = Fr; // used to get the type of the elements consistently with std::array | ||
|
||
|
@@ -47,6 +50,73 @@ template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_coun | |
Univariate& operator=(const Univariate& other) = default; | ||
Univariate& operator=(Univariate&& other) noexcept = default; | ||
|
||
explicit operator UnivariateMonomial<Fr, 2, true>() const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would be great to have some tests for UnivariateMonomial functionality, for example that construction of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good call. will add a test suite when I can find some time to do so! |
||
requires(LENGTH > 1) | ||
{ | ||
static_assert(domain_end >= 2); | ||
static_assert(domain_start == 0); | ||
|
||
UnivariateMonomial<Fr, 2, true> result; | ||
result.coefficients[0] = evaluations[0]; | ||
result.coefficients[1] = evaluations[1] - evaluations[0]; | ||
result.coefficients[2] = evaluations[1]; | ||
return result; | ||
} | ||
|
||
template <bool has_a0_plus_a1> Univariate(UnivariateMonomial<Fr, 2, has_a0_plus_a1> monomial) | ||
{ | ||
static_assert(domain_start == 0); | ||
Fr to_add = monomial.coefficients[1]; | ||
evaluations[0] = monomial.coefficients[0]; | ||
auto prev = evaluations[0]; | ||
for (size_t i = 1; i < skip_count + 1; ++i) { | ||
evaluations[i] = 0; | ||
prev = prev + to_add; | ||
} | ||
|
||
for (size_t i = skip_count + 1; i < domain_end; ++i) { | ||
prev = prev + to_add; | ||
evaluations[i] = prev; | ||
} | ||
} | ||
|
||
template <bool has_a0_plus_a1> Univariate(UnivariateMonomial<Fr, 3, has_a0_plus_a1> monomial) | ||
{ | ||
static_assert(domain_start == 0); | ||
Fr to_add = monomial.coefficients[1]; // a1 + a2 | ||
Fr derivative = monomial.coefficients[2] + monomial.coefficients[2]; // 2a2 | ||
evaluations[0] = monomial.coefficients[0]; | ||
auto prev = evaluations[0]; | ||
for (size_t i = 1; i < skip_count + 1; ++i) { | ||
evaluations[i] = 0; | ||
prev += to_add; | ||
to_add += derivative; | ||
} | ||
|
||
for (size_t i = skip_count + 1; i < domain_end - 1; ++i) { | ||
prev += to_add; | ||
evaluations[i] = prev; | ||
to_add += derivative; | ||
} | ||
prev += to_add; | ||
evaluations[domain_end - 1] = prev; | ||
} | ||
|
||
// explicit operator UnivariateMonomial<Fr, 2, 0, 0>() const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. stale? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
// { | ||
// static_assert(domain_end >= 2); | ||
// static_assert(domain_start == 0); | ||
// // (1 - X)a0 + Xa1 | ||
// // a0 | ||
// if constexpr (skip_count > 0) { | ||
// UnivariateMonomial<Fr, 2, 0, 0> result{ .evaluations = { evaluations[0], 0 } }; | ||
// return result; | ||
// } else { | ||
// UnivariateMonomial<Fr, 2, 0, 0> result{ .evaluations = { evaluations[0], | ||
// evaluations[1] - evaluations[0] } }; | ||
// return result; | ||
// } | ||
// } | ||
/** | ||
* @brief Convert from a version with skipped evaluations to one without skipping (with zeroes in previously skipped | ||
* locations) | ||
|
@@ -104,15 +174,12 @@ template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_coun | |
// Check if the univariate is identically zero | ||
bool is_zero() const | ||
{ | ||
if (!evaluations[0].is_zero()) { | ||
return false; | ||
} | ||
for (size_t i = skip_count + 1; i < LENGTH; ++i) { | ||
if (!evaluations[i].is_zero()) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return evaluations[0].is_zero(); | ||
} | ||
|
||
// Write the Univariate evaluations to a buffer | ||
|
@@ -350,6 +417,13 @@ template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_coun | |
return os; | ||
} | ||
|
||
template <size_t EXTENDED_DOMAIN_END, size_t NUM_SKIPPED_INDICES = 0> | ||
explicit operator Univariate<Fr, EXTENDED_DOMAIN_END, 0, NUM_SKIPPED_INDICES>() | ||
requires(domain_start == 0 && domain_end == 2) | ||
{ | ||
return extend_to<EXTENDED_DOMAIN_END, NUM_SKIPPED_INDICES>(); | ||
} | ||
|
||
/** | ||
* @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the | ||
* evaluations {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by | ||
|
@@ -576,15 +650,42 @@ template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_coun | |
public: | ||
static constexpr size_t LENGTH = domain_end - domain_start; | ||
std::span<const Fr, LENGTH> evaluations; | ||
static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; | ||
using MonomialAccumulator = UnivariateMonomial<Fr, MONOMIAL_LENGTH, true>; | ||
|
||
UnivariateView() = default; | ||
|
||
bool operator==(const UnivariateView& other) const | ||
{ | ||
bool r = true; | ||
r = r && (evaluations[0] == other.evaluations[0]); | ||
// a view might have nonzero terms in its skip_count if accessing an original monomial | ||
for (size_t i = skip_count + 1; i < LENGTH; ++i) { | ||
r = r && (evaluations[i] == other.evaluations[i]); | ||
} | ||
return r; | ||
}; | ||
|
||
const Fr& value_at(size_t i) const { return evaluations[i]; }; | ||
|
||
template <size_t full_domain_end, size_t full_domain_start = 0> | ||
explicit UnivariateView(const Univariate<Fr, full_domain_end, full_domain_start, skip_count>& univariate_in) | ||
: evaluations(std::span<const Fr>(univariate_in.evaluations.data(), LENGTH)){}; | ||
|
||
explicit operator UnivariateMonomial<Fr, 2, true>() const | ||
requires(LENGTH > 1) | ||
{ | ||
static_assert(domain_end >= 2); | ||
static_assert(domain_start == 0); | ||
|
||
UnivariateMonomial<Fr, 2, true> result; | ||
|
||
result.coefficients[0] = evaluations[0]; | ||
result.coefficients[1] = evaluations[1] - evaluations[0]; | ||
result.coefficients[2] = evaluations[1]; | ||
return result; | ||
} | ||
|
||
Univariate<Fr, domain_end, domain_start, skip_count> operator+(const UnivariateView& other) const | ||
{ | ||
Univariate<Fr, domain_end, domain_start, skip_count> res(*this); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add to translator and eccvm recursive flavor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed. I'm curious why the tests all passed without this. Do we not compile tests that use the sumcheck Prover for the translator and eccvm recursive flavours?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, now that I think about it, this flag is only useful for the prover, and given we only ever instantiate the verifiers with recursive flavors the flag is not necessary in them, my bad