From 1926c6bcc857dbc2476493d6428e27faf9108f74 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Fri, 8 Nov 2024 10:13:25 +0000 Subject: [PATCH 01/30] add monomial accumulator --- .../ecc/fields/field_declarations.hpp | 1 + .../barretenberg/polynomials/univariate.hpp | 128 ++++ .../polynomials/univariate_monomial.hpp | 602 ++++++++++++++++++ .../relations/permutation_relation.hpp | 251 ++++++-- .../stdlib/primitives/bigfield/bigfield.hpp | 1 + .../stdlib/primitives/field/field.hpp | 1 + 6 files changed, 947 insertions(+), 37 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp index af1643bdc1b..73101e199a8 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp @@ -29,6 +29,7 @@ namespace bb { template struct alignas(32) field { public: using View = field; + using MonomialAccumulator = field; using Params = Params_; using in_buf = const uint8_t*; using vec_in_buf = const uint8_t*; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index f86fc99ae2e..fb82bf886ca 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -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 namespace bb { @@ -30,6 +31,8 @@ template ; + static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; + using MonomialAccumulator = UnivariateMonomial; using value_type = Fr; // used to get the type of the elements consistently with std::array @@ -47,6 +50,90 @@ template () const + requires(LENGTH == 1) + { + static_assert(domain_start == 0); + // (1 - X)a0 + Xa1 + // a0 + UnivariateMonomial result; + result.evaluations[0] = evaluations[0]; + return result; + } + + explicit operator UnivariateMonomial() const + requires(LENGTH > 1) + { + // static std::mutex g_pages_mutex; + static_assert(domain_end >= 2); + static_assert(domain_start == 0); + // (1 - X)a0 + Xa1 + // a0 + + UnivariateMonomial result; + // std::lock_guard guard(g_pages_mutex); + // std::cout << "evaluations[0] = " << evaluations[0] << std::endl; + // std::cout << "evaluations[1] = " << evaluations[1] << std::endl; + + result.evaluations[0] = evaluations[0]; + result.evaluations[1] = evaluations[1] - evaluations[0]; + // std::cout << "evaluations[1] = " << result.evaluations[1] << std::endl; + // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; + return result; + } + + Univariate(UnivariateMonomial monomial) + { + static_assert(domain_start == 0); + Fr to_add = monomial.evaluations[1]; + evaluations[0] = monomial.evaluations[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; + } + } + + Univariate(UnivariateMonomial monomial) + { + static_assert(domain_start == 0); + Fr to_add = monomial.evaluations[1] + monomial.evaluations[2]; + Fr derivative = monomial.evaluations[2] + monomial.evaluations[2]; + evaluations[0] = monomial.evaluations[0]; + auto prev = evaluations[0]; + for (size_t i = 1; i < skip_count + 1; ++i) { + evaluations[i] = 0; + prev = prev + to_add; + to_add += derivative; + } + + for (size_t i = skip_count + 1; i < domain_end; ++i) { + prev = prev + to_add; + evaluations[i] = prev; + to_add += derivative; + } + } + + // explicit operator UnivariateMonomial() const + // { + // static_assert(domain_end >= 2); + // static_assert(domain_start == 0); + // // (1 - X)a0 + Xa1 + // // a0 + // if constexpr (skip_count > 0) { + // UnivariateMonomial result{ .evaluations = { evaluations[0], 0 } }; + // return result; + // } else { + // UnivariateMonomial 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) @@ -576,15 +663,56 @@ template evaluations; + static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; + using MonomialAccumulator = UnivariateMonomial; 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) { + // for (size_t i = 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 explicit UnivariateView(const Univariate& univariate_in) : evaluations(std::span(univariate_in.evaluations.data(), LENGTH)){}; + explicit operator UnivariateMonomial() const + requires(LENGTH == 1) + { + static_assert(domain_start == 0); + // (1 - X)a0 + Xa1 + // a0 + UnivariateMonomial result; + result.evaluations[0] = evaluations[0]; + return result; + } + + explicit operator UnivariateMonomial() const + requires(LENGTH > 1) + { + static_assert(domain_end >= 2); + static_assert(domain_start == 0); + // (1 - X)a0 + Xa1 + // a0 + + UnivariateMonomial result; + result.evaluations[0] = evaluations[0]; + result.evaluations[1] = evaluations[1] - evaluations[0]; + // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; + return result; + } + Univariate operator+(const UnivariateView& other) const { Univariate res(*this); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp new file mode 100644 index 00000000000..f880cc91a98 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -0,0 +1,602 @@ +#pragma once +#include "barretenberg/common/assert.hpp" +#include "barretenberg/common/serialize.hpp" +#include "barretenberg/polynomials/barycentric.hpp" +#include + +namespace bb { + +/** + * @brief A view of a univariate, also used to truncate univariates. + * + * @details For optimization purposes, it makes sense to define univariates with large lengths and then reuse only some + * of the data in those univariates. We do that by taking a view of those elements and then, as needed, using this to + * populate new containers. + */ +template class UnivariateView; + +/** + * @brief A univariate polynomial represented by its values on {domain_start, domain_start + 1,..., domain_end - 1}. For + * memory efficiency purposes, we store the evaluations in an array starting from 0 and make the mapping to the right + * domain under the hood. + * + * @tparam skip_count Skip computing the values of elements [domain_start+1,..,domain_start+skip_count]. Used for + * optimising computation in protogalaxy. The value at [domain_start] is the value from the accumulator, while the + * values in [domain_start+1, ... domain_start + skip_count] in the accumulator should be zero if the original if the + * skip_count-many keys to be folded are all valid + */ +template class UnivariateMonomial { + public: + static constexpr size_t LENGTH = domain_end - domain_start; + static_assert(LENGTH <= 3); + static constexpr size_t SKIP_COUNT = skip_count; + + using value_type = Fr; // used to get the type of the elements consistently with std::array + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/714) Try out std::valarray? + std::array evaluations; + + UnivariateMonomial() = default; + + explicit UnivariateMonomial(std::array _evaluations) + { + evaluations[0] = _evaluations[0]; + if constexpr (LENGTH > 1) { + evaluations[1] = _evaluations[1] - _evaluations[0]; + } + } + + ~UnivariateMonomial() = default; + UnivariateMonomial(const UnivariateMonomial& other) = default; + UnivariateMonomial(UnivariateMonomial&& other) noexcept = default; + UnivariateMonomial& operator=(const UnivariateMonomial& other) = default; + UnivariateMonomial& operator=(UnivariateMonomial&& other) noexcept = default; + + template + UnivariateMonomial(const UnivariateMonomial& other) + requires(domain_end > other_domain_end) + { + std::copy(other.evaluations.begin(), other.evaluations.end(), evaluations.begin()); + for (size_t i = other_domain_end; i < domain_end; ++i) { + evaluations[i] = 0; + } + }; + + /** + * @brief Convert from a version with skipped evaluations to one without skipping (with zeroes in previously skipped + * locations) + * + * @return Univariate + */ + UnivariateMonomial convert() const noexcept + { + UnivariateMonomial result; + result.evaluations[0] = evaluations[0]; + for (size_t i = 1; i < skip_count + 1; i++) { + result.evaluations[i] = Fr::zero(); + } + for (size_t i = skip_count + 1; i < LENGTH; i++) { + result.evaluations[i] = evaluations[i]; + } + return result; + } + // v0 = u + // v1 = v + 12 + // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a81 + // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a8d + // (1 - X)v0 + Xv1 + // a0 = v0 + // a1 = v1 - v0 + // a0 = u + // a1 = 12 + // Construct constant Univariate from scalar which represents the value that all the points in the domain + // evaluate to + explicit UnivariateMonomial(Fr value) + : evaluations{} + { + static_assert(LENGTH == 1); + evaluations[0] = value; + for (size_t i = 1; i < LENGTH; ++i) { + evaluations[i] = 0; + } + } + // // Construct UnivariateMonomial from UnivariateMonomialView + // explicit UnivariateMonomial(UnivariateView in) + // : evaluations{} + // { + // for (size_t i = 0; i < in.evaluations.size(); ++i) { + // evaluations[i] = in.evaluations[i]; + // } + // } + + Fr& value_at(size_t i) + { + if constexpr (domain_start == 0) { + return evaluations[i]; + } else { + return evaluations[i - domain_start]; + } + }; + const Fr& value_at(size_t i) const + { + if constexpr (domain_start == 0) { + return evaluations[i]; + } else { + return evaluations[i - domain_start]; + } + }; + size_t size() { return evaluations.size(); }; + + // 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; + } + + // Write the Univariate evaluations to a buffer + [[nodiscard]] std::vector to_buffer() const { return ::to_buffer(evaluations); } + + // Static method for creating a Univariate from a buffer + // IMPROVEMENT: Could be made to identically match equivalent methods in e.g. field.hpp. Currently bypasses + // unnecessary ::from_buffer call + static UnivariateMonomial serialize_from_buffer(uint8_t const* buffer) + { + UnivariateMonomial result; + std::read(buffer, result.evaluations); + return result; + } + + static UnivariateMonomial get_random() + { + auto output = UnivariateMonomial(); + for (size_t i = 0; i != LENGTH; ++i) { + output.value_at(i) = Fr::random_element(); + } + return output; + }; + + static UnivariateMonomial zero() + { + auto output = UnivariateMonomial(); + for (size_t i = 0; i != LENGTH; ++i) { + output.value_at(i) = Fr::zero(); + } + return output; + } + + static UnivariateMonomial random_element() { return get_random(); }; + + // Operations between UnivariateMonomial and other UnivariateMonomial + bool operator==(const UnivariateMonomial& other) const = default; + + template + UnivariateMonomial& operator+=(const UnivariateMonomial& other) + requires(other_domain_end < domain_end) + { + for (size_t i = 0; i < other_domain_end; ++i) { + evaluations[i] += other.evaluations[i]; + } + return *this; + } + UnivariateMonomial& operator+=(const UnivariateMonomial& other) + { + static_assert(skip_count == 0); + evaluations[0] += other.evaluations[0]; + for (size_t i = 1; i < LENGTH; ++i) { + evaluations[i] += other.evaluations[i]; + } + return *this; + } + UnivariateMonomial& operator-=(const UnivariateMonomial& other) + { + evaluations[0] -= other.evaluations[0]; + for (size_t i = 1; i < LENGTH; ++i) { + + evaluations[i] -= other.evaluations[i]; + } + return *this; + } + + UnivariateMonomial operator*(const UnivariateMonomial& other) const + requires(LENGTH == 2) + { + UnivariateMonomial result; + result.evaluations[0] = evaluations[0] * other.evaluations[0]; + result.evaluations[2] = evaluations[1] * other.evaluations[1]; + result.evaluations[1] = (evaluations[0] + evaluations[1]) * (other.evaluations[0] + other.evaluations[1]) - + (result.evaluations[0] + result.evaluations[2]); + return result; + } + + // UnivariateMonomial& self_sqr() + // { + // evaluations[0].self_sqr(); + // for (size_t i = skip_count + 1; i < LENGTH; ++i) { + // evaluations[i].self_sqr(); + // } + // return *this; + // } + UnivariateMonomial operator+(const UnivariateMonomial& other) const + { + UnivariateMonomial res(*this); + res += other; + return res; + } + + UnivariateMonomial operator-(const UnivariateMonomial& other) const + { + UnivariateMonomial res(*this); + res -= other; + return res; + } + UnivariateMonomial operator-() const + { + UnivariateMonomial res(*this); + size_t i = 0; + for (auto& eval : res.evaluations) { + if (i == 0 || i >= (skip_count + 1)) { + eval = -eval; + } + i++; + } + return res; + } + + UnivariateMonomial sqr() const + requires(LENGTH == 2) + { + UnivariateMonomial result; + result.evaluations[0] = evaluations[0].sqr(); + result.evaluations[2] = evaluations[1].sqr(); + // a0a0 a1a1 a0a1a1a0 + result.evaluations[1] = (evaluations[0] * evaluations[1]); + result.evaluations[1] += result.evaluations[1]; + + UnivariateMonomial res(*this); + res.self_sqr(); + return res; + } + + // Operations between Univariate and scalar + UnivariateMonomial& operator+=(const Fr& scalar) + { + evaluations[0] += scalar; + return *this; + } + + UnivariateMonomial& operator-=(const Fr& scalar) + { + evaluations[0] -= scalar; + return *this; + } + UnivariateMonomial& operator*=(const Fr& scalar) + { + for (size_t i = 0; i < LENGTH; ++i) { + evaluations[i] *= scalar; + } + return *this; + } + + UnivariateMonomial operator+(const Fr& scalar) const + { + UnivariateMonomial res(*this); + res += scalar; + return res; + } + + UnivariateMonomial operator-(const Fr& scalar) const + { + UnivariateMonomial res(*this); + res -= scalar; + return res; + } + + UnivariateMonomial operator*(const Fr& scalar) const + { + UnivariateMonomial res(*this); + res *= scalar; + return res; + } + + // // Operations between Univariate and UnivariateView + // Univariate& operator+=(const UnivariateView& view) + // { + // evaluations[0] += view.evaluations[0]; + // for (size_t i = skip_count + 1; i < LENGTH; ++i) { + // evaluations[i] += view.evaluations[i]; + // } + // return *this; + // } + + // Univariate& operator-=(const UnivariateView& view) + // { + // evaluations[0] -= view.evaluations[0]; + // for (size_t i = skip_count + 1; i < LENGTH; ++i) { + // evaluations[i] -= view.evaluations[i]; + // } + // return *this; + // } + + // Univariate& operator*=(const UnivariateView& view) + // { + // evaluations[0] *= view.evaluations[0]; + // for (size_t i = skip_count + 1; i < LENGTH; ++i) { + // evaluations[i] *= view.evaluations[i]; + // } + // return *this; + // } + + // Univariate operator+(const UnivariateView& view) const + // { + // Univariate res(*this); + // res += view; + // return res; + // } + + // Univariate operator-(const UnivariateView& view) const + // { + // Univariate res(*this); + // res -= view; + // return res; + // } + + // Univariate operator*(const UnivariateView& view) const + // { + // Univariate res(*this); + // res *= view; + // return res; + // } + + // Output is immediately parsable as a list of integers by Python. + friend std::ostream& operator<<(std::ostream& os, const UnivariateMonomial& u) + { + os << "["; + os << u.evaluations[0] << "," << std::endl; + for (size_t i = 1; i < u.evaluations.size(); i++) { + os << " " << u.evaluations[i]; + if (i + 1 < u.evaluations.size()) { + os << "," << std::endl; + } else { + os << "]"; + }; + } + return os; + } + + /** + * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the + * evaluations {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by + * {f(domain_start),..., f(extended_domain_end -1)} + * + * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently + * compute the needed values of f, we use the barycentric formula + * - f(x) = B(x) Σ_{i=domain_start}^{domain_end-1} v_i / (d_i*(x-x_i)) + * where + * - B(x) = Π_{i=domain_start}^{domain_end-1} (x-x_i) + * - d_i = Π_{j ∈ {domain_start, ..., domain_end-1}, j≠i} (x_i-x_j) for i ∈ {domain_start, ..., + * domain_end-1} + * + * When the domain size is two, extending f = v0(1-X) + v1X to a new value involves just one addition + * and a subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 + * = f(2) + Δ... + * + */ + // template + // Univariate extend_to() const + // { + // static constexpr size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; + // using Data = BarycentricData; + // static_assert(EXTENDED_LENGTH >= LENGTH); + + // Univariate result; + + // std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin()); + + // static constexpr Fr inverse_two = Fr(2).invert(); + // static_assert(NUM_SKIPPED_INDICES < LENGTH); + // if constexpr (LENGTH == 2) { + // Fr delta = value_at(1) - value_at(0); + // static_assert(EXTENDED_LENGTH != 0); + // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { + // result.value_at(idx + 1) = result.value_at(idx) + delta; + // } + // } else if constexpr (LENGTH == 3) { + // // Based off https://hackmd.io/@aztec-network/SyR45cmOq?type=view + // // The technique used here is the same as the length == 3 case below. + // Fr a = (value_at(2) + value_at(0)) * inverse_two - value_at(1); + // Fr b = value_at(1) - a - value_at(0); + // Fr a2 = a + a; + // Fr a_mul = a2; + // for (size_t i = 0; i < domain_end - 2; i++) { + // a_mul += a2; + // } + // Fr extra = a_mul + a + b; + // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { + // result.value_at(idx + 1) = result.value_at(idx) + extra; + // extra += a2; + // } + // } else if constexpr (LENGTH == 4) { + // static constexpr Fr inverse_six = Fr(6).invert(); // computed at compile time for efficiency + + // // To compute a barycentric extension, we can compute the coefficients of the univariate. + // // We have the evaluation of the polynomial at the domain (which is assumed to be 0, 1, 2, 3). + // // Therefore, we have the 4 linear equations from plugging into f(x) = ax^3 + bx^2 + cx + d: + // // a*0 + b*0 + c*0 + d = f(0) + // // a*1 + b*1 + c*1 + d = f(1) + // // a*2^3 + b*2^2 + c*2 + d = f(2) + // // a*3^3 + b*3^2 + c*3 + d = f(3) + // // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2), + // // f(3)], where M is: + // // 0, 0, 0, 1 + // // 1, 1, 1, 1 + // // 2^3, 2^2, 2, 1 + // // 3^3, 3^2, 3, 1 + // // We can invert this matrix in order to compute a, b, c, d: + // // -1/6, 1/2, -1/2, 1/6 + // // 1, -5/2, 2, -1/2 + // // -11/6, 3, -3/2, 1/3 + // // 1, 0, 0, 0 + // // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the + // // end for each coefficient The resulting computation here does 18 field adds, 6 subtracts, 3 + // // muls to compute a, b, c, and d. + // Fr zero_times_3 = value_at(0) + value_at(0) + value_at(0); + // Fr zero_times_6 = zero_times_3 + zero_times_3; + // Fr zero_times_12 = zero_times_6 + zero_times_6; + // Fr one_times_3 = value_at(1) + value_at(1) + value_at(1); + // Fr one_times_6 = one_times_3 + one_times_3; + // Fr two_times_3 = value_at(2) + value_at(2) + value_at(2); + // Fr three_times_2 = value_at(3) + value_at(3); + // Fr three_times_3 = three_times_2 + value_at(3); + + // Fr one_minus_two_times_3 = one_times_3 - two_times_3; + // Fr one_minus_two_times_6 = one_minus_two_times_3 + one_minus_two_times_3; + // Fr one_minus_two_times_12 = one_minus_two_times_6 + one_minus_two_times_6; + // Fr a = (one_minus_two_times_3 + value_at(3) - value_at(0)) * inverse_six; // compute a in 1 muls and 4 + // adds Fr b = (zero_times_6 - one_minus_two_times_12 - one_times_3 - three_times_3) * inverse_six; Fr c = + // (value_at(0) - zero_times_12 + one_minus_two_times_12 + one_times_6 + two_times_3 + three_times_2) * + // inverse_six; + + // // Then, outside of the a, b, c, d computation, we need to do some extra precomputation + // // This work is 3 field muls, 8 adds + // Fr a_plus_b = a + b; + // Fr a_plus_b_times_2 = a_plus_b + a_plus_b; + // size_t start_idx_sqr = (domain_end - 1) * (domain_end - 1); + // size_t idx_sqr_three = start_idx_sqr + start_idx_sqr + start_idx_sqr; + // Fr idx_sqr_three_times_a = Fr(idx_sqr_three) * a; + // Fr x_a_term = Fr(6 * (domain_end - 1)) * a; + // Fr three_a = a + a + a; + // Fr six_a = three_a + three_a; + + // Fr three_a_plus_two_b = a_plus_b_times_2 + a; + // Fr linear_term = Fr(domain_end - 1) * three_a_plus_two_b + (a_plus_b + c); + // // For each new evaluation, we do only 6 field additions and 0 muls. + // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { + // result.value_at(idx + 1) = result.value_at(idx) + idx_sqr_three_times_a + linear_term; + + // idx_sqr_three_times_a += x_a_term + three_a; + // x_a_term += six_a; + + // linear_term += three_a_plus_two_b; + // } + // } else { + // for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) { + // result.value_at(k) = 0; + // // compute each term v_j / (d_j*(x-x_j)) of the sum + // for (size_t j = domain_start; j != domain_end; ++j) { + // Fr term = value_at(j); + // term *= Data::precomputed_denominator_inverses[LENGTH * k + j]; + // result.value_at(k) += term; + // } + // // scale the sum by the value of of B(x) + // result.value_at(k) *= Data::full_numerator_values[k]; + // } + // } + // return result; + // } + + template void self_extend_from() + { + if constexpr (INITIAL_LENGTH == 2) { + const Fr delta = value_at(1) - value_at(0); + Fr next = value_at(1); + for (size_t idx = 2; idx < LENGTH; idx++) { + next += delta; + value_at(idx) = next; + } + } + } + + /** + * @brief Evaluate a univariate at a point u not known at compile time + * and assumed not to be in the domain (else we divide by zero). + * @param f + * @return Fr + */ + Fr evaluate(const Fr& u) const + { + using Data = BarycentricData; + Fr full_numerator_value = 1; + for (size_t i = domain_start; i != domain_end; ++i) { + full_numerator_value *= u - i; + } + + // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against + // each of these (rather than to divide by something) for each barycentric evaluation + std::array denominator_inverses; + for (size_t i = 0; i != LENGTH; ++i) { + Fr inv = Data::lagrange_denominators[i]; + inv *= u - Data::big_domain[i]; // warning: need to avoid zero here + inv = Fr(1) / inv; + denominator_inverses[i] = inv; + } + + Fr result = 0; + // compute each term v_j / (d_j*(x-x_j)) of the sum + for (size_t i = domain_start; i != domain_end; ++i) { + Fr term = value_at(i); + term *= denominator_inverses[i - domain_start]; + result += term; + } + // scale the sum by the value of of B(x) + result *= full_numerator_value; + return result; + }; + + // Begin iterators + auto begin() { return evaluations.begin(); } + auto begin() const { return evaluations.begin(); } + // End iterators + auto end() { return evaluations.end(); } + auto end() const { return evaluations.end(); } +}; + +template +inline void read(B& it, UnivariateMonomial& univariate) +{ + using serialize::read; + read(it, univariate.evaluations); +} + +template +inline void write(B& it, UnivariateMonomial const& univariate) +{ + using serialize::write; + write(it, univariate.evaluations); +} + +template +UnivariateMonomial operator+( + const Fr& ff, const UnivariateMonomial& uv) +{ + return uv + ff; +} + +template +UnivariateMonomial operator-( + const Fr& ff, const UnivariateMonomial& uv) +{ + return -uv + ff; +} + +template +UnivariateMonomial operator*( + const Fr& ff, const UnivariateMonomial& uv) +{ + return uv * ff; +} + +} // namespace bb + +namespace std { +template +struct tuple_size> : std::integral_constant {}; + +} // namespace std diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index af1c8bd9f64..ea9d8086893 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -1,6 +1,6 @@ #pragma once #include "barretenberg/relations/relation_types.hpp" - +#include namespace bb { /** * @brief Ultra Permutation Relation @@ -59,52 +59,160 @@ template class UltraPermutationRelationImpl { inline static auto& get_grand_product_polynomial(auto& in) { return in.z_perm; } inline static auto& get_shifted_grand_product_polynomial(auto& in) { return in.z_perm_shift; } - + // 0x000000000000000000000000000000000000000000000000c000000000000000 + // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a81 + // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a8d template inline static Accumulator compute_grand_product_numerator(const AllEntities& in, const Parameters& params) { + // static std::mutex g_pages_mutex; using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using ParameterView = GetParameterView; - auto w_1 = View(in.w_l); - auto w_2 = View(in.w_r); - auto w_3 = View(in.w_o); - auto w_4 = View(in.w_4); - auto id_1 = View(in.id_1); - auto id_2 = View(in.id_2); - auto id_3 = View(in.id_3); - auto id_4 = View(in.id_4); - - const auto& beta = ParameterView(params.beta); - const auto& gamma = ParameterView(params.gamma); - - // witness degree 4; full degree 8 - return (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) * - (w_4 + id_4 * beta + gamma); + // std::lock_guard guard(g_pages_mutex); + // if constexpr (std::same_as) { + // if (!r) { + // std::cout << result << " vs " << expected << std::endl; + // } + // ASSERT(r); + // } else { + // ASSERT(r.get_value()); + // } + // std::cout << "baz " << baz << std::endl; + + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + MonomialAccumulator w_1_m(in.w_l); + MonomialAccumulator w_2_m(in.w_r); + MonomialAccumulator w_3_m(in.w_o); + MonomialAccumulator w_4_m(in.w_4); + MonomialAccumulator id_1_m(in.id_1); + MonomialAccumulator id_2_m(in.id_2); + MonomialAccumulator id_3_m(in.id_3); + MonomialAccumulator id_4_m(in.id_4); + + ParameterMonomialAccumulator gamma_m(params.gamma); + ParameterMonomialAccumulator beta_m(params.beta); + + auto t0_m = (id_1_m * beta_m); + t0_m += (w_1_m + gamma_m); + auto t1_m = (id_2_m * beta_m); + t1_m += (w_2_m + gamma_m); + auto t2_m = (id_3_m * beta_m); + t2_m += (w_3_m + gamma_m); + auto t3_m = (id_4_m * beta_m); + t3_m += (w_4_m + gamma_m); + + Accumulator t0(t0_m); + Accumulator t1(t1_m); + Accumulator t2(t2_m); + Accumulator t3(t3_m); + + return t0 * t1 * t2 * t3; + // (1 - X)a0 + + // auto expected_2_a = (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) * + // (w_4 + id_4 * beta + gamma); + // View expected_2(expected_2_a); + // // witness degree 4; full degree 8 + // auto result_2_a = t0 * t1 * t2 * t3; + // View result_2(result_2_a); + // std::lock_guard guard(g_pages_mutex); + // auto r = result_2 == expected_2; + // if constexpr (std::same_as) { + // if (!r) { + // if constexpr (!std::same_as) { + // std::cout << "diff = " << in.w_l.evaluations[1] - in.w_l.evaluations[0] << std::endl; + // } + // // auto foo = (id_1_m * beta_m); + // Accumulator id1a(id_1_m); + // auto foo = id_1_m.test(beta_m); + // std::cout << "beta_m = " << beta_m << std::endl; + // std::cout << "id1_m in monomial form " << id_1_m << std::endl; + // std::cout << "mul result in monomial form " << foo << std::endl; + // Accumulator bar(foo); + // std::cout << "mul result in acc form " << bar << std::endl; + // std::cout << "versus " << (id_1 * beta) << std::endl; + // std::cout << "id_1 m" << id1a << std::endl; + // std::cout << "versus " << id_1 << std::endl; + // // std::cout << "mul result " << baz << std::endl; + // // std::cout << "versus " << (id_1 * beta) << std::endl; + // // std::cout << "alternate mform = " << bar << std::endl; + // // (1 - X)beta + Xbeta + // // 0 = beta + // // 1 = beta + // // beta + (beta - beta)X + // // + // // std::cout << "term result " << t0 << std::endl; + // // std::cout << "vs " << (w_1 + id_1 * beta + gamma) << std::endl; + // // std::cout << "w_1 = " << in.w_l << std::endl; + // // std::cout << "w_1_m = " << w_1_m << std::endl; + // // std::cout << "params gamma " << params.gamma << std::endl; + // // std::cout << "params gamma_m " << gamma_m << std::endl; + // // std::cout << result_2 << " vs " << expected_2 << std::endl; + // } + // ASSERT(r); + // } else { + // ASSERT(r.get_value()); + // } + + // return result_2_a; } template inline static Accumulator compute_grand_product_denominator(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using ParameterView = GetParameterView; + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + MonomialAccumulator w_1_m(in.w_l); + MonomialAccumulator w_2_m(in.w_r); + MonomialAccumulator w_3_m(in.w_o); + MonomialAccumulator w_4_m(in.w_4); + MonomialAccumulator sigma_1_m(in.sigma_1); + MonomialAccumulator sigma_2_m(in.sigma_2); + MonomialAccumulator sigma_3_m(in.sigma_3); + MonomialAccumulator sigma_4_m(in.sigma_4); + + ParameterMonomialAccumulator gamma_m(params.gamma); + ParameterMonomialAccumulator beta_m(params.beta); + + auto t0_m = (sigma_1_m * beta_m); + t0_m += (w_1_m + gamma_m); + auto t1_m = (sigma_2_m * beta_m); + t1_m += (w_2_m + gamma_m); + auto t2_m = (sigma_3_m * beta_m); + t2_m += (w_3_m + gamma_m); + auto t3_m = (sigma_4_m * beta_m); + t3_m += (w_4_m + gamma_m); - auto w_1 = View(in.w_l); - auto w_2 = View(in.w_r); - auto w_3 = View(in.w_o); - auto w_4 = View(in.w_4); + Accumulator t0(t0_m); + Accumulator t1(t1_m); + Accumulator t2(t2_m); + Accumulator t3(t3_m); - auto sigma_1 = View(in.sigma_1); - auto sigma_2 = View(in.sigma_2); - auto sigma_3 = View(in.sigma_3); - auto sigma_4 = View(in.sigma_4); + return t0 * t1 * t2 * t3; + // using View = typename Accumulator::View; + // using ParameterView = GetParameterView; + // // TODO. to use UnivariateMonomial... we want something that does not require us to propagate the type across + // // ContainerOverSubrelations - const auto& beta = ParameterView(params.beta); - const auto& gamma = ParameterView(params.gamma); + // auto w_1 = View(in.w_l); + // auto w_2 = View(in.w_r); + // auto w_3 = View(in.w_o); + // auto w_4 = View(in.w_4); - // witness degree 4; full degree 8 - return (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * - (w_4 + sigma_4 * beta + gamma); + // auto sigma_1 = View(in.sigma_1); + // auto sigma_2 = View(in.sigma_2); + // auto sigma_3 = View(in.sigma_3); + // auto sigma_4 = View(in.sigma_4); + + // const auto& beta = ParameterView(params.beta); + // const auto& gamma = ParameterView(params.gamma); + + // // witness degree 4; full degree 8 + // return (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * + // (w_4 + sigma_4 * beta + gamma); } /** @@ -134,20 +242,89 @@ template class UltraPermutationRelationImpl { [&]() { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using ParameterView = GetParameterView; - const auto public_input_delta = ParameterView(params.public_input_delta); + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + + const MonomialAccumulator w_1_m(in.w_l); + const MonomialAccumulator w_2_m(in.w_r); + const MonomialAccumulator w_3_m(in.w_o); + const MonomialAccumulator w_4_m(in.w_4); + const MonomialAccumulator id_1_m(in.id_1); + const MonomialAccumulator id_2_m(in.id_2); + const MonomialAccumulator id_3_m(in.id_3); + const MonomialAccumulator id_4_m(in.id_4); + const MonomialAccumulator sigma_1_m(in.sigma_1); + const MonomialAccumulator sigma_2_m(in.sigma_2); + const MonomialAccumulator sigma_3_m(in.sigma_3); + const MonomialAccumulator sigma_4_m(in.sigma_4); + + const ParameterMonomialAccumulator gamma_m(params.gamma); + const ParameterMonomialAccumulator beta_m(params.beta); + + const auto w_1_plus_gamma = w_1_m + gamma_m; + const auto w_2_plus_gamma = w_2_m + gamma_m; + const auto w_3_plus_gamma = w_3_m + gamma_m; + const auto w_4_plus_gamma = w_4_m + gamma_m; + + // improvements... when multiplying, `(a0 + a1) * (b0 + b1)` can be done without additions + // because a0 + a1 is equivalent to `evaluations[1]` of an Accumlulator or View object + // would save 32 additions + + // 24 adds + // karatsuba = 2 * 8 = 16 adds + // converting 14 entities into monomial accs = 14 adds + // 54 adds + // equiv of 5 degree-11 adds + // previously we had 16 degree-11 adds + + // we convert 8 acumulators + // each accumulator conversion requires degree * 2 adds which is 22 adds + // equivalent to 16 degree-11 adds + + // so in terms of additions we're down by 5 degree-11 adds + // previously we had 8 degree-11 muls + // new version we have 8 karatsuba muls which is 3 * 8 = 24 muls + // 8 * 11 = 88 (actually 80). diff = 56 muls + + // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 + // adds however we do these automatically atm? in theory we could remove about 80 additions- + auto t1 = id_1_m * beta_m; + auto t2 = id_2_m * beta_m; + auto t3 = id_3_m * beta_m; + auto t4 = id_4_m * beta_m; + + auto t5 = sigma_1_m * beta_m; + auto t6 = sigma_2_m * beta_m; + auto t7 = sigma_3_m * beta_m; + auto t8 = sigma_4_m * beta_m; + + const Accumulator numerator_1((t1) + w_1_plus_gamma); + const Accumulator numerator_2((t2) + w_2_plus_gamma); + const Accumulator numerator_3((t3) + w_3_plus_gamma); + const Accumulator numerator_4((t4) + w_4_plus_gamma); + + const Accumulator denominator_1((t5) + w_1_plus_gamma); + const Accumulator denominator_2((t6) + w_2_plus_gamma); + const Accumulator denominator_3((t7) + w_3_plus_gamma); + const Accumulator denominator_4((t8) + w_4_plus_gamma); + + const auto numerator = numerator_1 * numerator_2 * numerator_3 * numerator_4; + const auto denominator = denominator_1 * denominator_2 * denominator_3 * denominator_4; + + const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); const auto z_perm = View(in.z_perm); - const auto z_perm_shift = View(in.z_perm_shift); + const MonomialAccumulator z_perm_shift_m(in.z_perm_shift); const auto lagrange_first = View(in.lagrange_first); - const auto lagrange_last = View(in.lagrange_last); + const MonomialAccumulator lagrange_last_m(in.lagrange_last); + auto public_input_term_m = lagrange_last_m * public_input_delta_m; + public_input_term_m += z_perm_shift_m; + const Accumulator public_input_term(public_input_term_m); // witness degree: deg 5 - deg 5 = deg 5 // total degree: deg 9 - deg 10 = deg 10 std::get<0>(accumulators) += - (((z_perm + lagrange_first) * compute_grand_product_numerator(in, params)) - - ((z_perm_shift + lagrange_last * public_input_delta) * - compute_grand_product_denominator(in, params))) * - scaling_factor; + (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)) * scaling_factor; }(); // Contribution (2) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index dd3011149d8..9a34dcb2322 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -15,6 +15,7 @@ template class bigfield { public: using View = bigfield; + using MonomialAccumulator = bigfield; using TParams = T; using native = bb::field; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp index 77a1d4d8759..da70b430656 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp @@ -11,6 +11,7 @@ template class bool_t; template class field_t { public: using View = field_t; + using MonomialAccumulator = field_t; using native = bb::fr; field_t(Builder* parent_context = nullptr); From 3c96f4f493115562597b03f68d9e824cdd911da6 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Fri, 8 Nov 2024 10:28:38 +0000 Subject: [PATCH 02/30] wip --- .../cpp/src/barretenberg/polynomials/univariate.hpp | 2 ++ .../barretenberg/polynomials/univariate_monomial.hpp | 12 +++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index fb82bf886ca..b4e4894eb91 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -77,6 +77,7 @@ template class UltraPermutationRelationImpl { // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 // adds however we do these automatically atm? in theory we could remove about 80 additions- - auto t1 = id_1_m * beta_m; + auto t1 = (id_1_m * beta_m) + w_1_plus_gamma; auto t2 = id_2_m * beta_m; auto t3 = id_3_m * beta_m; auto t4 = id_4_m * beta_m; @@ -299,7 +299,7 @@ template class UltraPermutationRelationImpl { auto t7 = sigma_3_m * beta_m; auto t8 = sigma_4_m * beta_m; - const Accumulator numerator_1((t1) + w_1_plus_gamma); + const Accumulator numerator_1((t1)); const Accumulator numerator_2((t2) + w_2_plus_gamma); const Accumulator numerator_3((t3) + w_3_plus_gamma); const Accumulator numerator_4((t4) + w_4_plus_gamma); diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp index 10728d78256..951e5a94769 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp @@ -26,6 +26,13 @@ template struct RelationParameters { T lookup_grand_product_delta{ 0 }; // Lookup T beta_sqr{ 0 }; T beta_cube{ 0 }; + + // we could add useful temporaries into here although it's a bit bruteforce + // w_1 + gamma + // w_2 + gamma + // w_3 + gamma + // w_4 + gamma + // eccvm_set_permutation_delta is used in the set membership gadget in eccvm/ecc_set_relation.hpp // We can remove this by modifying the relation, but increases complexity T eccvm_set_permutation_delta = T(0); From 092290227d22c23fe10d07c978ae1e80683704ca Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 01:36:38 +0000 Subject: [PATCH 04/30] wip --- .../barretenberg/polynomials/univariate.hpp | 75 ++- .../polynomials/univariate_monomial.hpp | 524 ++++++++++-------- 2 files changed, 329 insertions(+), 270 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index b4e4894eb91..0c60f979c50 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -32,7 +32,7 @@ template ; static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; - using MonomialAccumulator = UnivariateMonomial; + using MonomialAccumulator = UnivariateMonomial; using value_type = Fr; // used to get the type of the elements consistently with std::array @@ -50,18 +50,18 @@ template () const - requires(LENGTH == 1) - { - static_assert(domain_start == 0); - // (1 - X)a0 + Xa1 - // a0 - UnivariateMonomial result; - result.evaluations[0] = evaluations[0]; - return result; - } + // explicit operator UnivariateMonomial() const + // requires(LENGTH == 1) + // { + // static_assert(domain_start == 0); + // // (1 - X)a0 + Xa1 + // // a0 + // UnivariateMonomial result; + // result.evaluations[0] = evaluations[0]; + // return result; + // } - explicit operator UnivariateMonomial() const + explicit operator UnivariateMonomial() const requires(LENGTH > 1) { // static std::mutex g_pages_mutex; @@ -70,24 +70,24 @@ template result; + UnivariateMonomial result; // std::lock_guard guard(g_pages_mutex); // std::cout << "evaluations[0] = " << evaluations[0] << std::endl; // std::cout << "evaluations[1] = " << evaluations[1] << std::endl; - result.evaluations[0] = evaluations[0]; - result.evaluations[1] = evaluations[1] - evaluations[0]; - result.midpoint = evaluations[1]; + result.coefficients[0] = evaluations[0]; + result.coefficients[1] = evaluations[1] - evaluations[0]; + result.coefficients[2] = evaluations[1]; // std::cout << "evaluations[1] = " << result.evaluations[1] << std::endl; // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; return result; } - Univariate(UnivariateMonomial monomial) + template Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); - Fr to_add = monomial.evaluations[1]; - evaluations[0] = monomial.evaluations[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; @@ -100,12 +100,12 @@ template monomial) + template Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); - Fr to_add = monomial.evaluations[1] + monomial.evaluations[2]; - Fr derivative = monomial.evaluations[2] + monomial.evaluations[2]; - evaluations[0] = monomial.evaluations[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; @@ -665,7 +665,7 @@ template evaluations; static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; - using MonomialAccumulator = UnivariateMonomial; + using MonomialAccumulator = UnivariateMonomial; UnivariateView() = default; @@ -688,29 +688,24 @@ template & univariate_in) : evaluations(std::span(univariate_in.evaluations.data(), LENGTH)){}; - explicit operator UnivariateMonomial() const - requires(LENGTH == 1) - { - static_assert(domain_start == 0); - // (1 - X)a0 + Xa1 - // a0 - UnivariateMonomial result; - result.evaluations[0] = evaluations[0]; - return result; - } - - explicit operator UnivariateMonomial() const + explicit operator UnivariateMonomial() const requires(LENGTH > 1) { + // static std::mutex g_pages_mutex; static_assert(domain_end >= 2); static_assert(domain_start == 0); // (1 - X)a0 + Xa1 // a0 - UnivariateMonomial result; - result.evaluations[0] = evaluations[0]; - result.evaluations[1] = evaluations[1] - evaluations[0]; - result.midpoint = evaluations[1]; + UnivariateMonomial result; + // std::lock_guard guard(g_pages_mutex); + // std::cout << "evaluations[0] = " << evaluations[0] << std::endl; + // std::cout << "evaluations[1] = " << evaluations[1] << std::endl; + + result.coefficients[0] = evaluations[0]; + result.coefficients[1] = evaluations[1] - evaluations[0]; + result.coefficients[2] = evaluations[1]; + // std::cout << "evaluations[1] = " << result.evaluations[1] << std::endl; // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; return result; } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index bea842e4817..8a6df4dc121 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -13,36 +13,61 @@ namespace bb { * of the data in those univariates. We do that by taking a view of those elements and then, as needed, using this to * populate new containers. */ -template class UnivariateView; /** * @brief A univariate polynomial represented by its values on {domain_start, domain_start + 1,..., domain_end - 1}. For - * memory efficiency purposes, we store the evaluations in an array starting from 0 and make the mapping to the right + * memory efficiency purposes, we store the coefficients in an array starting from 0 and make the mapping to the right * domain under the hood. * - * @tparam skip_count Skip computing the values of elements [domain_start+1,..,domain_start+skip_count]. Used for - * optimising computation in protogalaxy. The value at [domain_start] is the value from the accumulator, while the - * values in [domain_start+1, ... domain_start + skip_count] in the accumulator should be zero if the original if the - * skip_count-many keys to be folded are all valid */ -template class UnivariateMonomial { +template class UnivariateMonomial { public: - static constexpr size_t LENGTH = domain_end - domain_start; - static_assert(LENGTH <= 3); - static constexpr size_t SKIP_COUNT = skip_count; - + static constexpr size_t LENGTH = domain_end; + static_assert(LENGTH == 2 || LENGTH == 3); using value_type = Fr; // used to get the type of the elements consistently with std::array + // a0 + a1.X + a2.XX + // we need... + + // a0 + // a1 + a2 + // a2 // TODO(https://github.com/AztecProtocol/barretenberg/issues/714) Try out std::valarray? - std::array evaluations; - Fr midpoint; + + // struct Degree1Coefficients { + // Fr a0; + // Fr a1; + // Fr a0_plus_a1; + // }; + // struct Degree2Coefficients { + // Fr a0; + // Fr a1_plus_a2; + // Fr a2; + // }; + // union Coefficients { + // Degree1Coefficients d1; + // Degree2Coefficients d2; + // }; + // Coefficients coefficients; + std::array coefficients; + UnivariateMonomial() = default; - explicit UnivariateMonomial(std::array _evaluations) + // explicit UnivariateMonomial(std::array _coefficients) + // { + // coefficients[0] = _coefficients[0]; + // if constexpr (LENGTH > 1) { + // coefficients[1] = _coefficients[1] - _coefficients[0]; + // } + // } + + UnivariateMonomial(const UnivariateMonomial& other) + requires(!has_a0_plus_a1) { - evaluations[0] = _evaluations[0]; - if constexpr (LENGTH > 1) { - evaluations[1] = _evaluations[1] - _evaluations[0]; + coefficients[0] = other.coefficients[0]; + coefficients[1] = other.coefficients[1]; + if constexpr (domain_end == 3) { + coefficients[2] = other.coefficients[2]; } } @@ -52,35 +77,24 @@ template - UnivariateMonomial(const UnivariateMonomial& other) + template + UnivariateMonomial(const UnivariateMonomial& other) requires(domain_end > other_domain_end) { - std::copy(other.evaluations.begin(), other.evaluations.end(), evaluations.begin()); - for (size_t i = other_domain_end; i < domain_end; ++i) { - evaluations[i] = 0; + // (*this) as a0, a1+a2, a2 + // (other) has a0, a1 and maybe a0+a1 + coefficients[0] = other.coefficients[0]; + coefficients[1] = other.coefficients[1]; + if constexpr (domain_end == 3) { + coefficients[2] = 0; } - midpoint = other.midpoint; + // std::copy(other.coefficients.begin(), other.coefficients.end(), coefficients.begin()); + // for (size_t i = other_domain_end; i < domain_end; ++i) { + // coefficients[i] = 0; + // } + // midpoint = other.midpoint; }; - /** - * @brief Convert from a version with skipped evaluations to one without skipping (with zeroes in previously skipped - * locations) - * - * @return Univariate - */ - UnivariateMonomial convert() const noexcept - { - UnivariateMonomial result; - result.evaluations[0] = evaluations[0]; - for (size_t i = 1; i < skip_count + 1; i++) { - result.evaluations[i] = Fr::zero(); - } - for (size_t i = skip_count + 1; i < LENGTH; i++) { - result.evaluations[i] = evaluations[i]; - } - return result; - } // v0 = u // v1 = v + 12 // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a81 @@ -92,58 +106,58 @@ template in) - // : evaluations{} + // : coefficients{} // { - // for (size_t i = 0; i < in.evaluations.size(); ++i) { - // evaluations[i] = in.evaluations[i]; + // for (size_t i = 0; i < in.coefficients.size(); ++i) { + // coefficients[i] = in.coefficients[i]; // } // } - Fr& value_at(size_t i) - { - if constexpr (domain_start == 0) { - return evaluations[i]; - } else { - return evaluations[i - domain_start]; - } - }; - const Fr& value_at(size_t i) const - { - if constexpr (domain_start == 0) { - return evaluations[i]; - } else { - return evaluations[i - domain_start]; - } - }; - size_t size() { return evaluations.size(); }; + // Fr& value_at(size_t i) + // { + // if constexpr (domain_start == 0) { + // return coefficients[i]; + // } else { + // return coefficients[i - domain_start]; + // } + // }; + // const Fr& value_at(size_t i) const + // { + // if constexpr (domain_start == 0) { + // return coefficients[i]; + // } else { + // return coefficients[i - domain_start]; + // } + // }; + size_t size() { return coefficients.size(); }; // 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; - } + // bool is_zero() const + // { + // if (!coefficients[0].is_zero()) { + // return false; + // } + // for (size_t i = skip_count + 1; i < LENGTH; ++i) { + // if (!coefficients[i].is_zero()) { + // return false; + // } + // } + // return true; + // } - // Write the Univariate evaluations to a buffer - [[nodiscard]] std::vector to_buffer() const { return ::to_buffer(evaluations); } + // Write the Univariate coefficients to a buffer + [[nodiscard]] std::vector to_buffer() const { return ::to_buffer(coefficients); } // Static method for creating a Univariate from a buffer // IMPROVEMENT: Could be made to identically match equivalent methods in e.g. field.hpp. Currently bypasses @@ -151,14 +165,14 @@ template (); - for (size_t i = 0; i != LENGTH; ++i) { + auto output = UnivariateMonomial(); + for (size_t i = 0; i < LENGTH; ++i) { output.value_at(i) = Fr::random_element(); } return output; @@ -166,9 +180,9 @@ template (); + auto output = UnivariateMonomial(); for (size_t i = 0; i != LENGTH; ++i) { - output.value_at(i) = Fr::zero(); + output.coefficients[i] = Fr::zero(); } return output; } @@ -178,112 +192,158 @@ template - UnivariateMonomial& operator+=(const UnivariateMonomial& other) - requires(other_domain_end < domain_end) + template + UnivariateMonomial& operator+=( + const UnivariateMonomial& other) { - for (size_t i = 0; i < other_domain_end; ++i) { - evaluations[i] += other.evaluations[i]; + // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` + // the output object therefore must have `other_has_a0_plus_a1` set to false. + // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ + coefficients[0] += other.coefficients[0]; + coefficients[1] += other.coefficients[1]; + if constexpr (other_domain_end == 3 && domain_end == 3) { + coefficients[2] += other.coefficients[2]; } - midpoint += other.midpoint; return *this; } - UnivariateMonomial& operator+=(const UnivariateMonomial& other) - { - static_assert(skip_count == 0); - evaluations[0] += other.evaluations[0]; - for (size_t i = 1; i < LENGTH; ++i) { - evaluations[i] += other.evaluations[i]; - } - // TODO remove with dirty/clean flag - midpoint += other.midpoint; - return *this; - } - UnivariateMonomial& operator-=(const UnivariateMonomial& other) - { - evaluations[0] -= other.evaluations[0]; - for (size_t i = 1; i < LENGTH; ++i) { - evaluations[i] -= other.evaluations[i]; + template + UnivariateMonomial& operator-=( + const UnivariateMonomial& other) + { + // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` + // the output object therefore must have `other_has_a0_plus_a1` set to false. + // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ + coefficients[0] -= other.coefficients[0]; + coefficients[1] -= other.coefficients[1]; + if constexpr (other_domain_end == 3 && domain_end == 3) { + coefficients[2] -= other.coefficients[2]; } - midpoint -= other.midpoint; return *this; } - UnivariateMonomial operator*(const UnivariateMonomial& other) const + template + UnivariateMonomial operator*( + const UnivariateMonomial& other) const requires(LENGTH == 2) { - UnivariateMonomial result; - result.evaluations[0] = evaluations[0] * other.evaluations[0]; - result.evaluations[2] = evaluations[1] * other.evaluations[1]; - result.evaluations[1] = (midpoint) * (other.midpoint) - (result.evaluations[0] + result.evaluations[2]); + UnivariateMonomial result; + // result.coefficients[0] = a0 * a0; + // result.coefficients[1] = a1 * a1 + result.coefficients[0] = coefficients[0] * other.coefficients[0]; + result.coefficients[2] = coefficients[1] * other.coefficients[1]; + + // the reason we've been tracking this variable all this time. + // coefficients[1] = sum of X^2 and X coefficients + // (a0 + a1X) * (b0 + b1X) = a0b0 + (a0b1 + a1b0)X + a1b1XX + // coefficients[1] = a0b1 + a1b0 + a1b1 + // which represented as (a0 + a1) * (b0 + b1) - a0b0 + // if we have a1_plus_a0 + if constexpr (has_a0_plus_a1 && other_has_a0_plus_a1) { + result.coefficients[1] = (coefficients[2] * other.coefficients[2] - result.coefficients[0]); + } else if constexpr (has_a0_plus_a1 && !other_has_a0_plus_a1) { + result.coefficients[1] = + coefficients[2] * (other.coefficients[0] + other.coefficients[1]) - result.coefficients[0]; + } else if constexpr (!has_a0_plus_a1 && other_has_a0_plus_a1) { + result.coefficients[1] = + (coefficients[0] + coefficients[1]) * other.coefficients[2] - result.coefficients[0]; + } else { + result.coefficients[1] = + (coefficients[0] + coefficients[1]) * (other.coefficients[0] + other.coefficients[1]) - + result.coefficients[0]; + } return result; } // UnivariateMonomial& self_sqr() // { - // evaluations[0].self_sqr(); + // coefficients[0].self_sqr(); // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // evaluations[i].self_sqr(); + // coefficients[i].self_sqr(); // } // return *this; // } - UnivariateMonomial operator+(const UnivariateMonomial& other) const + template + UnivariateMonomial operator+( + const UnivariateMonomial& other) const { - UnivariateMonomial res(*this); - res += other; + UnivariateMonomial res(*this); + // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` + // the output object therefore must have `other_has_a0_plus_a1` set to false. + // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ + res.coefficients[0] += other.coefficients[0]; + res.coefficients[1] += other.coefficients[1]; + if constexpr (other_domain_end == 3 && domain_end == 3) { + res.coefficients[2] += other.coefficients[2]; + } return res; } - UnivariateMonomial operator-(const UnivariateMonomial& other) const + template + UnivariateMonomial operator-( + const UnivariateMonomial& other) const { - UnivariateMonomial res(*this); - res -= other; + UnivariateMonomial res(*this); + // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` + // the output object therefore must have `other_has_a0_plus_a1` set to false. + // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ + res.coefficients[0] -= other.coefficients[0]; + res.coefficients[1] -= other.coefficients[1]; + if constexpr (other_domain_end == 3 && domain_end == 3) { + res.coefficients[2] -= other.coefficients[2]; + } return res; } - UnivariateMonomial operator-() const + + UnivariateMonomial operator-() const { - UnivariateMonomial res(*this); - for (size_t i = 0; i < LENGTH; ++i) { - res.evaluations[i] = -res.evaluations[i]; - } - res.midpoint = -res.midpoint; + UnivariateMonomial res; + res.coefficients[0] = -coefficients[0]; + res.coefficients[1] = -coefficients[1]; return res; } - UnivariateMonomial sqr() const + UnivariateMonomial sqr() const requires(LENGTH == 2) { - UnivariateMonomial result; - result.evaluations[0] = evaluations[0].sqr(); - result.evaluations[2] = evaluations[1].sqr(); + UnivariateMonomial result; + result.coefficients[0] = coefficients[0].sqr(); + result.coefficients[2] = coefficients[1].sqr(); + + // (a0 + a1.X)^2 = a0a0 + 2a0a1.X + a1a1.XX + // coefficients[0] = a0a0 + // coefficients[1] = 2a0a1 + a1a1 = (a0 + a0 + a1).a1 + // coefficients[2] = a1a1 // a0a0 a1a1 a0a1a1a0 - result.evaluations[1] = evaluations[0] * evaluations[1]; - result.evaluations[1] += result.evaluations[1]; - + if constexpr (has_a0_plus_a1) { + result.coefficients[1] = (coefficients[2] + coefficients[0]) * coefficients[1]; + } else { + result.coefficients[1] = coefficients[0] * coefficients[1]; + result.coefficients[1] += result.coefficients[1]; + result.coefficients[1] += result.coefficients[2]; + } return result; } // Operations between Univariate and scalar UnivariateMonomial& operator+=(const Fr& scalar) { - evaluations[0] += scalar; - midpoint += scalar; // TODO remove with clean/dirty flags + coefficients[0] += scalar; return *this; } UnivariateMonomial& operator-=(const Fr& scalar) { - evaluations[0] -= scalar; - midpoint -= scalar; // TODO remove with clean/dirty flags + coefficients[0] -= scalar; return *this; } - UnivariateMonomial& operator*=(const Fr& scalar) + UnivariateMonomial& operator*=(const Fr& scalar) { - for (size_t i = 0; i < LENGTH; ++i) { - evaluations[i] *= scalar; + coefficients[0] *= scalar; + coefficients[1] *= scalar; + if constexpr (domain_end == 3) { + coefficients[2] *= scalar; } - midpoint *= scalar; // TODO remove with clean/dirty flags return *this; } @@ -301,37 +361,41 @@ template operator*(const Fr& scalar) const { UnivariateMonomial res(*this); - res *= scalar; + res.coefficients[0] *= scalar; + res.coefficients[1] *= scalar; + if constexpr (domain_end == 3) { + res.coefficients[2] *= scalar; + } return res; } // // Operations between Univariate and UnivariateView // Univariate& operator+=(const UnivariateView& view) // { - // evaluations[0] += view.evaluations[0]; + // coefficients[0] += view.coefficients[0]; // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // evaluations[i] += view.evaluations[i]; + // coefficients[i] += view.coefficients[i]; // } // return *this; // } // Univariate& operator-=(const UnivariateView& view) // { - // evaluations[0] -= view.evaluations[0]; + // coefficients[0] -= view.coefficients[0]; // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // evaluations[i] -= view.evaluations[i]; + // coefficients[i] -= view.coefficients[i]; // } // return *this; // } // Univariate& operator*=(const UnivariateView& view) // { - // evaluations[0] *= view.evaluations[0]; + // coefficients[0] *= view.coefficients[0]; // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // evaluations[i] *= view.evaluations[i]; + // coefficients[i] *= view.coefficients[i]; // } // return *this; // } @@ -361,10 +425,10 @@ template result; - // std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin()); + // std::copy(coefficients.begin(), coefficients.end(), result.coefficients.begin()); // static constexpr Fr inverse_two = Fr(2).invert(); // static_assert(NUM_SKIPPED_INDICES < LENGTH); @@ -504,17 +568,17 @@ template void self_extend_from() - { - if constexpr (INITIAL_LENGTH == 2) { - const Fr delta = value_at(1) - value_at(0); - Fr next = value_at(1); - for (size_t idx = 2; idx < LENGTH; idx++) { - next += delta; - value_at(idx) = next; - } - } - } + // template void self_extend_from() + // { + // if constexpr (INITIAL_LENGTH == 2) { + // const Fr delta = value_at(1) - value_at(0); + // Fr next = value_at(1); + // for (size_t idx = 2; idx < LENGTH; idx++) { + // next += delta; + // value_at(idx) = next; + // } + // } + // } /** * @brief Evaluate a univariate at a point u not known at compile time @@ -522,83 +586,83 @@ template ; - Fr full_numerator_value = 1; - for (size_t i = domain_start; i != domain_end; ++i) { - full_numerator_value *= u - i; - } + // Fr evaluate(const Fr& u) const + // { + // using Data = BarycentricData; + // Fr full_numerator_value = 1; + // for (size_t i = domain_start; i != domain_end; ++i) { + // full_numerator_value *= u - i; + // } - // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against - // each of these (rather than to divide by something) for each barycentric evaluation - std::array denominator_inverses; - for (size_t i = 0; i != LENGTH; ++i) { - Fr inv = Data::lagrange_denominators[i]; - inv *= u - Data::big_domain[i]; // warning: need to avoid zero here - inv = Fr(1) / inv; - denominator_inverses[i] = inv; - } + // // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against + // // each of these (rather than to divide by something) for each barycentric evaluation + // std::array denominator_inverses; + // for (size_t i = 0; i != LENGTH; ++i) { + // Fr inv = Data::lagrange_denominators[i]; + // inv *= u - Data::big_domain[i]; // warning: need to avoid zero here + // inv = Fr(1) / inv; + // denominator_inverses[i] = inv; + // } - Fr result = 0; - // compute each term v_j / (d_j*(x-x_j)) of the sum - for (size_t i = domain_start; i != domain_end; ++i) { - Fr term = value_at(i); - term *= denominator_inverses[i - domain_start]; - result += term; - } - // scale the sum by the value of of B(x) - result *= full_numerator_value; - return result; - }; + // Fr result = 0; + // // compute each term v_j / (d_j*(x-x_j)) of the sum + // for (size_t i = domain_start; i != domain_end; ++i) { + // Fr term = value_at(i); + // term *= denominator_inverses[i - domain_start]; + // result += term; + // } + // // scale the sum by the value of of B(x) + // result *= full_numerator_value; + // return result; + // }; // Begin iterators - auto begin() { return evaluations.begin(); } - auto begin() const { return evaluations.begin(); } + auto begin() { return coefficients.begin(); } + auto begin() const { return coefficients.begin(); } // End iterators - auto end() { return evaluations.end(); } - auto end() const { return evaluations.end(); } + auto end() { return coefficients.end(); } + auto end() const { return coefficients.end(); } }; -template -inline void read(B& it, UnivariateMonomial& univariate) +template +inline void read(B& it, UnivariateMonomial& univariate) { using serialize::read; - read(it, univariate.evaluations); + read(it, univariate.coefficients); } -template -inline void write(B& it, UnivariateMonomial const& univariate) +template +inline void write(B& it, UnivariateMonomial const& univariate) { using serialize::write; - write(it, univariate.evaluations); -} - -template -UnivariateMonomial operator+( - const Fr& ff, const UnivariateMonomial& uv) -{ - return uv + ff; -} - -template -UnivariateMonomial operator-( - const Fr& ff, const UnivariateMonomial& uv) -{ - return -uv + ff; + write(it, univariate.coefficients); } -template -UnivariateMonomial operator*( - const Fr& ff, const UnivariateMonomial& uv) -{ - return uv * ff; -} +// template +// UnivariateMonomial operator+( +// const Fr& ff, const UnivariateMonomial& uv) +// { +// return uv + ff; +// } + +// template +// UnivariateMonomial operator-( +// const Fr& ff, const UnivariateMonomial& uv) +// { +// return -uv + ff; +// } + +// template +// UnivariateMonomial operator*( +// const Fr& ff, const UnivariateMonomial& uv) +// { +// return uv * ff; +// } } // namespace bb namespace std { -template -struct tuple_size> : std::integral_constant {}; +template +struct tuple_size> : std::integral_constant {}; } // namespace std From 9c47d2657e2b566865bd8fa20ac663e142f66c35 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 01:50:44 +0000 Subject: [PATCH 05/30] wip --- .../barretenberg/polynomials/univariate.hpp | 10 +- .../relations/auxiliary_relation.hpp | 4 +- .../relations/permutation_relation.hpp | 186 +++++++++--------- 3 files changed, 102 insertions(+), 98 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 0c60f979c50..0ecb6ce0aa1 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -438,13 +438,21 @@ template + explicit operator Univariate() + requires(domain_start == 0 && domain_end == 2) + { + return extend_to(); + } + /** * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the * evaluations {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by * {f(domain_start),..., f(extended_domain_end -1)} * * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently - * compute the needed values of f, we use the barycentric formula + * compute the needed values of f, we use the barycentric + * formula/mnt/user-data/zac/aztec-packages/barretenberg/cpp/src/barretenberg/protogalaxy * - f(x) = B(x) Σ_{i=domain_start}^{domain_end-1} v_i / (d_i*(x-x_i)) * where * - B(x) = Π_{i=domain_start}^{domain_end-1} (x-x_i) diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index c419d3426a4..07ff87f90f3 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -149,7 +149,7 @@ template class AuxiliaryRelationImpl { auto q_4 = View(in.q_4); auto q_m = View(in.q_m); auto q_arith = View(in.q_arith); - auto q_aux = View(in.q_aux); + auto q_aux_m = MonomialAccumulator(in.q_aux); const FF LIMB_SIZE(uint256_t(1) << 68); const FF SUBLIMB_SHIFT(uint256_t(1) << 14); @@ -286,7 +286,7 @@ template class AuxiliaryRelationImpl { auto adjacent_values_match_if_adjacent_indices_match = ShortAccumulator(index_delta_is_zero_m * record_delta_m); // deg 2 - auto q_aux_by_scaling = q_aux * scaling_factor; + auto q_aux_by_scaling = Accumulator(q_aux_m * scaling_factor); auto q_one_by_two_m = q_1_m * q_2_m; auto q_one_by_two = ShortAccumulator(q_one_by_two_m); auto q_one_by_two_by_aux_by_scaling = q_one_by_two * q_aux_by_scaling; diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index d25fc0ac0cc..2993ce0c5b1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -239,103 +239,99 @@ template class UltraPermutationRelationImpl { { PROFILE_THIS_NAME("Permutation::accumulate"); // Contribution (1) - [&]() { - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - - const MonomialAccumulator w_1_m(in.w_l); - const MonomialAccumulator w_2_m(in.w_r); - const MonomialAccumulator w_3_m(in.w_o); - const MonomialAccumulator w_4_m(in.w_4); - const MonomialAccumulator id_1_m(in.id_1); - const MonomialAccumulator id_2_m(in.id_2); - const MonomialAccumulator id_3_m(in.id_3); - const MonomialAccumulator id_4_m(in.id_4); - const MonomialAccumulator sigma_1_m(in.sigma_1); - const MonomialAccumulator sigma_2_m(in.sigma_2); - const MonomialAccumulator sigma_3_m(in.sigma_3); - const MonomialAccumulator sigma_4_m(in.sigma_4); - - const ParameterMonomialAccumulator gamma_m(params.gamma); - const ParameterMonomialAccumulator beta_m(params.beta); - - const auto w_1_plus_gamma = w_1_m + gamma_m; - const auto w_2_plus_gamma = w_2_m + gamma_m; - const auto w_3_plus_gamma = w_3_m + gamma_m; - const auto w_4_plus_gamma = w_4_m + gamma_m; - - // improvements... when multiplying, `(a0 + a1) * (b0 + b1)` can be done without additions - // because a0 + a1 is equivalent to `evaluations[1]` of an Accumlulator or View object - // would save 32 additions - - // 24 adds - // karatsuba = 2 * 8 = 16 adds - // converting 14 entities into monomial accs = 14 adds - // 54 adds - // equiv of 5 degree-11 adds - // previously we had 16 degree-11 adds - - // we convert 8 acumulators - // each accumulator conversion requires degree * 2 adds which is 22 adds - // equivalent to 16 degree-11 adds - - // so in terms of additions we're down by 5 degree-11 adds - // previously we had 8 degree-11 muls - // new version we have 8 karatsuba muls which is 3 * 8 = 24 muls - // 8 * 11 = 88 (actually 80). diff = 56 muls - - // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 - // adds however we do these automatically atm? in theory we could remove about 80 additions- - auto t1 = (id_1_m * beta_m) + w_1_plus_gamma; - auto t2 = id_2_m * beta_m; - auto t3 = id_3_m * beta_m; - auto t4 = id_4_m * beta_m; - - auto t5 = sigma_1_m * beta_m; - auto t6 = sigma_2_m * beta_m; - auto t7 = sigma_3_m * beta_m; - auto t8 = sigma_4_m * beta_m; - - const Accumulator numerator_1((t1)); - const Accumulator numerator_2((t2) + w_2_plus_gamma); - const Accumulator numerator_3((t3) + w_3_plus_gamma); - const Accumulator numerator_4((t4) + w_4_plus_gamma); - - const Accumulator denominator_1((t5) + w_1_plus_gamma); - const Accumulator denominator_2((t6) + w_2_plus_gamma); - const Accumulator denominator_3((t7) + w_3_plus_gamma); - const Accumulator denominator_4((t8) + w_4_plus_gamma); - - const auto numerator = numerator_1 * numerator_2 * numerator_3 * numerator_4; - const auto denominator = denominator_1 * denominator_2 * denominator_3 * denominator_4; - - const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); - const auto z_perm = View(in.z_perm); - const MonomialAccumulator z_perm_shift_m(in.z_perm_shift); - const auto lagrange_first = View(in.lagrange_first); - const MonomialAccumulator lagrange_last_m(in.lagrange_last); - - auto public_input_term_m = lagrange_last_m * public_input_delta_m; - public_input_term_m += z_perm_shift_m; - const Accumulator public_input_term(public_input_term_m); - // witness degree: deg 5 - deg 5 = deg 5 - // total degree: deg 9 - deg 10 = deg 10 - std::get<0>(accumulators) += - (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)) * scaling_factor; - }(); + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using ParameterView = GetParameterView; + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + + const MonomialAccumulator w_1_m(in.w_l); + const MonomialAccumulator w_2_m(in.w_r); + const MonomialAccumulator w_3_m(in.w_o); + const MonomialAccumulator w_4_m(in.w_4); + const MonomialAccumulator id_1_m(in.id_1); + const MonomialAccumulator id_2_m(in.id_2); + const MonomialAccumulator id_3_m(in.id_3); + const MonomialAccumulator id_4_m(in.id_4); + const MonomialAccumulator sigma_1_m(in.sigma_1); + const MonomialAccumulator sigma_2_m(in.sigma_2); + const MonomialAccumulator sigma_3_m(in.sigma_3); + const MonomialAccumulator sigma_4_m(in.sigma_4); + + const ParameterMonomialAccumulator gamma_m(params.gamma); + const ParameterMonomialAccumulator beta_m(params.beta); + + const auto w_1_plus_gamma = w_1_m + gamma_m; + const auto w_2_plus_gamma = w_2_m + gamma_m; + const auto w_3_plus_gamma = w_3_m + gamma_m; + const auto w_4_plus_gamma = w_4_m + gamma_m; + + // improvements... when multiplying, `(a0 + a1) * (b0 + b1)` can be done without additions + // because a0 + a1 is equivalent to `evaluations[1]` of an Accumlulator or View object + // would save 32 additions + + // 24 adds + // karatsuba = 2 * 8 = 16 adds + // converting 14 entities into monomial accs = 14 adds + // 54 adds + // equiv of 5 degree-11 adds + // previously we had 16 degree-11 adds + + // we convert 8 acumulators + // each accumulator conversion requires degree * 2 adds which is 22 adds + // equivalent to 16 degree-11 adds + + // so in terms of additions we're down by 5 degree-11 adds + // previously we had 8 degree-11 muls + // new version we have 8 karatsuba muls which is 3 * 8 = 24 muls + // 8 * 11 = 88 (actually 80). diff = 56 muls + + // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 + // adds however we do these automatically atm? in theory we could remove about 80 additions- + auto t1 = (id_1_m * beta_m) + w_1_plus_gamma; + auto t2 = id_2_m * beta_m; + auto t3 = id_3_m * beta_m; + auto t4 = id_4_m * beta_m; + + auto t5 = sigma_1_m * beta_m; + auto t6 = sigma_2_m * beta_m; + auto t7 = sigma_3_m * beta_m; + auto t8 = sigma_4_m * beta_m; + + const Accumulator numerator_1((t1)); + const Accumulator numerator_2((t2) + w_2_plus_gamma); + const Accumulator numerator_3((t3) + w_3_plus_gamma); + const Accumulator numerator_4((t4) + w_4_plus_gamma); + + const Accumulator denominator_1((t5) + w_1_plus_gamma); + const Accumulator denominator_2((t6) + w_2_plus_gamma); + const Accumulator denominator_3((t7) + w_3_plus_gamma); + const Accumulator denominator_4((t8) + w_4_plus_gamma); + + const auto numerator = numerator_1 * numerator_2 * numerator_3 * numerator_4; + const auto denominator = denominator_1 * denominator_2 * denominator_3 * denominator_4; + + const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); + const auto z_perm = View(in.z_perm); + const MonomialAccumulator z_perm_shift_m(in.z_perm_shift); + const auto lagrange_first = View(in.lagrange_first); + const MonomialAccumulator lagrange_last_m(in.lagrange_last); + + auto public_input_term_m = lagrange_last_m * public_input_delta_m; + public_input_term_m += z_perm_shift_m; + const Accumulator public_input_term(public_input_term_m); + // witness degree: deg 5 - deg 5 = deg 5 + // total degree: deg 9 - deg 10 = deg 10 + std::get<0>(accumulators) += + (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)) * scaling_factor; // Contribution (2) - [&]() { - using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - using View = typename Accumulator::View; - auto z_perm_shift = View(in.z_perm_shift); - auto lagrange_last = View(in.lagrange_last); - - std::get<1>(accumulators) += (lagrange_last * z_perm_shift) * scaling_factor; - }(); + using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; + using ShortView = typename ShortAccumulator::View; + auto z_perm_shift_short = ShortView(in.z_perm_shift); + auto lagrange_last_short = ShortView(in.lagrange_last); + + std::get<1>(accumulators) += (lagrange_last_short * z_perm_shift_short) * scaling_factor; }; }; From f0673e263121bbf4d4efa763e3abb8bed49f16a7 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 01:58:27 +0000 Subject: [PATCH 06/30] wip --- .../relations/permutation_relation.hpp | 205 +++++------------- 1 file changed, 53 insertions(+), 152 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index 2993ce0c5b1..28ac1db84fd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -59,160 +59,52 @@ template class UltraPermutationRelationImpl { inline static auto& get_grand_product_polynomial(auto& in) { return in.z_perm; } inline static auto& get_shifted_grand_product_polynomial(auto& in) { return in.z_perm_shift; } - // 0x000000000000000000000000000000000000000000000000c000000000000000 - // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a81 - // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a8d + template inline static Accumulator compute_grand_product_numerator(const AllEntities& in, const Parameters& params) { - // static std::mutex g_pages_mutex; using View = typename Accumulator::View; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - // std::lock_guard guard(g_pages_mutex); - // if constexpr (std::same_as) { - // if (!r) { - // std::cout << result << " vs " << expected << std::endl; - // } - // ASSERT(r); - // } else { - // ASSERT(r.get_value()); - // } - // std::cout << "baz " << baz << std::endl; - - MonomialAccumulator w_1_m(in.w_l); - MonomialAccumulator w_2_m(in.w_r); - MonomialAccumulator w_3_m(in.w_o); - MonomialAccumulator w_4_m(in.w_4); - MonomialAccumulator id_1_m(in.id_1); - MonomialAccumulator id_2_m(in.id_2); - MonomialAccumulator id_3_m(in.id_3); - MonomialAccumulator id_4_m(in.id_4); - - ParameterMonomialAccumulator gamma_m(params.gamma); - ParameterMonomialAccumulator beta_m(params.beta); - - auto t0_m = (id_1_m * beta_m); - t0_m += (w_1_m + gamma_m); - auto t1_m = (id_2_m * beta_m); - t1_m += (w_2_m + gamma_m); - auto t2_m = (id_3_m * beta_m); - t2_m += (w_3_m + gamma_m); - auto t3_m = (id_4_m * beta_m); - t3_m += (w_4_m + gamma_m); - - Accumulator t0(t0_m); - Accumulator t1(t1_m); - Accumulator t2(t2_m); - Accumulator t3(t3_m); - - return t0 * t1 * t2 * t3; - // (1 - X)a0 + - // auto expected_2_a = (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) * - // (w_4 + id_4 * beta + gamma); - // View expected_2(expected_2_a); - // // witness degree 4; full degree 8 - // auto result_2_a = t0 * t1 * t2 * t3; - // View result_2(result_2_a); - // std::lock_guard guard(g_pages_mutex); - // auto r = result_2 == expected_2; - // if constexpr (std::same_as) { - // if (!r) { - // if constexpr (!std::same_as) { - // std::cout << "diff = " << in.w_l.evaluations[1] - in.w_l.evaluations[0] << std::endl; - // } - // // auto foo = (id_1_m * beta_m); - // Accumulator id1a(id_1_m); - // auto foo = id_1_m.test(beta_m); - // std::cout << "beta_m = " << beta_m << std::endl; - // std::cout << "id1_m in monomial form " << id_1_m << std::endl; - // std::cout << "mul result in monomial form " << foo << std::endl; - // Accumulator bar(foo); - // std::cout << "mul result in acc form " << bar << std::endl; - // std::cout << "versus " << (id_1 * beta) << std::endl; - // std::cout << "id_1 m" << id1a << std::endl; - // std::cout << "versus " << id_1 << std::endl; - // // std::cout << "mul result " << baz << std::endl; - // // std::cout << "versus " << (id_1 * beta) << std::endl; - // // std::cout << "alternate mform = " << bar << std::endl; - // // (1 - X)beta + Xbeta - // // 0 = beta - // // 1 = beta - // // beta + (beta - beta)X - // // - // // std::cout << "term result " << t0 << std::endl; - // // std::cout << "vs " << (w_1 + id_1 * beta + gamma) << std::endl; - // // std::cout << "w_1 = " << in.w_l << std::endl; - // // std::cout << "w_1_m = " << w_1_m << std::endl; - // // std::cout << "params gamma " << params.gamma << std::endl; - // // std::cout << "params gamma_m " << gamma_m << std::endl; - // // std::cout << result_2 << " vs " << expected_2 << std::endl; - // } - // ASSERT(r); - // } else { - // ASSERT(r.get_value()); - // } - - // return result_2_a; + auto w_1 = View(in.w_l); + auto w_2 = View(in.w_r); + auto w_3 = View(in.w_o); + auto w_4 = View(in.w_4); + auto id_1 = View(in.id_1); + auto id_2 = View(in.id_2); + auto id_3 = View(in.id_3); + auto id_4 = View(in.id_4); + + const auto& beta = ParameterView(params.beta); + const auto& gamma = ParameterView(params.gamma); + + // witness degree 4; full degree 8 + return (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) * + (w_4 + id_4 * beta + gamma); } template inline static Accumulator compute_grand_product_denominator(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - MonomialAccumulator w_1_m(in.w_l); - MonomialAccumulator w_2_m(in.w_r); - MonomialAccumulator w_3_m(in.w_o); - MonomialAccumulator w_4_m(in.w_4); - MonomialAccumulator sigma_1_m(in.sigma_1); - MonomialAccumulator sigma_2_m(in.sigma_2); - MonomialAccumulator sigma_3_m(in.sigma_3); - MonomialAccumulator sigma_4_m(in.sigma_4); - - ParameterMonomialAccumulator gamma_m(params.gamma); - ParameterMonomialAccumulator beta_m(params.beta); - - auto t0_m = (sigma_1_m * beta_m); - t0_m += (w_1_m + gamma_m); - auto t1_m = (sigma_2_m * beta_m); - t1_m += (w_2_m + gamma_m); - auto t2_m = (sigma_3_m * beta_m); - t2_m += (w_3_m + gamma_m); - auto t3_m = (sigma_4_m * beta_m); - t3_m += (w_4_m + gamma_m); - - Accumulator t0(t0_m); - Accumulator t1(t1_m); - Accumulator t2(t2_m); - Accumulator t3(t3_m); - - return t0 * t1 * t2 * t3; - // using View = typename Accumulator::View; - // using ParameterView = GetParameterView; - // // TODO. to use UnivariateMonomial... we want something that does not require us to propagate the type across - // // ContainerOverSubrelations - - // auto w_1 = View(in.w_l); - // auto w_2 = View(in.w_r); - // auto w_3 = View(in.w_o); - // auto w_4 = View(in.w_4); - - // auto sigma_1 = View(in.sigma_1); - // auto sigma_2 = View(in.sigma_2); - // auto sigma_3 = View(in.sigma_3); - // auto sigma_4 = View(in.sigma_4); - - // const auto& beta = ParameterView(params.beta); - // const auto& gamma = ParameterView(params.gamma); - - // // witness degree 4; full degree 8 - // return (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * - // (w_4 + sigma_4 * beta + gamma); + + auto w_1 = View(in.w_l); + auto w_2 = View(in.w_r); + auto w_3 = View(in.w_o); + auto w_4 = View(in.w_4); + + auto sigma_1 = View(in.sigma_1); + auto sigma_2 = View(in.sigma_2); + auto sigma_3 = View(in.sigma_3); + auto sigma_4 = View(in.sigma_4); + + const auto& beta = ParameterView(params.beta); + const auto& gamma = ParameterView(params.gamma); + + // witness degree 4; full degree 8 + return (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) * + (w_4 + sigma_4 * beta + gamma); } /** @@ -288,25 +180,35 @@ template class UltraPermutationRelationImpl { // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 // adds however we do these automatically atm? in theory we could remove about 80 additions- - auto t1 = (id_1_m * beta_m) + w_1_plus_gamma; + auto t1 = (id_1_m * beta_m); + t1 += w_1_plus_gamma; + t1 *= scaling_factor; auto t2 = id_2_m * beta_m; + t2 += w_2_plus_gamma; auto t3 = id_3_m * beta_m; + t3 += w_3_plus_gamma; auto t4 = id_4_m * beta_m; + t4 += w_4_plus_gamma; auto t5 = sigma_1_m * beta_m; + t5 += w_1_plus_gamma; + t5 *= scaling_factor; auto t6 = sigma_2_m * beta_m; + t6 += w_2_plus_gamma; auto t7 = sigma_3_m * beta_m; + t7 += w_3_plus_gamma; auto t8 = sigma_4_m * beta_m; + t8 += w_4_plus_gamma; - const Accumulator numerator_1((t1)); - const Accumulator numerator_2((t2) + w_2_plus_gamma); - const Accumulator numerator_3((t3) + w_3_plus_gamma); - const Accumulator numerator_4((t4) + w_4_plus_gamma); + const Accumulator numerator_1(t1); + const Accumulator numerator_2(t2); + const Accumulator numerator_3(t3); + const Accumulator numerator_4(t4); - const Accumulator denominator_1((t5) + w_1_plus_gamma); - const Accumulator denominator_2((t6) + w_2_plus_gamma); - const Accumulator denominator_3((t7) + w_3_plus_gamma); - const Accumulator denominator_4((t8) + w_4_plus_gamma); + const Accumulator denominator_1(t5); + const Accumulator denominator_2(t6); + const Accumulator denominator_3(t7); + const Accumulator denominator_4(t8); const auto numerator = numerator_1 * numerator_2 * numerator_3 * numerator_4; const auto denominator = denominator_1 * denominator_2 * denominator_3 * denominator_4; @@ -322,8 +224,7 @@ template class UltraPermutationRelationImpl { const Accumulator public_input_term(public_input_term_m); // witness degree: deg 5 - deg 5 = deg 5 // total degree: deg 9 - deg 10 = deg 10 - std::get<0>(accumulators) += - (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)) * scaling_factor; + std::get<0>(accumulators) += (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)); // Contribution (2) using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; From 019d8aa90919eee6346d81049712aef83587f687 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 02:00:01 +0000 Subject: [PATCH 07/30] wip --- .../relations/permutation_relation.hpp | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index 28ac1db84fd..205a3f40397 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -200,18 +200,15 @@ template class UltraPermutationRelationImpl { auto t8 = sigma_4_m * beta_m; t8 += w_4_plus_gamma; - const Accumulator numerator_1(t1); - const Accumulator numerator_2(t2); - const Accumulator numerator_3(t3); - const Accumulator numerator_4(t4); - - const Accumulator denominator_1(t5); - const Accumulator denominator_2(t6); - const Accumulator denominator_3(t7); - const Accumulator denominator_4(t8); - - const auto numerator = numerator_1 * numerator_2 * numerator_3 * numerator_4; - const auto denominator = denominator_1 * denominator_2 * denominator_3 * denominator_4; + const Accumulator numerator(t1); + numerator *= Accumulator(t2); + numerator *= Accumulator(t3); + numerator *= Accumulator(t4); + + const Accumulator denominator(t5); + denominator *= Accumulator(t6); + denominator *= Accumulator(t7); + denominator *= Accumulator(t8); const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); const auto z_perm = View(in.z_perm); From af2df2102bdbc908d097262a0fe168f67ecca3e1 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 02:01:31 +0000 Subject: [PATCH 08/30] wip --- .../cpp/src/barretenberg/relations/permutation_relation.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index 205a3f40397..c4fb3cb83bf 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -200,12 +200,12 @@ template class UltraPermutationRelationImpl { auto t8 = sigma_4_m * beta_m; t8 += w_4_plus_gamma; - const Accumulator numerator(t1); + Accumulator numerator(t1); numerator *= Accumulator(t2); numerator *= Accumulator(t3); numerator *= Accumulator(t4); - const Accumulator denominator(t5); + Accumulator denominator(t5); denominator *= Accumulator(t6); denominator *= Accumulator(t7); denominator *= Accumulator(t8); From ae4246ea389f4376e8aeb04c2ba3023dcaa8f637 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 02:34:00 +0000 Subject: [PATCH 09/30] wip --- .../polynomials/univariate_monomial.hpp | 13 +-- .../relations/ultra_arithmetic_relation.hpp | 89 +++++++++++++++---- 2 files changed, 80 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index 8a6df4dc121..63e7af2c952 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -327,17 +327,20 @@ template class UnivariateMono // Operations between Univariate and scalar UnivariateMonomial& operator+=(const Fr& scalar) + requires(!has_a0_plus_a1) { coefficients[0] += scalar; return *this; } UnivariateMonomial& operator-=(const Fr& scalar) + requires(!has_a0_plus_a1) { coefficients[0] -= scalar; return *this; } UnivariateMonomial& operator*=(const Fr& scalar) + requires(!has_a0_plus_a1) { coefficients[0] *= scalar; coefficients[1] *= scalar; @@ -347,23 +350,23 @@ template class UnivariateMono return *this; } - UnivariateMonomial operator+(const Fr& scalar) const + UnivariateMonomial operator+(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateMonomial res(*this); res += scalar; return res; } - UnivariateMonomial operator-(const Fr& scalar) const + UnivariateMonomial operator-(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateMonomial res(*this); res -= scalar; return res; } UnivariateMonomial operator*(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateMonomial res(*this); res.coefficients[0] *= scalar; res.coefficients[1] *= scalar; if constexpr (domain_end == 3) { diff --git a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp index bfc6e85bf85..878ff736bbb 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp @@ -86,29 +86,84 @@ template class UltraArithmeticRelationImpl { { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using View = typename Accumulator::View; - auto w_l = View(in.w_l); - auto w_r = View(in.w_r); - auto w_o = View(in.w_o); - auto w_4 = View(in.w_4); - auto w_4_shift = View(in.w_4_shift); - auto q_m = View(in.q_m); - auto q_l = View(in.q_l); - auto q_r = View(in.q_r); - auto q_o = View(in.q_o); - auto q_4 = View(in.q_4); - auto q_c = View(in.q_c); + // auto w_l = View(in.w_l); + // auto w_r = View(in.w_r); + // auto w_o = View(in.w_o); + // auto w_4 = View(in.w_4); + // auto w_4_shift = View(in.w_4_shift); + // auto q_m = View(in.q_m); + // auto q_l = View(in.q_l); + // auto q_r = View(in.q_r); + // auto q_o = View(in.q_o); + // auto q_4 = View(in.q_4); + // auto q_c = View(in.q_c); + // auto q_arith = View(in.q_arith); + + // static const FF neg_half = FF(-2).invert(); + + // auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; + // tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; + // tmp += (q_arith - 1) * w_4_shift; + // tmp *= q_arith; + // tmp *= scaling_factor; + // std::get<0>(evals) += tmp; + + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + // auto w_l_m = MonomialAccumulator(in.w_l); + // auto w_r_m = MonomialAccumulator(in.w_r); + auto q_arith_m = MonomialAccumulator(in.q_arith); + // auto q_m_m = MonomialAccumulator(in.q_m); + + auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); + auto w_l_m = MonomialAccumulator(in.w_l); + auto w_r_m = MonomialAccumulator(in.w_r); + auto w_o_m = MonomialAccumulator(in.w_o); + auto w_4_m = MonomialAccumulator(in.w_4); + auto q_m_m = MonomialAccumulator(in.q_m); + auto q_l_m = MonomialAccumulator(in.q_l); + auto q_r_m = MonomialAccumulator(in.q_r); + auto q_o_m = MonomialAccumulator(in.q_o); + auto q_4_m = MonomialAccumulator(in.q_4); + auto q_c_m = MonomialAccumulator(in.q_c); auto q_arith = View(in.q_arith); static const FF neg_half = FF(-2).invert(); - auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; - tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; - tmp += (q_arith - 1) * w_4_shift; - tmp *= q_arith; - tmp *= scaling_factor; - std::get<0>(evals) += tmp; + // auto tmp0 = (q_arith - 3) * q_m * Accumulator(w_r_m * w_l_m); + // tmp0 *= neg_half; + // tmp0 += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; + // tmp0 += (q_arith - 1) * w_4_shift; + // tmp0 *= q_arith; + // tmp0 *= scaling_factor; + + // std::get<0>(evals) += tmp0; + + auto tmp0 = Accumulator(w_r_m * w_l_m * neg_half * scaling_factor) * Accumulator((q_arith_m - 3) * q_m_m); + auto tmp1 = (q_l_m * w_l_m) + (q_r_m * w_r_m) + (q_o_m * w_o_m) + (q_4_m * w_4_m) + q_c_m; + tmp1 += (q_arith_m - 1) * w_4_shift_m; + tmp1 *= scaling_factor; + + std::get<0>(evals) += (tmp0 + Accumulator(tmp1)) * q_arith; + // auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; + // tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; + // tmp += (q_arith - 1) * w_4_shift; + // tmp *= q_arith; + // tmp *= scaling_factor; + // std::get<0>(evals) += tmp; } { + // using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; + // // using View = typename Accumulator::View; + // using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + // auto w_l = MonomialAccumulator(in.w_l); + // auto w_4 = MonomialAccumulator(in.w_4); + // auto w_l_shift = MonomialAccumulator(in.w_l_shift); + // auto q_m = MonomialAccumulator(in.q_m); + // auto q_arith = MonomialAccumulator(in.q_arith); + + // auto tmp0 = (w_l + w_4 - w_l_shift + q_m) * (q_arith - 2); + // auto tmp1 = (q_arith - 1) * q_arith * scaling_factor; + // std::get<1>(evals) += Accumulator(tmp0) * Accumulator(tmp1); using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; using View = typename Accumulator::View; auto w_l = View(in.w_l); From a5d457e830487c4767136ec9bcd3d4a54a856dc7 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 10 Nov 2024 02:40:09 +0000 Subject: [PATCH 10/30] wip --- .../cpp/src/barretenberg/polynomials/univariate.hpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 0ecb6ce0aa1..7bfc335a960 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -109,15 +109,17 @@ template () const From 1d0fbb0f6caf671043428c44822d995d1a218f3e Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 12 Nov 2024 06:56:15 +0000 Subject: [PATCH 11/30] wip --- .../delta_range_constraint_relation.hpp | 41 +++++------ .../relations/poseidon2_internal_relation.hpp | 69 +++++++++++-------- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp index 60e4da82bb0..e0b2948122d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp @@ -57,16 +57,18 @@ template class DeltaRangeConstraintRelationImpl { { PROFILE_THIS_NAME("DeltaRange::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using View = typename Accumulator::View; auto w_1 = View(in.w_l); auto w_2 = View(in.w_r); auto w_3 = View(in.w_o); auto w_4 = View(in.w_4); auto w_1_shift = View(in.w_l_shift); - auto q_delta_range = View(in.q_delta_range); + auto q_delta_range_m = MonomialAccumulator(in.q_delta_range); - static const FF minus_one = FF(-1); - static const FF minus_two = FF(-2); + auto q_delta_range_scaled_m = q_delta_range_m * scaling_factor; + Accumulator q_delta_range_scaled(q_delta_range_scaled_m); // Compute wire differences auto delta_1 = w_2 - w_1; @@ -75,36 +77,27 @@ template class DeltaRangeConstraintRelationImpl { auto delta_4 = w_1_shift - w_4; // Contribution (1) - auto tmp_1 = (delta_1 + minus_one).sqr() + minus_one; - tmp_1 *= (delta_1 + minus_two).sqr() + minus_one; - tmp_1 *= q_delta_range; - tmp_1 *= scaling_factor; + auto tmp_1 = (delta_1 - FF(3)) * delta_1; + tmp_1 *= (tmp_1 + FF(2)); + tmp_1 *= q_delta_range_scaled; std::get<0>(accumulators) += tmp_1; // Contribution (2) - auto tmp_2 = (delta_2 + minus_one).sqr() + minus_one; - tmp_2 *= (delta_2 + minus_two).sqr() + minus_one; - tmp_2 *= q_delta_range; - tmp_2 *= scaling_factor; + auto tmp_2 = (delta_2 - FF(3)) * delta_2; + tmp_2 *= (tmp_2 + FF(2)); + tmp_2 *= q_delta_range_scaled; std::get<1>(accumulators) += tmp_2; // Contribution (3) - auto tmp_3 = (delta_3 + minus_one).sqr() + minus_one; - tmp_3 *= (delta_3 + minus_two).sqr() + minus_one; - tmp_3 *= q_delta_range; - tmp_3 *= scaling_factor; + auto tmp_3 = (delta_3 - FF(3)) * delta_3; + tmp_3 *= (tmp_3 + FF(2)); + tmp_3 *= q_delta_range_scaled; std::get<2>(accumulators) += tmp_3; - // (d4 - 1)^2 - 1 = d4d4 - 2d4 - // (d4 - 2)^2 - 1 = d4d4 - 4d4 + 3 - - // (d4 - 1)^2 - // d4 + d4 + 3 // Contribution (4) - auto tmp_4 = (delta_4 + minus_one).sqr() + minus_one; - tmp_4 *= (delta_4 + minus_two).sqr() + minus_one; - tmp_4 *= q_delta_range; - tmp_4 *= scaling_factor; + auto tmp_4 = (delta_4 - FF(3)) * delta_4; + tmp_4 *= (tmp_4 + FF(2)); + tmp_4 *= q_delta_range_scaled; std::get<3>(accumulators) += tmp_4; }; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp index 9e84d736af4..0a4c1bd810d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp @@ -62,18 +62,19 @@ template class Poseidon2InternalRelationImpl { { PROFILE_THIS_NAME("PoseidonInt::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using View = typename Accumulator::View; auto w_l = View(in.w_l); - auto w_r = View(in.w_r); - auto w_o = View(in.w_o); - auto w_4 = View(in.w_4); - auto w_l_shift = View(in.w_l_shift); - auto w_r_shift = View(in.w_r_shift); - auto w_o_shift = View(in.w_o_shift); - auto w_4_shift = View(in.w_4_shift); + auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); + auto w_r_shift_m = MonomialAccumulator(in.w_r_shift); + auto w_o_shift_m = MonomialAccumulator(in.w_o_shift); + auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); auto q_l = View(in.q_l); - auto q_poseidon2_internal = View(in.q_poseidon2_internal); + auto q_poseidon2_internal_m = MonomialAccumulator(in.q_poseidon2_internal); + // old 9 muls, 14 adds + // new: // add round constants auto s1 = w_l + q_l; @@ -81,34 +82,44 @@ template class Poseidon2InternalRelationImpl { auto u1 = s1.sqr(); u1 = u1.sqr(); u1 *= s1; - auto u2 = w_r; - auto u3 = w_o; - auto u4 = w_4; + auto u2_m = MonomialAccumulator(in.w_r); + auto u3_m = MonomialAccumulator(in.w_o); + auto u4_m = MonomialAccumulator(in.w_4); + auto q_pos_by_scaling_m = (q_poseidon2_internal_m * scaling_factor); + auto q_pos_by_scaling = Accumulator(q_pos_by_scaling_m); // matrix mul with v = M_I * u 4 muls and 7 additions - auto sum = u1 + u2 + u3 + u4; + auto partial_sum = u2_m + u3_m + u4_m; + auto scaled_u1 = u1 * q_pos_by_scaling; - auto q_pos_by_scaling = q_poseidon2_internal * scaling_factor; + static const auto diagonal_term = FF(1) + crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[0]; + auto barycentric_term = scaled_u1 * (diagonal_term); + auto monomial_term = partial_sum; + monomial_term -= w_l_shift_m; + barycentric_term += Accumulator(monomial_term * q_pos_by_scaling_m); + std::get<0>(evals) += barycentric_term; - auto v1 = u1 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[0]; - v1 += sum; - auto tmp = q_pos_by_scaling * (v1 - w_l_shift); - std::get<0>(evals) += tmp; + auto v2_m = u2_m * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[1]; + v2_m += partial_sum; + v2_m -= w_r_shift_m; + barycentric_term = Accumulator(v2_m * q_pos_by_scaling_m); + barycentric_term += scaled_u1; + std::get<1>(evals) += barycentric_term; - auto v2 = u2 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[1]; - v2 += sum; - tmp = q_pos_by_scaling * (v2 - w_r_shift); - std::get<1>(evals) += tmp; + auto v3_m = u3_m * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[2]; + v3_m += partial_sum; + v3_m -= w_o_shift_m; + barycentric_term = Accumulator(v3_m * q_pos_by_scaling_m); + barycentric_term += scaled_u1; + std::get<2>(evals) += barycentric_term; - auto v3 = u3 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[2]; - v3 += sum; - tmp = q_pos_by_scaling * (v3 - w_o_shift); - std::get<2>(evals) += tmp; + auto v4_m = u4_m * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[3]; + v4_m += partial_sum; + v4_m -= w_4_shift_m; - auto v4 = u4 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[3]; - v4 += sum; - tmp = q_pos_by_scaling * (v4 - w_4_shift); - std::get<3>(evals) += tmp; + barycentric_term = Accumulator(v4_m * q_pos_by_scaling_m); + barycentric_term += scaled_u1; + std::get<3>(evals) += barycentric_term; }; }; // namespace bb From e66e3d6a572f0a4a621c8f130c06298566648200 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 12 Nov 2024 07:22:01 +0000 Subject: [PATCH 12/30] wip --- .../relations/ultra_arithmetic_relation.hpp | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp index 878ff736bbb..f5203163413 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp @@ -83,9 +83,18 @@ template class UltraArithmeticRelationImpl { const FF& scaling_factor) { PROFILE_THIS_NAME("Arithmetic::accumulate"); + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + + auto w_l_m = MonomialAccumulator(in.w_l); + auto w_4_m = MonomialAccumulator(in.w_4); + auto q_arith_m = MonomialAccumulator(in.q_arith); + auto q_m_m = MonomialAccumulator(in.q_m); + + auto q_arith_sub_1 = q_arith_m - FF(1); + auto scaled_q_arith = q_arith_m * scaling_factor; { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; // auto w_l = View(in.w_l); // auto w_r = View(in.w_r); // auto w_o = View(in.w_o); @@ -111,21 +120,16 @@ template class UltraArithmeticRelationImpl { using MonomialAccumulator = typename Accumulator::MonomialAccumulator; // auto w_l_m = MonomialAccumulator(in.w_l); // auto w_r_m = MonomialAccumulator(in.w_r); - auto q_arith_m = MonomialAccumulator(in.q_arith); // auto q_m_m = MonomialAccumulator(in.q_m); auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); - auto w_l_m = MonomialAccumulator(in.w_l); auto w_r_m = MonomialAccumulator(in.w_r); auto w_o_m = MonomialAccumulator(in.w_o); - auto w_4_m = MonomialAccumulator(in.w_4); - auto q_m_m = MonomialAccumulator(in.q_m); auto q_l_m = MonomialAccumulator(in.q_l); auto q_r_m = MonomialAccumulator(in.q_r); auto q_o_m = MonomialAccumulator(in.q_o); auto q_4_m = MonomialAccumulator(in.q_4); auto q_c_m = MonomialAccumulator(in.q_c); - auto q_arith = View(in.q_arith); static const FF neg_half = FF(-2).invert(); @@ -138,12 +142,11 @@ template class UltraArithmeticRelationImpl { // std::get<0>(evals) += tmp0; - auto tmp0 = Accumulator(w_r_m * w_l_m * neg_half * scaling_factor) * Accumulator((q_arith_m - 3) * q_m_m); + auto tmp0 = Accumulator(w_r_m * w_l_m * neg_half) * Accumulator((q_arith_m - 3) * q_m_m); auto tmp1 = (q_l_m * w_l_m) + (q_r_m * w_r_m) + (q_o_m * w_o_m) + (q_4_m * w_4_m) + q_c_m; - tmp1 += (q_arith_m - 1) * w_4_shift_m; - tmp1 *= scaling_factor; + tmp1 += q_arith_sub_1 * w_4_shift_m; - std::get<0>(evals) += (tmp0 + Accumulator(tmp1)) * q_arith; + std::get<0>(evals) += (tmp0 + Accumulator(tmp1)) * Accumulator(scaled_q_arith); // auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; // tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; // tmp += (q_arith - 1) * w_4_shift; @@ -164,20 +167,14 @@ template class UltraArithmeticRelationImpl { // auto tmp0 = (w_l + w_4 - w_l_shift + q_m) * (q_arith - 2); // auto tmp1 = (q_arith - 1) * q_arith * scaling_factor; // std::get<1>(evals) += Accumulator(tmp0) * Accumulator(tmp1); - using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - using View = typename Accumulator::View; - auto w_l = View(in.w_l); - auto w_4 = View(in.w_4); - auto w_l_shift = View(in.w_l_shift); - auto q_m = View(in.q_m); - auto q_arith = View(in.q_arith); - - auto tmp = w_l + w_4 - w_l_shift + q_m; - tmp *= (q_arith - 2); - tmp *= (q_arith - 1); - tmp *= q_arith; - tmp *= scaling_factor; - std::get<1>(evals) += tmp; + using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; + + auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); + + auto tmp_0 = w_l_m + w_4_m - w_l_shift_m + q_m_m; + auto tmp_1 = tmp_0 * (q_arith_m - FF(2)); + auto tmp_2 = q_arith_sub_1 * scaled_q_arith; + std::get<1>(evals) += ShortAccumulator(tmp_1) * ShortAccumulator(tmp_2); }; }; }; From ec321d1385cea15aa9cbb8ad0160c80fcea0b35a Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Mon, 18 Nov 2024 08:06:28 +0000 Subject: [PATCH 13/30] wip --- .../polynomials/univariate_monomial.hpp | 4 ++ .../protogalaxy_prover_internal.hpp | 32 +++++++++- .../relations/auxiliary_relation.hpp | 30 +++++---- .../relations/databus_lookup_relation.hpp | 63 ++++++++++--------- .../delta_range_constraint_relation.hpp | 19 +++--- .../relations/ecc_op_queue_relation.hpp | 22 +++---- .../relations/elliptic_relation.hpp | 34 +++++----- .../relations/logderiv_lookup_relation.hpp | 46 +++++++++----- .../relations/permutation_relation.hpp | 12 ++-- .../relations/poseidon2_external_relation.hpp | 46 +++++++------- .../relations/poseidon2_internal_relation.hpp | 7 +-- .../stdlib_circuit_builders/mega_flavor.hpp | 1 - 12 files changed, 183 insertions(+), 133 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index 63e7af2c952..85fff1fab2e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -300,6 +300,10 @@ template class UnivariateMono UnivariateMonomial res; res.coefficients[0] = -coefficients[0]; res.coefficients[1] = -coefficients[1]; + if constexpr (domain_end == 3) { + res.coefficients[2] = -coefficients[2]; + } + return res; } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index d02e63b4776..1a569ff3bff 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -43,6 +43,18 @@ template class ProtogalaxyProverInternal { // the folded relation batching challenge. using ExtendedUnivariateWithRandomization = Univariate; + // TODO: use the Monomial type directly + // TODO: describe wtf is going on here + using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<3>; + using ShortUnivariates = typename Flavor::template ProverUnivariatesWithOptimisticSkipping<3, DeciderPKs::NUM - 1>; + static constexpr size_t SHORT_LENGTH = 3; + + // using ShortUnivariatesNoOptimisticSkipping = + // typename Flavor::template ProverUnivariates; + // using ShortUnivariates = + // typename Flavor::template ProverUnivariatesWithOptimisticSkipping; + // static constexpr size_t SHORT_LENGTH = ExtendedUnivariate::LENGTH; using ExtendedUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates; using ExtendedUnivariates = @@ -254,16 +266,24 @@ template class ProtogalaxyProverInternal { template static void extend_univariates( - std::conditional_t& + std::conditional_t< + std::same_as, + std::conditional_t, + std::conditional_t>& extended_univariates, const DeciderPKs& keys, const size_t row_idx) { + // we get the incoming univariates from the deciver proving key... + // we want to access, for each univariate, a parameter that defines the maximu mdegree PROFILE_THIS_NAME("PG::extend_univariates"); - auto incoming_univariates = keys.template row_to_univariates(row_idx); + static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; + auto incoming_univariates = keys.template row_to_univariates(row_idx); for (auto [extended_univariate, incoming_univariate] : zip_view(extended_univariates.get_all(), incoming_univariates)) { + // if constexpr (!std::same_as) { incoming_univariate.template self_extend_from(); + // } extended_univariate = std::move(incoming_univariate); } } @@ -350,7 +370,13 @@ template class ProtogalaxyProverInternal { // doesn't skip computation), so we need to define types depending on the template instantiation using ThreadAccumulators = TupleOfTuples; using ExtendedUnivatiatesType = - std::conditional_t; + + std::conditional_t< + std::same_as, + std::conditional_t, + std::conditional_t>; // Construct univariate accumulator containers; one per thread std::vector thread_univariate_accumulators(num_threads); diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index 07ff87f90f3..162566d0c24 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -143,12 +143,8 @@ template class AuxiliaryRelationImpl { auto q_4_m = MonomialAccumulator(in.q_4); auto q_m_m = MonomialAccumulator(in.q_m); auto q_c_m = MonomialAccumulator(in.q_c); + auto q_arith_m = MonomialAccumulator(in.q_arith); - auto q_2 = View(in.q_r); - auto q_3 = View(in.q_o); - auto q_4 = View(in.q_4); - auto q_m = View(in.q_m); - auto q_arith = View(in.q_arith); auto q_aux_m = MonomialAccumulator(in.q_aux); const FF LIMB_SIZE(uint256_t(1) << 68); const FF SUBLIMB_SHIFT(uint256_t(1) << 14); @@ -168,21 +164,21 @@ template class AuxiliaryRelationImpl { non_native_field_gate_2_m *= LIMB_SIZE; non_native_field_gate_2_m -= w_4_shift_m; non_native_field_gate_2_m += limb_subproduct; - auto non_native_field_gate_2 = Accumulator(non_native_field_gate_2_m) * q_4; + auto non_native_field_gate_2 = Accumulator(non_native_field_gate_2_m) * Accumulator(q_4_m); limb_subproduct *= LIMB_SIZE; limb_subproduct += (w_1_shift_m * w_2_shift_m); auto non_native_field_gate_1_m = limb_subproduct; non_native_field_gate_1_m -= (w_3_m + w_4_m); - auto non_native_field_gate_1 = Accumulator(non_native_field_gate_1_m) * q_3; + auto non_native_field_gate_1 = Accumulator(non_native_field_gate_1_m) * Accumulator(q_3_m); auto non_native_field_gate_3_m = limb_subproduct; non_native_field_gate_3_m += w_4_m; non_native_field_gate_3_m -= (w_3_shift_m + w_4_shift_m); - auto non_native_field_gate_3 = Accumulator(non_native_field_gate_3_m) * q_m; + auto non_native_field_gate_3 = Accumulator(non_native_field_gate_3_m) * Accumulator(q_m_m); auto non_native_field_identity = non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3; - non_native_field_identity *= q_2; + non_native_field_identity *= Accumulator(q_2_m); // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm // deg 2 @@ -286,7 +282,8 @@ template class AuxiliaryRelationImpl { auto adjacent_values_match_if_adjacent_indices_match = ShortAccumulator(index_delta_is_zero_m * record_delta_m); // deg 2 - auto q_aux_by_scaling = Accumulator(q_aux_m * scaling_factor); + auto q_aux_by_scaling_m = q_aux_m * scaling_factor; + auto q_aux_by_scaling = Accumulator(q_aux_by_scaling_m); auto q_one_by_two_m = q_1_m * q_2_m; auto q_one_by_two = ShortAccumulator(q_one_by_two_m); auto q_one_by_two_by_aux_by_scaling = q_one_by_two * q_aux_by_scaling; @@ -316,8 +313,8 @@ template class AuxiliaryRelationImpl { * with a WRITE operation. */ auto neg_access_type_m = (partial_record_check_m - w_4_m); // will be 0 or 1 for honest Prover; deg 1 or 2 - Accumulator neg_access_type(neg_access_type_m); - auto access_check = neg_access_type * neg_access_type + neg_access_type; // check value is 0 or 1; deg 2 or 4 + ShortAccumulator neg_access_type(neg_access_type_m); + auto access_check = neg_access_type.sqr() + neg_access_type; // check value is 0 or 1; deg 2 or 4 // TODO(https://github.com/AztecProtocol/barretenberg/issues/757): If we sorted in // reverse order we could re-use `partial_record_check` 1 - (w3' * eta_three + w2' * eta_two + w1' * @@ -339,7 +336,7 @@ template class AuxiliaryRelationImpl { // deg 2 or 4 auto next_gate_access_type_is_boolean = neg_next_gate_access_type.sqr() + neg_next_gate_access_type; - auto q_arith_by_aux_and_scaling = q_arith * q_aux_by_scaling; + auto q_arith_by_aux_and_scaling = Accumulator(q_arith_m * q_aux_by_scaling_m); // Putting it all together... std::get<3>(accumulators) += adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * @@ -348,7 +345,7 @@ template class AuxiliaryRelationImpl { std::get<5>(accumulators) += ShortView(next_gate_access_type_is_boolean * q_arith_by_aux_and_scaling); // deg 4 or 6 - auto RAM_consistency_check_identity = access_check * (q_arith); // deg 3 or 5 + auto RAM_consistency_check_identity = access_check * q_arith_by_aux_and_scaling; // deg 3 or 5 /** * RAM Timestamp Consistency Check @@ -371,11 +368,12 @@ template class AuxiliaryRelationImpl { auto memory_identity = ROM_consistency_check_identity; // deg 3 or 4 memory_identity += RAM_timestamp_check_identity * ShortAccumulator(q_4_m * q_1_m); // deg 4 memory_identity += memory_record_check * ShortAccumulator(q_m_m * q_1_m); // deg 3 or 4 - memory_identity += RAM_consistency_check_identity; // deg 3 or 5 + // memory_identity += RAM_consistency_check_identity; // deg 3 or 5 // (deg 3 or 5) + (deg 4) + (deg 3) auto auxiliary_identity = memory_identity + non_native_field_identity + limb_accumulator_identity; - auxiliary_identity *= q_aux_by_scaling; // deg 5 or 6 + auxiliary_identity *= q_aux_by_scaling; // deg 5 or 6 + auxiliary_identity += RAM_consistency_check_identity; // deg 3 or 5 std::get<0>(accumulators) += ShortView(auxiliary_identity); }; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index bb29d9bc8a9..39d0821aa3a 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -153,11 +153,12 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_inverse_exists(const AllEntities& in) { - using View = typename Accumulator::View; - - const auto is_read_gate = get_read_selector(in); // is this a read gate - const auto read_tag = View(BusData::read_tags(in)); // does row contain data being read + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + const auto is_read_gate = get_read_selector(in); // is this a read gate + const auto read_tag_m = + MonomialAccumulator(BusData::read_tags(in)); // does row contain data being read + const Accumulator read_tag(read_tag_m); return is_read_gate + read_tag - (is_read_gate * read_tag); } @@ -169,12 +170,12 @@ template class DatabusLookupRelationImpl { template static Accumulator get_read_selector(const AllEntities& in) { - using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - auto q_busread = View(in.q_busread); - auto column_selector = View(BusData::selector(in)); + auto q_busread = MonomialAccumulator(in.q_busread); + auto column_selector = MonomialAccumulator(BusData::selector(in)); - return q_busread * column_selector; + return Accumulator(q_busread * column_selector); } /** @@ -184,16 +185,18 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) { + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using View = typename Accumulator::View; using ParameterView = GetParameterView; + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - const auto& id = View(in.databus_id); - const auto& value = View(BusData::values(in)); - const auto& gamma = ParameterView(params.gamma); - const auto& beta = ParameterView(params.beta); + const auto& id = MonomialAccumulator(in.databus_id); + const auto& value = MonomialAccumulator(BusData::values(in)); + const auto& gamma = ParameterMonomialAccumulator(params.gamma); + const auto& beta = ParameterMonomialAccumulator(params.beta); // Construct value_i + idx_i*\beta + \gamma - return value + gamma + id * beta; // degree 1 + return Accumulator(id * beta + value + gamma); // degree 1 } /** @@ -204,17 +207,19 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) { + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; using View = typename Accumulator::View; using ParameterView = GetParameterView; + using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; // Bus value stored in w_1, index into bus column stored in w_2 - const auto& w_1 = View(in.w_l); - const auto& w_2 = View(in.w_r); - const auto& gamma = ParameterView(params.gamma); - const auto& beta = ParameterView(params.beta); + const auto& w_1 = MonomialAccumulator(in.w_l); + const auto& w_2 = MonomialAccumulator(in.w_r); + const auto& gamma = ParameterMonomialAccumulator(params.gamma); + const auto& beta = ParameterMonomialAccumulator(params.beta); // Construct value + index*\beta + \gamma - return w_1 + gamma + w_2 * beta; + return Accumulator((w_2 * beta) + w_1 + gamma); } /** @@ -284,16 +289,15 @@ template class DatabusLookupRelationImpl { { PROFILE_THIS_NAME("DatabusRead::accumulate"); using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - const auto inverses = View(BusData::inverses(in)); // Degree 1 - const auto read_counts = View(BusData::read_counts(in)); // Degree 1 - const auto read_term = compute_read_term(in, params); // Degree 1 (2) - const auto write_term = compute_write_term(in, params); // Degree 1 (2) - const auto inverse_exists = compute_inverse_exists(in); // Degree 2 - const auto read_selector = get_read_selector(in); // Degree 2 - const auto write_inverse = inverses * read_term; // Degree 2 (3) - const auto read_inverse = inverses * write_term; // Degree 2 (3) + const auto inverses_m = MonomialAccumulator(BusData::inverses(in)); // Degree 1 + Accumulator inverses(inverses_m); + const auto read_counts_m = MonomialAccumulator(BusData::read_counts(in)); // Degree 1 + const auto read_term = compute_read_term(in, params); // Degree 1 (2) + const auto write_term = compute_write_term(in, params); // Degree 1 (2) + const auto inverse_exists = compute_inverse_exists(in); // Degree 2 + const auto read_selector = get_read_selector(in); // Degree 2 // Determine which pair of subrelations to update based on which bus column is being read constexpr size_t subrel_idx_1 = 2 * bus_idx; @@ -305,7 +309,10 @@ template class DatabusLookupRelationImpl { // Establish validity of the read. Note: no scaling factor here since this constraint is enforced across the // entire trace, not on a per-row basis. - std::get(accumulator) += read_selector * read_inverse - read_counts * write_inverse; // Deg 4 (5) + Accumulator tmp = read_selector * write_term; + tmp -= Accumulator(read_counts_m) * read_term; + tmp *= inverses; + std::get(accumulator) += tmp; // Deg 4 (5) } /** diff --git a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp index e0b2948122d..7ff51c02ee3 100644 --- a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp @@ -59,22 +59,21 @@ template class DeltaRangeConstraintRelationImpl { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using View = typename Accumulator::View; - auto w_1 = View(in.w_l); - auto w_2 = View(in.w_r); - auto w_3 = View(in.w_o); - auto w_4 = View(in.w_4); - auto w_1_shift = View(in.w_l_shift); + auto w_1 = MonomialAccumulator(in.w_l); + auto w_2 = MonomialAccumulator(in.w_r); + auto w_3 = MonomialAccumulator(in.w_o); + auto w_4 = MonomialAccumulator(in.w_4); + auto w_1_shift = MonomialAccumulator(in.w_l_shift); auto q_delta_range_m = MonomialAccumulator(in.q_delta_range); auto q_delta_range_scaled_m = q_delta_range_m * scaling_factor; Accumulator q_delta_range_scaled(q_delta_range_scaled_m); // Compute wire differences - auto delta_1 = w_2 - w_1; - auto delta_2 = w_3 - w_2; - auto delta_3 = w_4 - w_3; - auto delta_4 = w_1_shift - w_4; + auto delta_1 = Accumulator(w_2 - w_1); + auto delta_2 = Accumulator(w_3 - w_2); + auto delta_3 = Accumulator(w_4 - w_3); + auto delta_4 = Accumulator(w_1_shift - w_4); // Contribution (1) auto tmp_1 = (delta_1 - FF(3)) * delta_1; diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp index 5ae3ca02028..74b2949afb5 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp @@ -67,17 +67,17 @@ template class EccOpQueueRelationImpl { { PROFILE_THIS_NAME("EccOp::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto w_1 = View(in.w_l); - auto w_2 = View(in.w_r); - auto w_3 = View(in.w_o); - auto w_4 = View(in.w_4); - auto op_wire_1 = View(in.ecc_op_wire_1); - auto op_wire_2 = View(in.ecc_op_wire_2); - auto op_wire_3 = View(in.ecc_op_wire_3); - auto op_wire_4 = View(in.ecc_op_wire_4); - auto lagrange_ecc_op = View(in.lagrange_ecc_op); + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + + auto w_1 = Accumulator(MonomialAccumulator(in.w_l)); + auto w_2 = Accumulator(MonomialAccumulator(in.w_r)); + auto w_3 = Accumulator(MonomialAccumulator(in.w_o)); + auto w_4 = Accumulator(MonomialAccumulator(in.w_4)); + auto op_wire_1 = Accumulator(MonomialAccumulator(in.ecc_op_wire_1)); + auto op_wire_2 = Accumulator(MonomialAccumulator(in.ecc_op_wire_2)); + auto op_wire_3 = Accumulator(MonomialAccumulator(in.ecc_op_wire_3)); + auto op_wire_4 = Accumulator(MonomialAccumulator(in.ecc_op_wire_4)); + auto lagrange_ecc_op = Accumulator(MonomialAccumulator(in.lagrange_ecc_op)); // If lagrange_ecc_op is the indicator for ecc_op_gates, this is the indicator for the complement auto lagrange_by_scaling = lagrange_ecc_op * scaling_factor; diff --git a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp index cab447db3ae..82704a65748 100644 --- a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp @@ -64,15 +64,10 @@ template class EllipticRelationImpl { using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using View = typename Accumulator::View; - auto x_1 = View(in.w_r); - // auto y_1 = View(in.w_o); - auto x_2 = View(in.w_l_shift); // auto y_2 = View(in.w_4_shift); // auto y_3 = View(in.w_o_shift); - auto x_3 = View(in.w_r_shift); - auto y_1 = View(in.w_o); + auto x_3_m = MonomialAccumulator(in.w_r_shift); auto y_1_m = MonomialAccumulator(in.w_o); auto y_2_m = MonomialAccumulator(in.w_4_shift); @@ -94,21 +89,30 @@ template class EllipticRelationImpl { // 2. (x3 - x1) // 3. (x3 + x2 + x1) // 4. (x1 + x1 + x1) - auto x2_sub_x1 = (x_2 - x_1); - auto x1_mul_3 = (x_1 + x_1 + x_1); - auto x3_sub_x1 = x_3 - x_1; - auto x3_plus_two_x1 = x3_sub_x1 + x1_mul_3; - auto x3_plus_x2_plus_x1 = x3_plus_two_x1 + x2_sub_x1; - + auto x2_sub_x1_m = (x_2_m - x_1_m); + auto x1_mul_3_m = (x_1_m + x_1_m + x_1_m); // used + auto x3_sub_x1_m = x_3_m - x_1_m; // used + auto x3_plus_two_x1_m = x3_sub_x1_m + x1_mul_3_m; // used + auto x3_plus_x2_plus_x1_m = x3_plus_two_x1_m + x2_sub_x1_m; // used + Accumulator x3_plus_x2_plus_x1(x3_plus_x2_plus_x1_m); + Accumulator x3_sub_x1(x3_sub_x1_m); + Accumulator x1_mul_3(x1_mul_3_m); + Accumulator x3_plus_two_x1(x3_plus_two_x1_m); + // (3x1 already made in monomial basis) + // x3 - x1 = 2 adds + covnvert + // x3 + x1 + x1 = 2 adds + convert + // x3 + x2 + x1 = 2 adds + convert + // 3 converts and 6 adds = 4 * 3 + 6 = 18 adds + + // vs 6 add = 6 * 5 = 30 F adds // Contribution (1) point addition, x-coordinate check // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 - auto x2_sub_x1_m = (x_2_m - x_1_m); auto y2_sqr_m = y_2_m.sqr(); auto y1_sqr_m = y_1_m.sqr(); // auto y1y2_m = y_1_m * y_2_m; auto y2_mul_q_sign_m = y_2_m * q_sign_m; auto x_add_identity = x3_plus_x2_plus_x1 * Accumulator(x2_sub_x1_m.sqr()) - Accumulator(y2_sqr_m + y1_sqr_m) + - Accumulator(y2_mul_q_sign_m + y2_mul_q_sign_m) * y_1; + Accumulator(y2_mul_q_sign_m + y2_mul_q_sign_m) * Accumulator(y_1_m); // q_elliptic - q_elliptic * q_double // (q_elliptic - 1) * q_double @@ -152,7 +156,7 @@ template class EllipticRelationImpl { // Contribution (4) point doubling, y-coordinate check // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0 - auto x1_sqr_mul_3 = Accumulator((x_1_m + x_1_m + x_1_m) * x_1_m); + auto x1_sqr_mul_3 = Accumulator(x1_mul_3_m * x_1_m); auto neg_y_double_identity = x1_sqr_mul_3 * (x3_sub_x1) + Accumulator((y_1_m + y_1_m) * (y1_plus_y3_m)); std::get<1>(accumulators) -= neg_y_double_identity * q_elliptic_q_double_scaling; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index 8b5df3ee0ab..d335be3d5b5 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -69,18 +69,18 @@ template class LogDerivLookupRelationImpl { template static Accumulator compute_inverse_exists(const AllEntities& in) { - using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - const auto row_has_write = View(in.lookup_read_tags); - const auto row_has_read = View(in.q_lookup); - return row_has_write + row_has_read - (row_has_write * row_has_read); + const auto row_has_write = MonomialAccumulator(in.lookup_read_tags); + const auto row_has_read = MonomialAccumulator(in.q_lookup); + return Accumulator(-(row_has_write * row_has_read) + row_has_write + row_has_read); } template static Accumulator lookup_read_counts(const AllEntities& in) { - using View = typename Accumulator::View; - return Accumulator(View(in.lookup_read_counts)); + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + return Accumulator(MonomialAccumulator(in.lookup_read_counts)); } // Compute table_1 + gamma + table_2 * eta + table_3 * eta_2 + table_4 * eta_3 @@ -230,31 +230,47 @@ template class LogDerivLookupRelationImpl { // declare the accumulator of the maximum length, in non-ZK Flavors, they are of the same length, // whereas in ZK Flavors, the accumulator corresponding log derivative lookup argument sub-relation is the // longest + using ShortAccumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; - using View = typename Accumulator::View; + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + // allows to re-use the values accumulated by the accumulator of the size smaller than // the size of Accumulator declared above - using ShortView = typename std::tuple_element_t<0, ContainerOverSubrelations>::View; - const auto inverses = View(in.lookup_inverses); // Degree 1 - const auto read_counts = View(in.lookup_read_counts); // Degree 1 - const auto read_selector = View(in.q_lookup); // Degree 1 + const auto inverses_m = MonomialAccumulator(in.lookup_inverses); // Degree 1 + const Accumulator inverses(inverses_m); + const auto read_counts_m = MonomialAccumulator(in.lookup_read_counts); // Degree 1 + const auto read_selector_m = MonomialAccumulator(in.q_lookup); // Degree 1 + + // const MonomialAccumulator row_has_write = MonomialAccumulator(in.lookup_read_tags); + // const MonomialAccumulator row_has_read = MonomialAccumulator(in.q_lookup); + // auto inverse_exists_m = -(row_has_write * row_has_read) + row_has_write + row_has_read; const auto inverse_exists = compute_inverse_exists(in); // Degree 2 const auto read_term = compute_read_term(in, params); // Degree 2 (3) const auto write_term = compute_write_term(in, params); // Degree 1 (2) - const auto write_inverse = inverses * read_term; // Degree 3 (4) - const auto read_inverse = inverses * write_term; // Degree 2 (3) + // const auto write_inverse = Accumulator(inverses_m) * read_term; // Degree 3 (4) + // const auto read_inverse = Accumulator(inverses_m) * write_term; // Degree 2 (3) // Establish the correctness of the polynomial of inverses I. Note: inverses is computed so that the value is 0 // if !inverse_exists. // Degrees: 2 (3) 1 (2) 1 1 std::get<0>(accumulator) += - ShortView((read_term * write_term * inverses - inverse_exists) * scaling_factor); // Deg 4 (6) + ShortAccumulator((read_term * write_term * inverses - inverse_exists) * scaling_factor); // Deg 4 (6) // Establish validity of the read. Note: no scaling factor here since this constraint is 'linearly dependent, // i.e. enforced across the entire trace, not on a per-row basis. // Degrees: 1 2 (3) 1 3 (4) - std::get<1>(accumulator) += read_selector * read_inverse - read_counts * write_inverse; // Deg 4 (5) + + // rs * I * w - rc * I * r + + // (rs * w - rc * r) * I + Accumulator tmp = Accumulator(read_selector_m) * write_term; + tmp -= (Accumulator(read_counts_m) * read_term); + tmp *= inverses; // degree 4(5) + std::get<1>(accumulator) += tmp; // Deg 4 (5) + + // std::get<1>(accumulator) += + // Accumulator(read_selector_m) * read_inverse - Accumulator(read_counts_m) * write_inverse; // Deg 4 (5) } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index c4fb3cb83bf..5f3573f681d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -211,9 +211,9 @@ template class UltraPermutationRelationImpl { denominator *= Accumulator(t8); const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); - const auto z_perm = View(in.z_perm); + const auto z_perm_m = MonomialAccumulator(in.z_perm); const MonomialAccumulator z_perm_shift_m(in.z_perm_shift); - const auto lagrange_first = View(in.lagrange_first); + const auto lagrange_first_m = MonomialAccumulator(in.lagrange_first); const MonomialAccumulator lagrange_last_m(in.lagrange_last); auto public_input_term_m = lagrange_last_m * public_input_delta_m; @@ -221,15 +221,13 @@ template class UltraPermutationRelationImpl { const Accumulator public_input_term(public_input_term_m); // witness degree: deg 5 - deg 5 = deg 5 // total degree: deg 9 - deg 10 = deg 10 - std::get<0>(accumulators) += (((z_perm + lagrange_first) * numerator) - (public_input_term * denominator)); + std::get<0>(accumulators) += + ((Accumulator(z_perm_m + lagrange_first_m) * numerator) - (public_input_term * denominator)); // Contribution (2) using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - using ShortView = typename ShortAccumulator::View; - auto z_perm_shift_short = ShortView(in.z_perm_shift); - auto lagrange_last_short = ShortView(in.lagrange_last); - std::get<1>(accumulators) += (lagrange_last_short * z_perm_shift_short) * scaling_factor; + std::get<1>(accumulators) += ShortAccumulator((lagrange_last_m * z_perm_shift_m) * scaling_factor); }; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp index e13650e711a..5719455fd1e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp @@ -65,26 +65,26 @@ template class Poseidon2ExternalRelationImpl { { PROFILE_THIS_NAME("PoseidonExt::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - auto w_l = View(in.w_l); - auto w_r = View(in.w_r); - auto w_o = View(in.w_o); - auto w_4 = View(in.w_4); - auto w_l_shift = View(in.w_l_shift); - auto w_r_shift = View(in.w_r_shift); - auto w_o_shift = View(in.w_o_shift); - auto w_4_shift = View(in.w_4_shift); - auto q_l = View(in.q_l); - auto q_r = View(in.q_r); - auto q_o = View(in.q_o); - auto q_4 = View(in.q_4); - auto q_poseidon2_external = View(in.q_poseidon2_external); + using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + auto w_l = MonomialAccumulator(in.w_l); + auto w_r = MonomialAccumulator(in.w_r); + auto w_o = MonomialAccumulator(in.w_o); + auto w_4 = MonomialAccumulator(in.w_4); + auto w_l_shift = MonomialAccumulator(in.w_l_shift); + auto w_r_shift = MonomialAccumulator(in.w_r_shift); + auto w_o_shift = MonomialAccumulator(in.w_o_shift); + auto w_4_shift = MonomialAccumulator(in.w_4_shift); + auto q_l = MonomialAccumulator(in.q_l); + auto q_r = MonomialAccumulator(in.q_r); + auto q_o = MonomialAccumulator(in.q_o); + auto q_4 = MonomialAccumulator(in.q_4); + auto q_poseidon2_external = MonomialAccumulator(in.q_poseidon2_external); // add round constants which are loaded in selectors - auto s1 = w_l + q_l; - auto s2 = w_r + q_r; - auto s3 = w_o + q_o; - auto s4 = w_4 + q_4; + auto s1 = Accumulator(w_l + q_l); + auto s2 = Accumulator(w_r + q_r); + auto s3 = Accumulator(w_o + q_o); + auto s4 = Accumulator(w_4 + q_4); // apply s-box round auto u1 = s1.sqr(); @@ -116,17 +116,17 @@ template class Poseidon2ExternalRelationImpl { auto v1 = t3 + v2; // 5u_1 + 7u_2 + u_3 + 3u_4 auto v3 = t2 + v4; // u_1 + 3u_2 + 5u_3 + 7u_4 - auto q_pos_by_scaling = q_poseidon2_external * scaling_factor; - auto tmp = q_pos_by_scaling * (v1 - w_l_shift); + auto q_pos_by_scaling = Accumulator(q_poseidon2_external * scaling_factor); + auto tmp = q_pos_by_scaling * (v1 - Accumulator(w_l_shift)); std::get<0>(evals) += tmp; - tmp = q_pos_by_scaling * (v2 - w_r_shift); + tmp = q_pos_by_scaling * (v2 - Accumulator(w_r_shift)); std::get<1>(evals) += tmp; - tmp = q_pos_by_scaling * (v3 - w_o_shift); + tmp = q_pos_by_scaling * (v3 - Accumulator(w_o_shift)); std::get<2>(evals) += tmp; - tmp = q_pos_by_scaling * (v4 - w_4_shift); + tmp = q_pos_by_scaling * (v4 - Accumulator(w_4_shift)); std::get<3>(evals) += tmp; }; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp index 0a4c1bd810d..e392975ffd6 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp @@ -64,19 +64,18 @@ template class Poseidon2InternalRelationImpl { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using View = typename Accumulator::View; - auto w_l = View(in.w_l); + auto w_l_m = MonomialAccumulator(in.w_l); auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); auto w_r_shift_m = MonomialAccumulator(in.w_r_shift); auto w_o_shift_m = MonomialAccumulator(in.w_o_shift); auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); - auto q_l = View(in.q_l); + auto q_l_m = MonomialAccumulator(in.q_l); auto q_poseidon2_internal_m = MonomialAccumulator(in.q_poseidon2_internal); // old 9 muls, 14 adds // new: // add round constants - auto s1 = w_l + q_l; + auto s1 = Accumulator(w_l_m + q_l_m); // apply s-box round auto u1 = s1.sqr(); 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 bf304fea663..f3a2fe70be7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -779,7 +779,6 @@ class MegaFlavor { return_data_read_counts = "RETURN_DATA_READ_COUNTS"; return_data_read_tags = "RETURN_DATA_READ_TAGS"; return_data_inverses = "RETURN_DATA_INVERSES"; - q_c = "Q_C"; q_l = "Q_L"; q_r = "Q_R"; From 5c07a8a2739f7be4ceb292386ac48eeeee344358 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Mon, 18 Nov 2024 09:57:19 +0000 Subject: [PATCH 14/30] wip --- .../barretenberg/polynomials/univariate.hpp | 4 + .../protogalaxy_prover_internal.hpp | 103 ++++++++++++++++-- .../relations/permutation_relation.hpp | 4 +- 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 7bfc335a960..5aab5ffdccb 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -197,6 +197,10 @@ template class ProtogalaxyProverInternal { Univariate; // TODO: use the Monomial type directly // TODO: describe wtf is going on here - using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<3>; - using ShortUnivariates = typename Flavor::template ProverUnivariatesWithOptimisticSkipping<3, DeciderPKs::NUM - 1>; - static constexpr size_t SHORT_LENGTH = 3; + using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<2>; + using ShortUnivariates = typename Flavor::template ProverUnivariatesWithOptimisticSkipping<2, DeciderPKs::NUM - 1>; + static constexpr size_t SHORT_LENGTH = 2; // using ShortUnivariatesNoOptimisticSkipping = // typename Flavor::template ProverUnivariates; @@ -265,7 +265,7 @@ template class ProtogalaxyProverInternal { */ template - static void extend_univariates( + BB_INLINE static void extend_univariates( std::conditional_t< std::same_as, std::conditional_t, @@ -277,17 +277,97 @@ template class ProtogalaxyProverInternal { // we get the incoming univariates from the deciver proving key... // we want to access, for each univariate, a parameter that defines the maximu mdegree PROFILE_THIS_NAME("PG::extend_univariates"); + static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; auto incoming_univariates = keys.template row_to_univariates(row_idx); for (auto [extended_univariate, incoming_univariate] : zip_view(extended_univariates.get_all(), incoming_univariates)) { - // if constexpr (!std::same_as) { - incoming_univariate.template self_extend_from(); - // } + if constexpr (!std::same_as) { + incoming_univariate.template self_extend_from(); + } extended_univariate = std::move(incoming_univariate); } } + // template + // static void extend_univariates_2( + // std::conditional_t< + // std::same_as, + // std::conditional_t, + // std::conditional_t>& + // extended_univariates, + // const DeciderPKs& keys, + // const size_t row_idx) + // { + // // we get the incoming univariates from the deciver proving key... + // // we want to access, for each univariate, a parameter that defines the maximu mdegree + // PROFILE_THIS_NAME("PG::extend_univariates"); + // static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; + // auto incoming_univariates = keys.template row_to_univariates(row_idx); + // for (auto [extended_univariate, incoming_univariate] : + // zip_view(extended_univariates.get_all(), incoming_univariates)) { + // // if constexpr (!std::same_as) { + // incoming_univariate.template self_extend_from(); + // // } + // extended_univariate = std::move(incoming_univariate); + // } + // } + + // template + // BB_INLINE static void accumulate_relation_univariates_debug(const DeciderPKs& keys, + // size_t idx, + // TupleOfTuplesOfUnivariates_& univariate_accumulators, + // ExtendedUnivariates_& extended_univariates, + // const Parameters& relation_parameters, + // const FF& scaling_factor) + // { + // if (relation_idx == 0) { + // extend_univariates_2(extended_univariates, keys, idx); + // } + // if constexpr (std::same_as) { + // if (relation_idx == Flavor::NUM_RELATIONS - 1) { + // for (auto& foo : extended_univariates.get_all()) { + // foo.evaluations[2] = 1; + // } + // } + // } + // // if (relation_idx == 4) { + // // extend_univariates_2(extended_univariates, keys, idx); + // // } + // using Relation = std::tuple_element_t; + + // // Check if the relation is skippable to speed up accumulation + // if constexpr (!isSkippable) { + // // If not, accumulate normally + // Relation::accumulate(std::get(univariate_accumulators), + // extended_univariates, + // relation_parameters, + // scaling_factor); + // } else { + // // If so, only compute the contribution if the relation is active + // if (!Relation::skip(extended_univariates)) { + // Relation::accumulate(std::get(univariate_accumulators), + // extended_univariates, + // relation_parameters, + // scaling_factor); + // } + // } + + // // Repeat for the next relation. + // if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { + // accumulate_relation_univariates_debug( + // keys, idx, univariate_accumulators, extended_univariates, relation_parameters, scaling_factor); + // } + // } + /** * @brief Add the value of each relation over univariates to an appropriate accumulator * @@ -305,10 +385,10 @@ template class ProtogalaxyProverInternal { typename ExtendedUnivariates_, typename Parameters, size_t relation_idx = 0> - static void accumulate_relation_univariates(TupleOfTuplesOfUnivariates_& univariate_accumulators, - const ExtendedUnivariates_& extended_univariates, - const Parameters& relation_parameters, - const FF& scaling_factor) + BB_INLINE static void accumulate_relation_univariates(TupleOfTuplesOfUnivariates_& univariate_accumulators, + const ExtendedUnivariates_& extended_univariates, + const Parameters& relation_parameters, + const FF& scaling_factor) { using Relation = std::tuple_element_t; @@ -328,6 +408,7 @@ template class ProtogalaxyProverInternal { scaling_factor); } } + // extend_univariates_2<1>(extended_univariates, keys, idx); // Repeat for the next relation. if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index 5f3573f681d..af44129c6cf 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -212,9 +212,9 @@ template class UltraPermutationRelationImpl { const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); const auto z_perm_m = MonomialAccumulator(in.z_perm); - const MonomialAccumulator z_perm_shift_m(in.z_perm_shift); + const auto z_perm_shift_m = MonomialAccumulator(in.z_perm_shift); const auto lagrange_first_m = MonomialAccumulator(in.lagrange_first); - const MonomialAccumulator lagrange_last_m(in.lagrange_last); + const auto lagrange_last_m = MonomialAccumulator(in.lagrange_last); auto public_input_term_m = lagrange_last_m * public_input_delta_m; public_input_term_m += z_perm_shift_m; From 5d78d663c658e91654f8c8be2db50e0c024b67b0 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 15:09:42 +0000 Subject: [PATCH 15/30] small cleanup --- .../barretenberg/polynomials/univariate.hpp | 42 +- .../polynomials/univariate_monomial.hpp | 358 +----------------- .../protogalaxy_prover_internal.hpp | 103 +---- .../relations/elliptic_relation.hpp | 34 -- .../relations/logderiv_lookup_relation.hpp | 19 +- .../stdlib_circuit_builders/mega_flavor.hpp | 1 + 6 files changed, 31 insertions(+), 526 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 5aab5ffdccb..5555a917d46 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -50,36 +50,16 @@ template () const - // requires(LENGTH == 1) - // { - // static_assert(domain_start == 0); - // // (1 - X)a0 + Xa1 - // // a0 - // UnivariateMonomial result; - // result.evaluations[0] = evaluations[0]; - // return result; - // } - explicit operator UnivariateMonomial() const requires(LENGTH > 1) { - // static std::mutex g_pages_mutex; static_assert(domain_end >= 2); static_assert(domain_start == 0); - // (1 - X)a0 + Xa1 - // a0 UnivariateMonomial result; - // std::lock_guard guard(g_pages_mutex); - // std::cout << "evaluations[0] = " << evaluations[0] << std::endl; - // std::cout << "evaluations[1] = " << evaluations[1] << std::endl; - result.coefficients[0] = evaluations[0]; result.coefficients[1] = evaluations[1] - evaluations[0]; result.coefficients[2] = evaluations[1]; - // std::cout << "evaluations[1] = " << result.evaluations[1] << std::endl; - // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; return result; } @@ -194,19 +174,12 @@ template () const requires(LENGTH > 1) { - // static std::mutex g_pages_mutex; static_assert(domain_end >= 2); static_assert(domain_start == 0); - // (1 - X)a0 + Xa1 - // a0 UnivariateMonomial result; - // std::lock_guard guard(g_pages_mutex); - // std::cout << "evaluations[0] = " << evaluations[0] << std::endl; - // std::cout << "evaluations[1] = " << evaluations[1] << std::endl; result.coefficients[0] = evaluations[0]; result.coefficients[1] = evaluations[1] - evaluations[0]; result.coefficients[2] = evaluations[1]; - // std::cout << "evaluations[1] = " << result.evaluations[1] << std::endl; - // { .evaluations = { evaluations[0], evaluations[1] - evaluations[0] } }; return result; } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index 85fff1fab2e..a7d465e8a94 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -26,41 +26,10 @@ template class UnivariateMono static_assert(LENGTH == 2 || LENGTH == 3); using value_type = Fr; // used to get the type of the elements consistently with std::array - // a0 + a1.X + a2.XX - // we need... - - // a0 - // a1 + a2 - // a2 - // TODO(https://github.com/AztecProtocol/barretenberg/issues/714) Try out std::valarray? - - // struct Degree1Coefficients { - // Fr a0; - // Fr a1; - // Fr a0_plus_a1; - // }; - // struct Degree2Coefficients { - // Fr a0; - // Fr a1_plus_a2; - // Fr a2; - // }; - // union Coefficients { - // Degree1Coefficients d1; - // Degree2Coefficients d2; - // }; - // Coefficients coefficients; std::array coefficients; UnivariateMonomial() = default; - // explicit UnivariateMonomial(std::array _coefficients) - // { - // coefficients[0] = _coefficients[0]; - // if constexpr (LENGTH > 1) { - // coefficients[1] = _coefficients[1] - _coefficients[0]; - // } - // } - UnivariateMonomial(const UnivariateMonomial& other) requires(!has_a0_plus_a1) { @@ -81,80 +50,28 @@ template class UnivariateMono UnivariateMonomial(const UnivariateMonomial& other) requires(domain_end > other_domain_end) { - // (*this) as a0, a1+a2, a2 - // (other) has a0, a1 and maybe a0+a1 coefficients[0] = other.coefficients[0]; coefficients[1] = other.coefficients[1]; if constexpr (domain_end == 3) { coefficients[2] = 0; } - // std::copy(other.coefficients.begin(), other.coefficients.end(), coefficients.begin()); - // for (size_t i = other_domain_end; i < domain_end; ++i) { - // coefficients[i] = 0; - // } - // midpoint = other.midpoint; }; - // v0 = u - // v1 = v + 12 - // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a81 - // 0x30644e72e131a029b85045b68181571da92cbfcf419ffeb1d9192544cc247a8d - // (1 - X)v0 + Xv1 - // a0 = v0 - // a1 = v1 - v0 - // a0 = u - // a1 = 12 - // Construct constant Univariate from scalar which represents the value that all the points in the domain - // evaluate to - // explicit UnivariateMonomial(Fr value) - // : coefficients{} - // { - // static_assert(LENGTH == 1); - // coefficients[0] = value; - // for (size_t i = 1; i < LENGTH; ++i) { - // coefficients[i] = 0; - // } - // } - // // Construct UnivariateMonomial from UnivariateMonomialView - // explicit UnivariateMonomial(UnivariateView in) - // : coefficients{} - // { - // for (size_t i = 0; i < in.coefficients.size(); ++i) { - // coefficients[i] = in.coefficients[i]; - // } - // } - - // Fr& value_at(size_t i) - // { - // if constexpr (domain_start == 0) { - // return coefficients[i]; - // } else { - // return coefficients[i - domain_start]; - // } - // }; - // const Fr& value_at(size_t i) const - // { - // if constexpr (domain_start == 0) { - // return coefficients[i]; - // } else { - // return coefficients[i - domain_start]; - // } - // }; size_t size() { return coefficients.size(); }; - // Check if the univariate is identically zero - // bool is_zero() const - // { - // if (!coefficients[0].is_zero()) { - // return false; - // } - // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // if (!coefficients[i].is_zero()) { - // return false; - // } - // } - // return true; - // } + // Check if the UnivariateMonomial is identically zero + bool is_zero() const + requires(LENGTH == 2) + { + return coefficients[0].is_zero() || coefficients[1].is_zero(); + } + + // Check if the UnivariateMonomial is identically zero + bool is_zero() const + requires(LENGTH == 3) + { + return coefficients[2].is_zero() || coefficients[0].is_zero() || coefficients[1].is_zero(); + } // Write the Univariate coefficients to a buffer [[nodiscard]] std::vector to_buffer() const { return ::to_buffer(coefficients); } @@ -379,55 +296,6 @@ template class UnivariateMono return res; } - // // Operations between Univariate and UnivariateView - // Univariate& operator+=(const UnivariateView& view) - // { - // coefficients[0] += view.coefficients[0]; - // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // coefficients[i] += view.coefficients[i]; - // } - // return *this; - // } - - // Univariate& operator-=(const UnivariateView& view) - // { - // coefficients[0] -= view.coefficients[0]; - // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // coefficients[i] -= view.coefficients[i]; - // } - // return *this; - // } - - // Univariate& operator*=(const UnivariateView& view) - // { - // coefficients[0] *= view.coefficients[0]; - // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // coefficients[i] *= view.coefficients[i]; - // } - // return *this; - // } - - // Univariate operator+(const UnivariateView& view) const - // { - // Univariate res(*this); - // res += view; - // return res; - // } - - // Univariate operator-(const UnivariateView& view) const - // { - // Univariate res(*this); - // res -= view; - // return res; - // } - - // Univariate operator*(const UnivariateView& view) const - // { - // Univariate res(*this); - // res *= view; - // return res; - // } - // Output is immediately parsable as a list of integers by Python. friend std::ostream& operator<<(std::ostream& os, const UnivariateMonomial& u) { @@ -444,185 +312,6 @@ template class UnivariateMono return os; } - /** - * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the - * coefficients {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by - * {f(domain_start),..., f(extended_domain_end -1)} - * - * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently - * compute the needed values of f, we use the barycentric formula - * - f(x) = B(x) Σ_{i=domain_start}^{domain_end-1} v_i / (d_i*(x-x_i)) - * where - * - B(x) = Π_{i=domain_start}^{domain_end-1} (x-x_i) - * - d_i = Π_{j ∈ {domain_start, ..., domain_end-1}, j≠i} (x_i-x_j) for i ∈ {domain_start, ..., - * domain_end-1} - * - * When the domain size is two, extending f = v0(1-X) + v1X to a new value involves just one addition - * and a subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 - * = f(2) + Δ... - * - */ - // template - // Univariate extend_to() const - // { - // static constexpr size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; - // using Data = BarycentricData; - // static_assert(EXTENDED_LENGTH >= LENGTH); - - // Univariate result; - - // std::copy(coefficients.begin(), coefficients.end(), result.coefficients.begin()); - - // static constexpr Fr inverse_two = Fr(2).invert(); - // static_assert(NUM_SKIPPED_INDICES < LENGTH); - // if constexpr (LENGTH == 2) { - // Fr delta = value_at(1) - value_at(0); - // static_assert(EXTENDED_LENGTH != 0); - // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { - // result.value_at(idx + 1) = result.value_at(idx) + delta; - // } - // } else if constexpr (LENGTH == 3) { - // // Based off https://hackmd.io/@aztec-network/SyR45cmOq?type=view - // // The technique used here is the same as the length == 3 case below. - // Fr a = (value_at(2) + value_at(0)) * inverse_two - value_at(1); - // Fr b = value_at(1) - a - value_at(0); - // Fr a2 = a + a; - // Fr a_mul = a2; - // for (size_t i = 0; i < domain_end - 2; i++) { - // a_mul += a2; - // } - // Fr extra = a_mul + a + b; - // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { - // result.value_at(idx + 1) = result.value_at(idx) + extra; - // extra += a2; - // } - // } else if constexpr (LENGTH == 4) { - // static constexpr Fr inverse_six = Fr(6).invert(); // computed at compile time for efficiency - - // // To compute a barycentric extension, we can compute the coefficients of the univariate. - // // We have the evaluation of the polynomial at the domain (which is assumed to be 0, 1, 2, 3). - // // Therefore, we have the 4 linear equations from plugging into f(x) = ax^3 + bx^2 + cx + d: - // // a*0 + b*0 + c*0 + d = f(0) - // // a*1 + b*1 + c*1 + d = f(1) - // // a*2^3 + b*2^2 + c*2 + d = f(2) - // // a*3^3 + b*3^2 + c*3 + d = f(3) - // // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2), - // // f(3)], where M is: - // // 0, 0, 0, 1 - // // 1, 1, 1, 1 - // // 2^3, 2^2, 2, 1 - // // 3^3, 3^2, 3, 1 - // // We can invert this matrix in order to compute a, b, c, d: - // // -1/6, 1/2, -1/2, 1/6 - // // 1, -5/2, 2, -1/2 - // // -11/6, 3, -3/2, 1/3 - // // 1, 0, 0, 0 - // // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the - // // end for each coefficient The resulting computation here does 18 field adds, 6 subtracts, 3 - // // muls to compute a, b, c, and d. - // Fr zero_times_3 = value_at(0) + value_at(0) + value_at(0); - // Fr zero_times_6 = zero_times_3 + zero_times_3; - // Fr zero_times_12 = zero_times_6 + zero_times_6; - // Fr one_times_3 = value_at(1) + value_at(1) + value_at(1); - // Fr one_times_6 = one_times_3 + one_times_3; - // Fr two_times_3 = value_at(2) + value_at(2) + value_at(2); - // Fr three_times_2 = value_at(3) + value_at(3); - // Fr three_times_3 = three_times_2 + value_at(3); - - // Fr one_minus_two_times_3 = one_times_3 - two_times_3; - // Fr one_minus_two_times_6 = one_minus_two_times_3 + one_minus_two_times_3; - // Fr one_minus_two_times_12 = one_minus_two_times_6 + one_minus_two_times_6; - // Fr a = (one_minus_two_times_3 + value_at(3) - value_at(0)) * inverse_six; // compute a in 1 muls and 4 - // adds Fr b = (zero_times_6 - one_minus_two_times_12 - one_times_3 - three_times_3) * inverse_six; Fr c = - // (value_at(0) - zero_times_12 + one_minus_two_times_12 + one_times_6 + two_times_3 + three_times_2) * - // inverse_six; - - // // Then, outside of the a, b, c, d computation, we need to do some extra precomputation - // // This work is 3 field muls, 8 adds - // Fr a_plus_b = a + b; - // Fr a_plus_b_times_2 = a_plus_b + a_plus_b; - // size_t start_idx_sqr = (domain_end - 1) * (domain_end - 1); - // size_t idx_sqr_three = start_idx_sqr + start_idx_sqr + start_idx_sqr; - // Fr idx_sqr_three_times_a = Fr(idx_sqr_three) * a; - // Fr x_a_term = Fr(6 * (domain_end - 1)) * a; - // Fr three_a = a + a + a; - // Fr six_a = three_a + three_a; - - // Fr three_a_plus_two_b = a_plus_b_times_2 + a; - // Fr linear_term = Fr(domain_end - 1) * three_a_plus_two_b + (a_plus_b + c); - // // For each new evaluation, we do only 6 field additions and 0 muls. - // for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) { - // result.value_at(idx + 1) = result.value_at(idx) + idx_sqr_three_times_a + linear_term; - - // idx_sqr_three_times_a += x_a_term + three_a; - // x_a_term += six_a; - - // linear_term += three_a_plus_two_b; - // } - // } else { - // for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) { - // result.value_at(k) = 0; - // // compute each term v_j / (d_j*(x-x_j)) of the sum - // for (size_t j = domain_start; j != domain_end; ++j) { - // Fr term = value_at(j); - // term *= Data::precomputed_denominator_inverses[LENGTH * k + j]; - // result.value_at(k) += term; - // } - // // scale the sum by the value of of B(x) - // result.value_at(k) *= Data::full_numerator_values[k]; - // } - // } - // return result; - // } - - // template void self_extend_from() - // { - // if constexpr (INITIAL_LENGTH == 2) { - // const Fr delta = value_at(1) - value_at(0); - // Fr next = value_at(1); - // for (size_t idx = 2; idx < LENGTH; idx++) { - // next += delta; - // value_at(idx) = next; - // } - // } - // } - - /** - * @brief Evaluate a univariate at a point u not known at compile time - * and assumed not to be in the domain (else we divide by zero). - * @param f - * @return Fr - */ - // Fr evaluate(const Fr& u) const - // { - // using Data = BarycentricData; - // Fr full_numerator_value = 1; - // for (size_t i = domain_start; i != domain_end; ++i) { - // full_numerator_value *= u - i; - // } - - // // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against - // // each of these (rather than to divide by something) for each barycentric evaluation - // std::array denominator_inverses; - // for (size_t i = 0; i != LENGTH; ++i) { - // Fr inv = Data::lagrange_denominators[i]; - // inv *= u - Data::big_domain[i]; // warning: need to avoid zero here - // inv = Fr(1) / inv; - // denominator_inverses[i] = inv; - // } - - // Fr result = 0; - // // compute each term v_j / (d_j*(x-x_j)) of the sum - // for (size_t i = domain_start; i != domain_end; ++i) { - // Fr term = value_at(i); - // term *= denominator_inverses[i - domain_start]; - // result += term; - // } - // // scale the sum by the value of of B(x) - // result *= full_numerator_value; - // return result; - // }; - // Begin iterators auto begin() { return coefficients.begin(); } auto begin() const { return coefficients.begin(); } @@ -645,27 +334,6 @@ inline void write(B& it, UnivariateMonomial cons write(it, univariate.coefficients); } -// template -// UnivariateMonomial operator+( -// const Fr& ff, const UnivariateMonomial& uv) -// { -// return uv + ff; -// } - -// template -// UnivariateMonomial operator-( -// const Fr& ff, const UnivariateMonomial& uv) -// { -// return -uv + ff; -// } - -// template -// UnivariateMonomial operator*( -// const Fr& ff, const UnivariateMonomial& uv) -// { -// return uv * ff; -// } - } // namespace bb namespace std { diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index 280fd659114..de59b012cd7 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -45,8 +45,9 @@ template class ProtogalaxyProverInternal { Univariate; // TODO: use the Monomial type directly // TODO: describe wtf is going on here - using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<2>; - using ShortUnivariates = typename Flavor::template ProverUnivariatesWithOptimisticSkipping<2, DeciderPKs::NUM - 1>; + // using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<2>; + using ShortUnivariates = typename Flavor::template ProverUnivariates<2>; + // typename Flavor::template ProverUnivariatesWithOptimisticSkipping<2, DeciderPKs::NUM - 1>; static constexpr size_t SHORT_LENGTH = 2; // using ShortUnivariatesNoOptimisticSkipping = @@ -307,7 +308,7 @@ template class ProtogalaxyProverInternal { BB_INLINE static void extend_univariates( std::conditional_t< std::same_as, - std::conditional_t, + ShortUnivariates, std::conditional_t>& extended_univariates, const DeciderPKs& keys, @@ -318,7 +319,10 @@ template class ProtogalaxyProverInternal { PROFILE_THIS_NAME("PG::extend_univariates"); static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; - auto incoming_univariates = keys.template row_to_univariates(row_idx); + // what is going on here... is that we want to, if we are using a flavor that allows for a short univariate + // representation, we + constexpr size_t _skip_count = std::same_as ? 0 : skip_count; + auto incoming_univariates = keys.template row_to_univariates(row_idx); for (auto [extended_univariate, incoming_univariate] : zip_view(extended_univariates.get_all(), incoming_univariates)) { if constexpr (!std::same_as) { @@ -328,85 +332,6 @@ template class ProtogalaxyProverInternal { } } - // template - // static void extend_univariates_2( - // std::conditional_t< - // std::same_as, - // std::conditional_t, - // std::conditional_t>& - // extended_univariates, - // const DeciderPKs& keys, - // const size_t row_idx) - // { - // // we get the incoming univariates from the deciver proving key... - // // we want to access, for each univariate, a parameter that defines the maximu mdegree - // PROFILE_THIS_NAME("PG::extend_univariates"); - // static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; - // auto incoming_univariates = keys.template row_to_univariates(row_idx); - // for (auto [extended_univariate, incoming_univariate] : - // zip_view(extended_univariates.get_all(), incoming_univariates)) { - // // if constexpr (!std::same_as) { - // incoming_univariate.template self_extend_from(); - // // } - // extended_univariate = std::move(incoming_univariate); - // } - // } - - // template - // BB_INLINE static void accumulate_relation_univariates_debug(const DeciderPKs& keys, - // size_t idx, - // TupleOfTuplesOfUnivariates_& univariate_accumulators, - // ExtendedUnivariates_& extended_univariates, - // const Parameters& relation_parameters, - // const FF& scaling_factor) - // { - // if (relation_idx == 0) { - // extend_univariates_2(extended_univariates, keys, idx); - // } - // if constexpr (std::same_as) { - // if (relation_idx == Flavor::NUM_RELATIONS - 1) { - // for (auto& foo : extended_univariates.get_all()) { - // foo.evaluations[2] = 1; - // } - // } - // } - // // if (relation_idx == 4) { - // // extend_univariates_2(extended_univariates, keys, idx); - // // } - // using Relation = std::tuple_element_t; - - // // Check if the relation is skippable to speed up accumulation - // if constexpr (!isSkippable) { - // // If not, accumulate normally - // Relation::accumulate(std::get(univariate_accumulators), - // extended_univariates, - // relation_parameters, - // scaling_factor); - // } else { - // // If so, only compute the contribution if the relation is active - // if (!Relation::skip(extended_univariates)) { - // Relation::accumulate(std::get(univariate_accumulators), - // extended_univariates, - // relation_parameters, - // scaling_factor); - // } - // } - - // // Repeat for the next relation. - // if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { - // accumulate_relation_univariates_debug( - // keys, idx, univariate_accumulators, extended_univariates, relation_parameters, scaling_factor); - // } - // } - /** * @brief Add the value of each relation over univariates to an appropriate accumulator * @@ -447,7 +372,6 @@ template class ProtogalaxyProverInternal { scaling_factor); } } - // extend_univariates_2<1>(extended_univariates, keys, idx); // Repeat for the next relation. if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { @@ -493,12 +417,11 @@ template class ProtogalaxyProverInternal { using ThreadAccumulators = TupleOfTuples; using ExtendedUnivatiatesType = - std::conditional_t< - std::same_as, - std::conditional_t, - std::conditional_t>; + std::conditional_t, + ShortUnivariates, + std::conditional_t>; // Construct univariate accumulator containers; one per thread std::vector thread_univariate_accumulators(num_threads); diff --git a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp index 82704a65748..24cdc71a8c6 100644 --- a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp @@ -58,15 +58,9 @@ template class EllipticRelationImpl { const FF& scaling_factor) { PROFILE_THIS_NAME("Elliptic::accumulate"); - // TODO(@zac - williamson #2608 when Pedersen refactor is completed, - // replace old addition relations with these ones and - // remove endomorphism coefficient in ecc add gate(not used)) using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - - // auto y_2 = View(in.w_4_shift); - // auto y_3 = View(in.w_o_shift); auto x_3_m = MonomialAccumulator(in.w_r_shift); auto y_1_m = MonomialAccumulator(in.w_o); auto y_2_m = MonomialAccumulator(in.w_4_shift); @@ -74,12 +68,6 @@ template class EllipticRelationImpl { auto x_1_m = MonomialAccumulator(in.w_r); auto x_2_m = MonomialAccumulator(in.w_l_shift); auto y_3_m = MonomialAccumulator(in.w_o_shift); - // auto x_3_m = MonomialAccumulator(in.w_r_shift); - // 20 muls - // auto q_sign = View(in.q_l); - // auto q_elliptic = View(in.q_elliptic); - // auto q_is_double = View(in.q_m); - auto q_elliptic_m = MonomialAccumulator(in.q_elliptic); auto q_is_double_m = MonomialAccumulator(in.q_m); auto q_sign_m = MonomialAccumulator(in.q_l); @@ -98,41 +86,19 @@ template class EllipticRelationImpl { Accumulator x3_sub_x1(x3_sub_x1_m); Accumulator x1_mul_3(x1_mul_3_m); Accumulator x3_plus_two_x1(x3_plus_two_x1_m); - // (3x1 already made in monomial basis) - // x3 - x1 = 2 adds + covnvert - // x3 + x1 + x1 = 2 adds + convert - // x3 + x2 + x1 = 2 adds + convert - // 3 converts and 6 adds = 4 * 3 + 6 = 18 adds - // vs 6 add = 6 * 5 = 30 F adds // Contribution (1) point addition, x-coordinate check // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 auto y2_sqr_m = y_2_m.sqr(); auto y1_sqr_m = y_1_m.sqr(); - // auto y1y2_m = y_1_m * y_2_m; auto y2_mul_q_sign_m = y_2_m * q_sign_m; auto x_add_identity = x3_plus_x2_plus_x1 * Accumulator(x2_sub_x1_m.sqr()) - Accumulator(y2_sqr_m + y1_sqr_m) + Accumulator(y2_mul_q_sign_m + y2_mul_q_sign_m) * Accumulator(y_1_m); - // q_elliptic - q_elliptic * q_double - // (q_elliptic - 1) * q_double auto q_elliptic_by_scaling_m = q_elliptic_m * scaling_factor; auto q_elliptic_q_double_scaling_m = (q_elliptic_by_scaling_m * q_is_double_m); Accumulator q_elliptic_q_double_scaling(q_elliptic_q_double_scaling_m); auto neg_q_elliptic_not_double_scaling = Accumulator(q_elliptic_q_double_scaling_m - q_elliptic_by_scaling_m); - - // qecc * qdouble * scaling - // qecc * (q_double - 1) * scaling - // auto qecc_qscaling = q_elliptic_m * scaling_factor; // degree 1 - // auto q_elliptic_q_double_scaling = qecc_qscaling * q_double_m; - // auto q_elliptic_not_double_scaling = q_elliptic_q_double_scaling - qecc_qscaling; - // auto q_elliptic_not_double_scaling_partial_m = (q_elliptic_m - FF(1)) * q_is_double_m; - // auto q_elliptic_not_double_scaling = Accumulator((q_elliptic_not_double_scaling_partial_m)*scaling_factor); - // auto q_elliptic_q_double_scaling = - // Accumulator((q_elliptic_not_double_scaling_partial_m + q_is_double_m) * scaling_factor); - // auto q_elliptic_by_scaling = q_elliptic * scaling_factor; - // auto q_elliptic_q_double_scaling = q_elliptic_by_scaling * q_is_double; - // auto q_elliptic_not_double_scaling = q_elliptic_by_scaling - q_elliptic_q_double_scaling; std::get<0>(accumulators) -= x_add_identity * neg_q_elliptic_not_double_scaling; // Contribution (2) point addition, x-coordinate check diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index d335be3d5b5..4eda1c91d20 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -144,14 +144,11 @@ template class LogDerivLookupRelationImpl { auto derived_table_entry_3 = (negative_column_3_step_size * w_3_shift) + w_3; auto table_index_entry = table_index * eta_three; + // (w_1 + \gamma q_2*w_1_shift) + η(w_2 + q_m*w_2_shift) + η₂(w_3 + q_c*w_3_shift) + η₃q_index. + // deg 2 or 3 auto result = Accumulator(derived_table_entry_2) * eta + Accumulator(derived_table_entry_3) * eta_two; result += Accumulator(derived_table_entry_1 + table_index_entry); return result; - // (w_1 + \gamma q_2*w_1_shift) + η(w_2 + q_m*w_2_shift) + η₂(w_3 + q_c*w_3_shift) + η₃q_index. - // deg 2 or 3 - // auto result = derived_table_entry_2 * eta + derived_table_entry_3 * eta_two + table_index * eta_three; - // result += derived_table_entry_1; - // return Accumulator(result); } /** @@ -242,14 +239,9 @@ template class LogDerivLookupRelationImpl { const auto read_counts_m = MonomialAccumulator(in.lookup_read_counts); // Degree 1 const auto read_selector_m = MonomialAccumulator(in.q_lookup); // Degree 1 - // const MonomialAccumulator row_has_write = MonomialAccumulator(in.lookup_read_tags); - // const MonomialAccumulator row_has_read = MonomialAccumulator(in.q_lookup); - // auto inverse_exists_m = -(row_has_write * row_has_read) + row_has_write + row_has_read; const auto inverse_exists = compute_inverse_exists(in); // Degree 2 const auto read_term = compute_read_term(in, params); // Degree 2 (3) const auto write_term = compute_write_term(in, params); // Degree 1 (2) - // const auto write_inverse = Accumulator(inverses_m) * read_term; // Degree 3 (4) - // const auto read_inverse = Accumulator(inverses_m) * write_term; // Degree 2 (3) // Establish the correctness of the polynomial of inverses I. Note: inverses is computed so that the value is 0 // if !inverse_exists. @@ -260,17 +252,10 @@ template class LogDerivLookupRelationImpl { // Establish validity of the read. Note: no scaling factor here since this constraint is 'linearly dependent, // i.e. enforced across the entire trace, not on a per-row basis. // Degrees: 1 2 (3) 1 3 (4) - - // rs * I * w - rc * I * r - - // (rs * w - rc * r) * I Accumulator tmp = Accumulator(read_selector_m) * write_term; tmp -= (Accumulator(read_counts_m) * read_term); tmp *= inverses; // degree 4(5) std::get<1>(accumulator) += tmp; // Deg 4 (5) - - // std::get<1>(accumulator) += - // Accumulator(read_selector_m) * read_inverse - Accumulator(read_counts_m) * write_inverse; // Deg 4 (5) } }; 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 a1e9ddd9644..f4129c363a3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -816,6 +816,7 @@ class MegaFlavor { return_data_read_counts = "RETURN_DATA_READ_COUNTS"; return_data_read_tags = "RETURN_DATA_READ_TAGS"; return_data_inverses = "RETURN_DATA_INVERSES"; + q_c = "Q_C"; q_l = "Q_L"; q_r = "Q_R"; From a3e47d95b877fb51d30f997658e985d5ae9d9a88 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 16:20:05 +0000 Subject: [PATCH 16/30] test inlines --- .../barretenberg/polynomials/univariate.hpp | 56 +++++++++---------- .../polynomials/univariate_monomial.hpp | 36 ++++++------ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 5555a917d46..186bd743a4d 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -50,7 +50,7 @@ template () const + BB_INLINE explicit operator UnivariateMonomial() const requires(LENGTH > 1) { static_assert(domain_end >= 2); @@ -63,7 +63,7 @@ template Univariate(UnivariateMonomial monomial) + template BB_INLINE Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; @@ -80,7 +80,7 @@ template Univariate(UnivariateMonomial monomial) + template BB_INLINE Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; // a1 + a2 @@ -123,7 +123,7 @@ template */ - Univariate convert() const noexcept + BB_INLINE Univariate convert() const noexcept { Univariate result; result.evaluations[0] = evaluations[0]; @@ -137,7 +137,7 @@ template in) + BB_INLINE explicit Univariate(UnivariateView in) : evaluations{} { for (size_t i = 0; i < in.evaluations.size(); ++i) { @@ -172,7 +172,7 @@ template & view) + BB_INLINE Univariate& operator+=(const UnivariateView& view) { evaluations[0] += view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -362,7 +362,7 @@ template & view) + BB_INLINE Univariate& operator-=(const UnivariateView& view) { evaluations[0] -= view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -371,7 +371,7 @@ template & view) + BB_INLINE Univariate& operator*=(const UnivariateView& view) { evaluations[0] *= view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -380,21 +380,21 @@ template & view) const + BB_INLINE Univariate operator+(const UnivariateView& view) const { Univariate res(*this); res += view; return res; } - Univariate operator-(const UnivariateView& view) const + BB_INLINE Univariate operator-(const UnivariateView& view) const { Univariate res(*this); res -= view; return res; } - Univariate operator*(const UnivariateView& view) const + BB_INLINE Univariate operator*(const UnivariateView& view) const { Univariate res(*this); res *= view; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index a7d465e8a94..058d24d546a 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -30,7 +30,7 @@ template class UnivariateMono UnivariateMonomial() = default; - UnivariateMonomial(const UnivariateMonomial& other) + BB_INLINE UnivariateMonomial(const UnivariateMonomial& other) requires(!has_a0_plus_a1) { coefficients[0] = other.coefficients[0]; @@ -47,7 +47,7 @@ template class UnivariateMono UnivariateMonomial& operator=(UnivariateMonomial&& other) noexcept = default; template - UnivariateMonomial(const UnivariateMonomial& other) + BB_INLINE UnivariateMonomial(const UnivariateMonomial& other) requires(domain_end > other_domain_end) { coefficients[0] = other.coefficients[0]; @@ -60,14 +60,14 @@ template class UnivariateMono size_t size() { return coefficients.size(); }; // Check if the UnivariateMonomial is identically zero - bool is_zero() const + BB_INLINE bool is_zero() const requires(LENGTH == 2) { return coefficients[0].is_zero() || coefficients[1].is_zero(); } // Check if the UnivariateMonomial is identically zero - bool is_zero() const + BB_INLINE bool is_zero() const requires(LENGTH == 3) { return coefficients[2].is_zero() || coefficients[0].is_zero() || coefficients[1].is_zero(); @@ -95,7 +95,7 @@ template class UnivariateMono return output; }; - static UnivariateMonomial zero() + BB_INLINE static UnivariateMonomial zero() { auto output = UnivariateMonomial(); for (size_t i = 0; i != LENGTH; ++i) { @@ -110,7 +110,7 @@ template class UnivariateMono bool operator==(const UnivariateMonomial& other) const = default; template - UnivariateMonomial& operator+=( + BB_INLINE UnivariateMonomial& operator+=( const UnivariateMonomial& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` @@ -125,7 +125,7 @@ template class UnivariateMono } template - UnivariateMonomial& operator-=( + BB_INLINE UnivariateMonomial& operator-=( const UnivariateMonomial& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` @@ -140,7 +140,7 @@ template class UnivariateMono } template - UnivariateMonomial operator*( + BB_INLINE UnivariateMonomial operator*( const UnivariateMonomial& other) const requires(LENGTH == 2) { @@ -181,7 +181,7 @@ template class UnivariateMono // return *this; // } template - UnivariateMonomial operator+( + BB_INLINE UnivariateMonomial operator+( const UnivariateMonomial& other) const { UnivariateMonomial res(*this); @@ -197,7 +197,7 @@ template class UnivariateMono } template - UnivariateMonomial operator-( + BB_INLINE UnivariateMonomial operator-( const UnivariateMonomial& other) const { UnivariateMonomial res(*this); @@ -212,7 +212,7 @@ template class UnivariateMono return res; } - UnivariateMonomial operator-() const + BB_INLINE UnivariateMonomial operator-() const { UnivariateMonomial res; res.coefficients[0] = -coefficients[0]; @@ -224,7 +224,7 @@ template class UnivariateMono return res; } - UnivariateMonomial sqr() const + BB_INLINE UnivariateMonomial sqr() const requires(LENGTH == 2) { UnivariateMonomial result; @@ -247,20 +247,20 @@ template class UnivariateMono } // Operations between Univariate and scalar - UnivariateMonomial& operator+=(const Fr& scalar) + BB_INLINE UnivariateMonomial& operator+=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] += scalar; return *this; } - UnivariateMonomial& operator-=(const Fr& scalar) + BB_INLINE UnivariateMonomial& operator-=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] -= scalar; return *this; } - UnivariateMonomial& operator*=(const Fr& scalar) + BB_INLINE UnivariateMonomial& operator*=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] *= scalar; @@ -271,21 +271,21 @@ template class UnivariateMono return *this; } - UnivariateMonomial operator+(const Fr& scalar) const + BB_INLINE UnivariateMonomial operator+(const Fr& scalar) const { UnivariateMonomial res(*this); res += scalar; return res; } - UnivariateMonomial operator-(const Fr& scalar) const + BB_INLINE UnivariateMonomial operator-(const Fr& scalar) const { UnivariateMonomial res(*this); res -= scalar; return res; } - UnivariateMonomial operator*(const Fr& scalar) const + BB_INLINE UnivariateMonomial operator*(const Fr& scalar) const { UnivariateMonomial res(*this); res.coefficients[0] *= scalar; From 911801fd1ec35eb74c5c31e19695fbb688945e28 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 16:46:31 +0000 Subject: [PATCH 17/30] add short univariate case to sumcheck prover --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 3 +++ .../protogalaxy_prover_internal.hpp | 18 +++++------------- .../stdlib_circuit_builders/mega_flavor.hpp | 2 ++ .../mega_recursive_flavor.hpp | 2 ++ .../stdlib_circuit_builders/ultra_flavor.hpp | 3 +++ .../ultra_recursive_flavor.hpp | 3 +++ .../barretenberg/sumcheck/sumcheck_round.hpp | 10 ++++++++-- .../translator_vm/translator_flavor.hpp | 4 ++++ .../vm/avm/recursion/recursive_flavor.hpp | 3 +++ 9 files changed, 33 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index a44e827d90e..7a0128fedbe 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -40,6 +40,9 @@ class ECCVMFlavor { using RelationSeparator = FF; using MSM = bb::eccvm::MSM; + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = false; + // Indicates that this flavor runs with ZK Sumcheck. static constexpr bool HasZK = true; static constexpr size_t NUM_WIRES = 85; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index de59b012cd7..c09f0b6dd14 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -43,19 +43,11 @@ template class ProtogalaxyProverInternal { // the folded relation batching challenge. using ExtendedUnivariateWithRandomization = Univariate; - // TODO: use the Monomial type directly + // TODO: describe wtf is going on here - // using ShortUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates<2>; using ShortUnivariates = typename Flavor::template ProverUnivariates<2>; - // typename Flavor::template ProverUnivariatesWithOptimisticSkipping<2, DeciderPKs::NUM - 1>; static constexpr size_t SHORT_LENGTH = 2; - // using ShortUnivariatesNoOptimisticSkipping = - // typename Flavor::template ProverUnivariates; - // using ShortUnivariates = - // typename Flavor::template ProverUnivariatesWithOptimisticSkipping; - // static constexpr size_t SHORT_LENGTH = ExtendedUnivariate::LENGTH; using ExtendedUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates; using ExtendedUnivariates = @@ -307,7 +299,7 @@ template class ProtogalaxyProverInternal { template BB_INLINE static void extend_univariates( std::conditional_t< - std::same_as, + Flavor::USE_SHORT_MONOMIALS, ShortUnivariates, std::conditional_t>& extended_univariates, @@ -318,10 +310,10 @@ template class ProtogalaxyProverInternal { // we want to access, for each univariate, a parameter that defines the maximu mdegree PROFILE_THIS_NAME("PG::extend_univariates"); - static constexpr size_t len = std::same_as ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; + static constexpr size_t len = Flavor::USE_SHORT_MONOMIALS ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; // what is going on here... is that we want to, if we are using a flavor that allows for a short univariate // representation, we - constexpr size_t _skip_count = std::same_as ? 0 : skip_count; + constexpr size_t _skip_count = Flavor::USE_SHORT_MONOMIALS ? 0 : skip_count; auto incoming_univariates = keys.template row_to_univariates(row_idx); for (auto [extended_univariate, incoming_univariate] : zip_view(extended_univariates.get_all(), incoming_univariates)) { @@ -417,7 +409,7 @@ template class ProtogalaxyProverInternal { using ThreadAccumulators = TupleOfTuples; using ExtendedUnivatiatesType = - std::conditional_t, + std::conditional_t; using TraceBlocks = MegaExecutionTraceBlocks; + // indicates when evaluating sumcheck, edges can be left as degree-1 monomials + static constexpr bool USE_SHORT_MONOMIALS = true; // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = false; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp index 9fc58872fab..39db9c183b0 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp @@ -40,6 +40,8 @@ template class MegaRecursiveFlavor_ { using NativeFlavor = MegaFlavor; using NativeVerificationKey = NativeFlavor::VerificationKey; + // indicates when evaluating sumcheck, edges can be left as degree-1 monomials + static constexpr bool USE_SHORT_MONOMIALS = true; // Note(luke): Eventually this may not be needed at all using VerifierCommitmentKey = bb::VerifierCommitmentKey; // Indicates that this flavor runs with non-ZK Sumcheck. 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 6ff45fb338d..666dfbc38b5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -36,6 +36,9 @@ class UltraFlavor { using CommitmentKey = bb::CommitmentKey; using VerifierCommitmentKey = bb::VerifierCommitmentKey; + // indicates when evaluating sumcheck, edges can be left as degree-1 monomials + static constexpr bool USE_SHORT_MONOMIALS = true; + // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = false; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp index 9b28f0de7d9..31bdec750e0 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp @@ -54,6 +54,9 @@ template class UltraRecursiveFlavor_ { using NativeFlavor = UltraFlavor; using NativeVerificationKey = NativeFlavor::VerificationKey; + // indicates when evaluating sumcheck, edges can be left as degree-1 monomials + static constexpr bool USE_SHORT_MONOMIALS = true; + // Note(luke): Eventually this may not be needed at all using VerifierCommitmentKey = bb::VerifierCommitmentKey; // Indicates that this flavor runs with non-ZK Sumcheck. diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 758797b8bcc..4a05949e51e 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -39,7 +39,9 @@ template class SumcheckProverRound { public: using FF = typename Flavor::FF; - using ExtendedEdges = typename Flavor::ExtendedEdges; + using ExtendedEdges = std::conditional_t, + typename Flavor::ExtendedEdges>; /** * @brief In Round \f$i = 0,\ldots, d-1\f$, equals \f$2^{d-i}\f$. */ @@ -108,7 +110,11 @@ template class SumcheckProverRound { { for (auto [extended_edge, multivariate] : zip_view(extended_edges.get_all(), multivariates.get_all())) { bb::Univariate edge({ multivariate[edge_idx], multivariate[edge_idx + 1] }); - extended_edge = edge.template extend_to(); + if constexpr (Flavor::USE_SHORT_MONOMIALS) { + extended_edge = edge; + } else { + extended_edge = edge.template extend_to(); + } } } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 7167437d4e3..18bb9b63818 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -35,6 +35,10 @@ class TranslatorFlavor { using BF = Curve::BaseField; using Polynomial = bb::Polynomial; using RelationSeparator = FF; + + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = false; + // Indicates that this flavor runs with ZK Sumcheck. static constexpr bool HasZK = true; static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp index d20a2496c0d..dac1a7515a1 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp @@ -25,6 +25,9 @@ template class AvmRecursiveFlavor_ { using Relations = AvmFlavor::Relations_; + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = false; + static constexpr size_t NUM_WIRES = NativeFlavor::NUM_WIRES; static constexpr size_t NUM_ALL_ENTITIES = NativeFlavor::NUM_ALL_ENTITIES; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = NativeFlavor::NUM_PRECOMPUTED_ENTITIES; From 2a0b185c25456efc4227cfedeb5e24fd3b2c67df Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 17:01:39 +0000 Subject: [PATCH 18/30] move small computations within thread block --- .../protogalaxy_prover_internal.hpp | 18 +++++++----------- .../cpp/src/barretenberg/sumcheck/sumcheck.hpp | 3 ++- .../barretenberg/sumcheck/sumcheck_round.hpp | 16 ++++++---------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index c09f0b6dd14..2b0c7326f23 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -417,30 +417,26 @@ template class ProtogalaxyProverInternal { // Construct univariate accumulator containers; one per thread std::vector thread_univariate_accumulators(num_threads); - for (auto& accum : thread_univariate_accumulators) { - // just normal relation lengths - RelationUtils::zero_univariates(accum); - } - - // Construct extended univariates containers; one per thread - std::vector extended_univariates; - extended_univariates.resize(num_threads); // Distribute the execution trace rows across threads so that each handles an equal number of active rows trace_usage_tracker.construct_thread_ranges(num_threads, common_polynomial_size); // Accumulate the contribution from each sub-relation parallel_for(num_threads, [&](size_t thread_idx) { + // Initialize the thread accumulator to 0 + RelationUtils::zero_univariates(thread_univariate_accumulators[thread_idx]); + // Construct extended univariates containers; one per thread + ExtendedUnivatiatesType extended_univariate; + const size_t start = trace_usage_tracker.thread_ranges[thread_idx].first; const size_t end = trace_usage_tracker.thread_ranges[thread_idx].second; - for (size_t idx = start; idx < end; idx++) { if (trace_usage_tracker.check_is_active(idx)) { // Instantiate univariates, possibly with skipping toto ignore computation in those indices (they // are still available for skipping relations, but all derived univariate will ignore those // evaluations) No need to initialise extended_univariates to 0, as it's assigned to. constexpr size_t skip_count = skip_zero_computations ? DeciderPKs::NUM - 1 : 0; - extend_univariates(extended_univariates[thread_idx], keys, idx); + extend_univariates(extended_univariate, keys, idx); const FF pow_challenge = gate_separators[idx]; @@ -448,7 +444,7 @@ template class ProtogalaxyProverInternal { // this function have already been folded. Moreover, linear-dependent relations that act over the // entire execution trace rather than on rows, will not be multiplied by the pow challenge. accumulate_relation_univariates(thread_univariate_accumulators[thread_idx], - extended_univariates[thread_idx], + extended_univariate, relation_parameters, // these parameters have already been folded pow_challenge); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 887730da472..220ec0838df 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -115,7 +115,8 @@ transcript. These operations are taken care of by \ref bb::BaseTranscript "Trans The Sumcheck output is specified by \ref bb::SumcheckOutput< Flavor >. */ template class SumcheckProver { - + // PartiallyEvaluatedMultivariates OR ProverPolynomials + // both inherit from AllEntities public: using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 4a05949e51e..ea8c7ec3713 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -161,28 +161,24 @@ template class SumcheckProverRound { // Construct univariate accumulator containers; one per thread std::vector thread_univariate_accumulators(num_threads); - for (auto& accum : thread_univariate_accumulators) { - Utils::zero_univariates(accum); - } - - // Construct extended edge containers; one per thread - std::vector extended_edges; - extended_edges.resize(num_threads); // Accumulate the contribution from each sub-relation accross each edge of the hyper-cube parallel_for(num_threads, [&](size_t thread_idx) { + // Initialize the thread accumulator to 0 + Utils::zero_univariates(thread_univariate_accumulators[thread_idx]); + // Construct extended univariates containers; one per thread + ExtendedEdges extended_edges; size_t start = thread_idx * iterations_per_thread; size_t end = (thread_idx + 1) * iterations_per_thread; - for (size_t edge_idx = start; edge_idx < end; edge_idx += 2) { - extend_edges(extended_edges[thread_idx], polynomials, edge_idx); + extend_edges(extended_edges, polynomials, edge_idx); // Compute the \f$ \ell \f$-th edge's univariate contribution, // scale it by the corresponding \f$ pow_{\beta} \f$ contribution and add it to the accumulators for \f$ // \tilde{S}^i(X_i) \f$. If \f$ \ell \f$'s binary representation is given by \f$ (\ell_{i+1},\ldots, // \ell_{d-1})\f$, the \f$ pow_{\beta}\f$-contribution is \f$\beta_{i+1}^{\ell_{i+1}} \cdot \ldots \cdot // \beta_{d-1}^{\ell_{d-1}}\f$. accumulate_relation_univariates(thread_univariate_accumulators[thread_idx], - extended_edges[thread_idx], + extended_edges, relation_parameters, gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); } From da6b1a60d36d914a0074f3bb917c39224c2a43ad Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 17:16:31 +0000 Subject: [PATCH 19/30] tweaks --- .../barretenberg/polynomials/univariate.hpp | 56 +++++++++---------- .../polynomials/univariate_monomial.hpp | 36 ++++++------ .../protogalaxy_prover_internal.hpp | 18 +++--- .../barretenberg/ultra_honk/decider_keys.hpp | 16 ++++++ 4 files changed, 71 insertions(+), 55 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 186bd743a4d..5555a917d46 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -50,7 +50,7 @@ template () const + explicit operator UnivariateMonomial() const requires(LENGTH > 1) { static_assert(domain_end >= 2); @@ -63,7 +63,7 @@ template BB_INLINE Univariate(UnivariateMonomial monomial) + template Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; @@ -80,7 +80,7 @@ template BB_INLINE Univariate(UnivariateMonomial monomial) + template Univariate(UnivariateMonomial monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; // a1 + a2 @@ -123,7 +123,7 @@ template */ - BB_INLINE Univariate convert() const noexcept + Univariate convert() const noexcept { Univariate result; result.evaluations[0] = evaluations[0]; @@ -137,7 +137,7 @@ template in) + explicit Univariate(UnivariateView in) : evaluations{} { for (size_t i = 0; i < in.evaluations.size(); ++i) { @@ -172,7 +172,7 @@ template & view) + Univariate& operator+=(const UnivariateView& view) { evaluations[0] += view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -362,7 +362,7 @@ template & view) + Univariate& operator-=(const UnivariateView& view) { evaluations[0] -= view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -371,7 +371,7 @@ template & view) + Univariate& operator*=(const UnivariateView& view) { evaluations[0] *= view.evaluations[0]; for (size_t i = skip_count + 1; i < LENGTH; ++i) { @@ -380,21 +380,21 @@ template & view) const + Univariate operator+(const UnivariateView& view) const { Univariate res(*this); res += view; return res; } - BB_INLINE Univariate operator-(const UnivariateView& view) const + Univariate operator-(const UnivariateView& view) const { Univariate res(*this); res -= view; return res; } - BB_INLINE Univariate operator*(const UnivariateView& view) const + Univariate operator*(const UnivariateView& view) const { Univariate res(*this); res *= view; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index 058d24d546a..a7d465e8a94 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -30,7 +30,7 @@ template class UnivariateMono UnivariateMonomial() = default; - BB_INLINE UnivariateMonomial(const UnivariateMonomial& other) + UnivariateMonomial(const UnivariateMonomial& other) requires(!has_a0_plus_a1) { coefficients[0] = other.coefficients[0]; @@ -47,7 +47,7 @@ template class UnivariateMono UnivariateMonomial& operator=(UnivariateMonomial&& other) noexcept = default; template - BB_INLINE UnivariateMonomial(const UnivariateMonomial& other) + UnivariateMonomial(const UnivariateMonomial& other) requires(domain_end > other_domain_end) { coefficients[0] = other.coefficients[0]; @@ -60,14 +60,14 @@ template class UnivariateMono size_t size() { return coefficients.size(); }; // Check if the UnivariateMonomial is identically zero - BB_INLINE bool is_zero() const + bool is_zero() const requires(LENGTH == 2) { return coefficients[0].is_zero() || coefficients[1].is_zero(); } // Check if the UnivariateMonomial is identically zero - BB_INLINE bool is_zero() const + bool is_zero() const requires(LENGTH == 3) { return coefficients[2].is_zero() || coefficients[0].is_zero() || coefficients[1].is_zero(); @@ -95,7 +95,7 @@ template class UnivariateMono return output; }; - BB_INLINE static UnivariateMonomial zero() + static UnivariateMonomial zero() { auto output = UnivariateMonomial(); for (size_t i = 0; i != LENGTH; ++i) { @@ -110,7 +110,7 @@ template class UnivariateMono bool operator==(const UnivariateMonomial& other) const = default; template - BB_INLINE UnivariateMonomial& operator+=( + UnivariateMonomial& operator+=( const UnivariateMonomial& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` @@ -125,7 +125,7 @@ template class UnivariateMono } template - BB_INLINE UnivariateMonomial& operator-=( + UnivariateMonomial& operator-=( const UnivariateMonomial& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` @@ -140,7 +140,7 @@ template class UnivariateMono } template - BB_INLINE UnivariateMonomial operator*( + UnivariateMonomial operator*( const UnivariateMonomial& other) const requires(LENGTH == 2) { @@ -181,7 +181,7 @@ template class UnivariateMono // return *this; // } template - BB_INLINE UnivariateMonomial operator+( + UnivariateMonomial operator+( const UnivariateMonomial& other) const { UnivariateMonomial res(*this); @@ -197,7 +197,7 @@ template class UnivariateMono } template - BB_INLINE UnivariateMonomial operator-( + UnivariateMonomial operator-( const UnivariateMonomial& other) const { UnivariateMonomial res(*this); @@ -212,7 +212,7 @@ template class UnivariateMono return res; } - BB_INLINE UnivariateMonomial operator-() const + UnivariateMonomial operator-() const { UnivariateMonomial res; res.coefficients[0] = -coefficients[0]; @@ -224,7 +224,7 @@ template class UnivariateMono return res; } - BB_INLINE UnivariateMonomial sqr() const + UnivariateMonomial sqr() const requires(LENGTH == 2) { UnivariateMonomial result; @@ -247,20 +247,20 @@ template class UnivariateMono } // Operations between Univariate and scalar - BB_INLINE UnivariateMonomial& operator+=(const Fr& scalar) + UnivariateMonomial& operator+=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] += scalar; return *this; } - BB_INLINE UnivariateMonomial& operator-=(const Fr& scalar) + UnivariateMonomial& operator-=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] -= scalar; return *this; } - BB_INLINE UnivariateMonomial& operator*=(const Fr& scalar) + UnivariateMonomial& operator*=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] *= scalar; @@ -271,21 +271,21 @@ template class UnivariateMono return *this; } - BB_INLINE UnivariateMonomial operator+(const Fr& scalar) const + UnivariateMonomial operator+(const Fr& scalar) const { UnivariateMonomial res(*this); res += scalar; return res; } - BB_INLINE UnivariateMonomial operator-(const Fr& scalar) const + UnivariateMonomial operator-(const Fr& scalar) const { UnivariateMonomial res(*this); res -= scalar; return res; } - BB_INLINE UnivariateMonomial operator*(const Fr& scalar) const + UnivariateMonomial operator*(const Fr& scalar) const { UnivariateMonomial res(*this); res.coefficients[0] *= scalar; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index 2b0c7326f23..bb1aee04480 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -310,17 +310,17 @@ template class ProtogalaxyProverInternal { // we want to access, for each univariate, a parameter that defines the maximu mdegree PROFILE_THIS_NAME("PG::extend_univariates"); - static constexpr size_t len = Flavor::USE_SHORT_MONOMIALS ? SHORT_LENGTH : ExtendedUnivariate::LENGTH; - // what is going on here... is that we want to, if we are using a flavor that allows for a short univariate - // representation, we - constexpr size_t _skip_count = Flavor::USE_SHORT_MONOMIALS ? 0 : skip_count; - auto incoming_univariates = keys.template row_to_univariates(row_idx); - for (auto [extended_univariate, incoming_univariate] : - zip_view(extended_univariates.get_all(), incoming_univariates)) { - if constexpr (!std::same_as) { + if constexpr (Flavor::USE_SHORT_MONOMIALS) { + extended_univariates = std::move(keys.row_to_short_univariates(row_idx)); + } else { + constexpr size_t _skip_count = Flavor::USE_SHORT_MONOMIALS ? 0 : skip_count; + auto incoming_univariates = + keys.template row_to_univariates(row_idx); + for (auto [extended_univariate, incoming_univariate] : + zip_view(extended_univariates.get_all(), incoming_univariates)) { incoming_univariate.template self_extend_from(); + extended_univariate = std::move(incoming_univariate); } - extended_univariate = std::move(incoming_univariate); } } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 770cede8297..c7bb902b711 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -69,6 +69,22 @@ template struct DeciderProvingKeys_ { return results; } + typename Flavor::template ProverUnivariates<2> row_to_short_univariates(size_t row_idx) const + { + auto prover_polynomials_views = get_polynomials_views(); + typename Flavor::template ProverUnivariates<2> results; + // Set the size corresponding to the number of rows in the execution trace + // Iterate over the prover polynomials' views corresponding to each proving key + for (size_t dpk_idx = 0; auto& get_all : prover_polynomials_views) { + // Iterate over all columns in the trace execution of an proving key and extract their value at row_idx. + for (auto [result, poly_ptr] : zip_view(results.get_all(), get_all)) { + result.evaluations[dpk_idx] = poly_ptr[row_idx]; + } + dpk_idx++; + } + return results; + } + private: // Returns a vector containing pointer views to the prover polynomials corresponding to each proving key. auto get_polynomials_views() const From 81315c76a2300f4e343889cba21e29bf58b5dda7 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 4 Dec 2024 17:27:13 +0000 Subject: [PATCH 20/30] tweaks --- .../protogalaxy/protogalaxy_prover_internal.hpp | 9 +++------ .../src/barretenberg/relations/permutation_relation.hpp | 1 - .../relations/poseidon2_internal_relation.hpp | 2 -- .../src/barretenberg/relations/relation_parameters.hpp | 7 ------- .../cpp/src/barretenberg/vm/avm/generated/flavor.hpp | 3 +++ 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index bb1aee04480..7c7bcd77ffb 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -46,7 +46,6 @@ template class ProtogalaxyProverInternal { // TODO: describe wtf is going on here using ShortUnivariates = typename Flavor::template ProverUnivariates<2>; - static constexpr size_t SHORT_LENGTH = 2; using ExtendedUnivariatesNoOptimisticSkipping = typename Flavor::template ProverUnivariates; @@ -306,8 +305,6 @@ template class ProtogalaxyProverInternal { const DeciderPKs& keys, const size_t row_idx) { - // we get the incoming univariates from the deciver proving key... - // we want to access, for each univariate, a parameter that defines the maximu mdegree PROFILE_THIS_NAME("PG::extend_univariates"); if constexpr (Flavor::USE_SHORT_MONOMIALS) { @@ -426,7 +423,7 @@ template class ProtogalaxyProverInternal { // Initialize the thread accumulator to 0 RelationUtils::zero_univariates(thread_univariate_accumulators[thread_idx]); // Construct extended univariates containers; one per thread - ExtendedUnivatiatesType extended_univariate; + ExtendedUnivatiatesType extended_univariates; const size_t start = trace_usage_tracker.thread_ranges[thread_idx].first; const size_t end = trace_usage_tracker.thread_ranges[thread_idx].second; @@ -436,7 +433,7 @@ template class ProtogalaxyProverInternal { // are still available for skipping relations, but all derived univariate will ignore those // evaluations) No need to initialise extended_univariates to 0, as it's assigned to. constexpr size_t skip_count = skip_zero_computations ? DeciderPKs::NUM - 1 : 0; - extend_univariates(extended_univariate, keys, idx); + extend_univariates(extended_univariates, keys, idx); const FF pow_challenge = gate_separators[idx]; @@ -444,7 +441,7 @@ template class ProtogalaxyProverInternal { // this function have already been folded. Moreover, linear-dependent relations that act over the // entire execution trace rather than on rows, will not be multiplied by the pow challenge. accumulate_relation_univariates(thread_univariate_accumulators[thread_idx], - extended_univariate, + extended_univariates, relation_parameters, // these parameters have already been folded pow_challenge); } diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index af44129c6cf..a6314a82cbd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -1,6 +1,5 @@ #pragma once #include "barretenberg/relations/relation_types.hpp" -#include namespace bb { /** * @brief Ultra Permutation Relation diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp index e392975ffd6..c737415ba71 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp @@ -72,8 +72,6 @@ template class Poseidon2InternalRelationImpl { auto q_l_m = MonomialAccumulator(in.q_l); auto q_poseidon2_internal_m = MonomialAccumulator(in.q_poseidon2_internal); - // old 9 muls, 14 adds - // new: // add round constants auto s1 = Accumulator(w_l_m + q_l_m); diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp index 951e5a94769..10728d78256 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp @@ -26,13 +26,6 @@ template struct RelationParameters { T lookup_grand_product_delta{ 0 }; // Lookup T beta_sqr{ 0 }; T beta_cube{ 0 }; - - // we could add useful temporaries into here although it's a bit bruteforce - // w_1 + gamma - // w_2 + gamma - // w_3 + gamma - // w_4 + gamma - // eccvm_set_permutation_delta is used in the set membership gadget in eccvm/ecc_set_relation.hpp // We can remove this by modifying the relation, but increases complexity T eccvm_set_permutation_delta = T(0); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index f82d78abe6e..f6d95ddd047 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -121,6 +121,9 @@ class AvmFlavor { using VerifierCommitmentKey = AvmFlavorSettings::VerifierCommitmentKey; using RelationSeparator = AvmFlavorSettings::RelationSeparator; + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = false; + // This flavor would not be used with ZK Sumcheck static constexpr bool HasZK = false; From 160e8424cd34008711d7e42ab4a6c02c85da4a43 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 5 Dec 2024 12:01:58 +0000 Subject: [PATCH 21/30] updated flavor.hpp.hbs to generate USE_SHORT_MONOMIALS --- bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs index a31cdd55fdd..a6d5335c692 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs @@ -56,6 +56,9 @@ class {{name}}Flavor { using VerifierCommitmentKey = {{name}}FlavorSettings::VerifierCommitmentKey; using RelationSeparator = {{name}}FlavorSettings::RelationSeparator; + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = false; + // This flavor would not be used with ZK Sumcheck static constexpr bool HasZK = false; From e8d3508fe619ad709af08835a2630f23e3c0f16e Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 5 Dec 2024 12:02:38 +0000 Subject: [PATCH 22/30] recursive_flavor derives USE_SHORT_MONOMIALS --- .../cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp index dac1a7515a1..43b7f0991e0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp @@ -26,7 +26,7 @@ template class AvmRecursiveFlavor_ { using Relations = AvmFlavor::Relations_; // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH - static constexpr bool USE_SHORT_MONOMIALS = false; + static constexpr bool USE_SHORT_MONOMIALS = NativeFlavor::USE_SHORT_MONOMIALS; static constexpr size_t NUM_WIRES = NativeFlavor::NUM_WIRES; static constexpr size_t NUM_ALL_ENTITIES = NativeFlavor::NUM_ALL_ENTITIES; From 4b9af43182bebd0c3e81691433097f3b9a043ad1 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 5 Dec 2024 12:16:52 +0000 Subject: [PATCH 23/30] compiler fixes --- .../relations/auxiliary_relation.hpp | 36 ++++++++++--------- .../relations/logderiv_lookup_relation.hpp | 6 ++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index 162566d0c24..1bce9ca64b6 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -164,21 +164,21 @@ template class AuxiliaryRelationImpl { non_native_field_gate_2_m *= LIMB_SIZE; non_native_field_gate_2_m -= w_4_shift_m; non_native_field_gate_2_m += limb_subproduct; - auto non_native_field_gate_2 = Accumulator(non_native_field_gate_2_m) * Accumulator(q_4_m); + auto non_native_field_gate_2 = ShortAccumulator(non_native_field_gate_2_m) * ShortAccumulator(q_4_m); limb_subproduct *= LIMB_SIZE; limb_subproduct += (w_1_shift_m * w_2_shift_m); auto non_native_field_gate_1_m = limb_subproduct; non_native_field_gate_1_m -= (w_3_m + w_4_m); - auto non_native_field_gate_1 = Accumulator(non_native_field_gate_1_m) * Accumulator(q_3_m); + auto non_native_field_gate_1 = ShortAccumulator(non_native_field_gate_1_m) * ShortAccumulator(q_3_m); auto non_native_field_gate_3_m = limb_subproduct; non_native_field_gate_3_m += w_4_m; non_native_field_gate_3_m -= (w_3_shift_m + w_4_shift_m); - auto non_native_field_gate_3 = Accumulator(non_native_field_gate_3_m) * Accumulator(q_m_m); + auto non_native_field_gate_3 = ShortAccumulator(non_native_field_gate_3_m) * ShortAccumulator(q_m_m); auto non_native_field_identity = non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3; - non_native_field_identity *= Accumulator(q_2_m); + non_native_field_identity *= ShortAccumulator(q_2_m); // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * qm // deg 2 @@ -207,7 +207,7 @@ template class AuxiliaryRelationImpl { auto limb_accumulator_2_m_full = limb_accumulator_2_m * q_m_m; auto limb_accumulator_identity_m = limb_accumulator_1_m_full + limb_accumulator_2_m_full; - Accumulator limb_accumulator_identity(limb_accumulator_identity_m); + ShortAccumulator limb_accumulator_identity(limb_accumulator_identity_m); limb_accumulator_identity *= q_3_m; // deg 3 /** @@ -256,7 +256,7 @@ template class AuxiliaryRelationImpl { memory_record_check_m += q_c_m; auto partial_record_check_m = memory_record_check_m; // used in RAM consistency check; deg 1 or 2 memory_record_check_m = memory_record_check_m - w_4_m; - auto memory_record_check = Accumulator(memory_record_check_m); + auto memory_record_check = ShortAccumulator(memory_record_check_m); /** * ROM Consistency Check * Partial degree: 1 @@ -277,22 +277,21 @@ template class AuxiliaryRelationImpl { auto record_delta_m = w_4_shift_m - w_4_m; auto index_is_monotonically_increasing_m = neg_index_delta_m.sqr() + neg_index_delta_m; // deg 2 - Accumulator index_is_monotonically_increasing(index_is_monotonically_increasing_m); + ShortAccumulator index_is_monotonically_increasing(index_is_monotonically_increasing_m); auto adjacent_values_match_if_adjacent_indices_match = ShortAccumulator(index_delta_is_zero_m * record_delta_m); // deg 2 auto q_aux_by_scaling_m = q_aux_m * scaling_factor; - auto q_aux_by_scaling = Accumulator(q_aux_by_scaling_m); + auto q_aux_by_scaling = ShortAccumulator(q_aux_by_scaling_m); auto q_one_by_two_m = q_1_m * q_2_m; auto q_one_by_two = ShortAccumulator(q_one_by_two_m); auto q_one_by_two_by_aux_by_scaling = q_one_by_two * q_aux_by_scaling; std::get<1>(accumulators) += - ShortView(adjacent_values_match_if_adjacent_indices_match * q_one_by_two_by_aux_by_scaling); // deg 5 - std::get<2>(accumulators) += - ShortView(index_is_monotonically_increasing) * q_one_by_two_by_aux_by_scaling; // deg 5 - auto ROM_consistency_check_identity = memory_record_check * q_one_by_two; // deg 3 or 4 + (adjacent_values_match_if_adjacent_indices_match * q_one_by_two_by_aux_by_scaling); // deg 5 + std::get<2>(accumulators) += (index_is_monotonically_increasing)*q_one_by_two_by_aux_by_scaling; // deg 5 + auto ROM_consistency_check_identity = memory_record_check * q_one_by_two; // deg 3 or 4 /** * RAM Consistency Check @@ -324,6 +323,7 @@ template class AuxiliaryRelationImpl { neg_next_gate_access_type_m += w_1_shift_m * eta_m; neg_next_gate_access_type_m = neg_next_gate_access_type_m - w_4_shift_m; Accumulator neg_next_gate_access_type(neg_next_gate_access_type_m); + ShortView neg_next_gate_access_type_short(neg_next_gate_access_type); auto value_delta_m = w_3_shift_m - w_3_m; auto adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = Accumulator(index_delta_is_zero_m * value_delta_m) * @@ -334,18 +334,20 @@ template class AuxiliaryRelationImpl { // do with an arithmetic gate because of the `eta` factors. We need to check that the *next* gate's access // type is correct, to cover this edge case // deg 2 or 4 - auto next_gate_access_type_is_boolean = neg_next_gate_access_type.sqr() + neg_next_gate_access_type; + auto next_gate_access_type_is_boolean = neg_next_gate_access_type_short.sqr() + neg_next_gate_access_type_short; auto q_arith_by_aux_and_scaling = Accumulator(q_arith_m * q_aux_by_scaling_m); + ShortView q_arith_by_aux_and_scaling_short(q_arith_by_aux_and_scaling); // Putting it all together... std::get<3>(accumulators) += adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * q_arith_by_aux_and_scaling; // deg 5 or 6 - std::get<4>(accumulators) += ShortView(index_is_monotonically_increasing * q_arith_by_aux_and_scaling); // deg 4 + std::get<4>(accumulators) += + ShortView(index_is_monotonically_increasing * q_arith_by_aux_and_scaling_short); // deg 4 std::get<5>(accumulators) += - ShortView(next_gate_access_type_is_boolean * q_arith_by_aux_and_scaling); // deg 4 or 6 + ShortView(next_gate_access_type_is_boolean * q_arith_by_aux_and_scaling_short); // deg 4 or 6 - auto RAM_consistency_check_identity = access_check * q_arith_by_aux_and_scaling; // deg 3 or 5 + auto RAM_consistency_check_identity = access_check * q_arith_by_aux_and_scaling_short; // deg 3 or 5 /** * RAM Timestamp Consistency Check @@ -360,7 +362,7 @@ template class AuxiliaryRelationImpl { */ auto timestamp_delta_m = w_2_shift_m - w_2_m; auto RAM_timestamp_check_identity_m = index_delta_is_zero_m * timestamp_delta_m - w_3_m; // deg 3 - Accumulator RAM_timestamp_check_identity(RAM_timestamp_check_identity_m); + ShortAccumulator RAM_timestamp_check_identity(RAM_timestamp_check_identity_m); /** * The complete RAM/ROM memory identity * Partial degree: diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index 4eda1c91d20..2f39f6460eb 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -228,6 +228,8 @@ template class LogDerivLookupRelationImpl { // whereas in ZK Flavors, the accumulator corresponding log derivative lookup argument sub-relation is the // longest using ShortAccumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; + using ShortView = typename ShortAccumulator::View; + using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; @@ -246,8 +248,8 @@ template class LogDerivLookupRelationImpl { // Establish the correctness of the polynomial of inverses I. Note: inverses is computed so that the value is 0 // if !inverse_exists. // Degrees: 2 (3) 1 (2) 1 1 - std::get<0>(accumulator) += - ShortAccumulator((read_term * write_term * inverses - inverse_exists) * scaling_factor); // Deg 4 (6) + const Accumulator logderiv_first_term = (read_term * write_term * inverses - inverse_exists) * scaling_factor; + std::get<0>(accumulator) += ShortView(logderiv_first_term); // Deg 4 (6) // Establish validity of the read. Note: no scaling factor here since this constraint is 'linearly dependent, // i.e. enforced across the entire trace, not on a per-row basis. From 21b8d223fab1b72e6e8c1f2a0d611bbedf5517c9 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 10 Dec 2024 13:55:43 +0000 Subject: [PATCH 24/30] reduced tparams in ProtogalaxyProverInternal Moved methods in ProtogalaxyProverInternal that did not optimistically skip into a separate class `PGInternalTest` in `combiner.test.cpp` --- .../protogalaxy/combiner.test.cpp | 190 ++++++++++++++++-- .../protogalaxy/protogalaxy_prover.hpp | 2 - .../protogalaxy_prover_internal.hpp | 96 ++++----- 3 files changed, 213 insertions(+), 75 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp index c280cf241f1..0189fd8e7a3 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp @@ -10,15 +10,173 @@ using namespace bb; using Flavor = MegaFlavor; using Polynomial = typename Flavor::Polynomial; using FF = typename Flavor::FF; +constexpr size_t NUM_KEYS = 2; + +/** + * @brief Extend the ProtogalaxyProverInternal class to compute the combiner *without* optimistically skipping + * @details "optimistic skipping" is the act of not computing the flavor's relation monomials at evaluation points where + * an honest Prover would produce an evaluation result of `0` For example, when folding 1 instance `w0` with 1 + * accumulator `w`, ProtoGalaxy uses a witness polynomial w(X) = w.L0(X) + w0.L1(X), where L0, L1 are Lagrange + * polynomials. At X=1, w(X) = w0 . The full Protogalaxy relation in this case should evaluate to `0`. so we can skip + * its computation at X=1. The PGInternalTest class adds methods where we do *not* perform this optimistic skipping, so + * we can test whether the optimistic skipping algorithm produces the correct result + * + */ +class PGInternalTest : public ProtogalaxyProverInternal> { + public: + using ExtendedUnivariatesNoOptimisticSkipping = + typename Flavor::template ProverUnivariates; + + using UnivariateRelationParametersNoOptimisticSkipping = + bb::RelationParameters>; + using ExtendedUnivariatesTypeNoOptimisticSkipping = + std::conditional_t; + + /** + * @brief Compute combiner using univariates that do not avoid zero computation in case of valid incoming indices. + * @details This is only used for testing the combiner calculation. + */ + ExtendedUnivariateWithRandomization compute_combiner_no_optimistic_skipping( + const DeciderPKs& keys, + const GateSeparatorPolynomial& gate_separators, + const UnivariateRelationParametersNoOptimisticSkipping& relation_parameters, + const UnivariateRelationSeparator& alphas) + { + TupleOfTuplesOfUnivariatesNoOptimisticSkipping accumulators; + return compute_combiner_no_optimistic_skipping( + keys, gate_separators, relation_parameters, alphas, accumulators); + } + + /** + * @brief Compute the combiner polynomial $G$ in the Protogalaxy paper + * @details We have implemented an optimization that (eg in the case where we fold one instance-witness pair at a + * time) assumes the value G(1) is 0, which is true in the case where the witness to be folded is valid. + * @todo (https://github.com/AztecProtocol/barretenberg/issues/968) Make combiner tests better + * + * @tparam skip_zero_computations whether to use the optimization that skips computing zero. + * @param + * @param gate_separators + * @return ExtendedUnivariateWithRandomization + */ + ExtendedUnivariateWithRandomization compute_combiner_no_optimistic_skipping( + const DeciderPKs& keys, + const GateSeparatorPolynomial& gate_separators, + const UnivariateRelationParametersNoOptimisticSkipping& relation_parameters, + const UnivariateRelationSeparator& alphas, + TupleOfTuplesOfUnivariatesNoOptimisticSkipping& univariate_accumulators) + { + PROFILE_THIS(); + + // Determine the number of threads over which to distribute the work + // The polynomial size is given by the virtual size since the computation includes + // the incoming key which could have nontrivial values on the larger domain in case of overflow. + const size_t common_polynomial_size = keys[0]->proving_key.polynomials.w_l.virtual_size(); + const size_t num_threads = compute_num_threads(common_polynomial_size); + + // Univariates are optimised for usual PG, but we need the unoptimised version for tests (it's a version that + // doesn't skip computation), so we need to define types depending on the template instantiation + using ThreadAccumulators = TupleOfTuplesOfUnivariatesNoOptimisticSkipping; + // Construct univariate accumulator containers; one per thread + std::vector thread_univariate_accumulators(num_threads); + + // Distribute the execution trace rows across threads so that each handles an equal number of active rows + trace_usage_tracker.construct_thread_ranges(num_threads, common_polynomial_size); + + // Accumulate the contribution from each sub-relation + parallel_for(num_threads, [&](size_t thread_idx) { + // Initialize the thread accumulator to 0 + RelationUtils::zero_univariates(thread_univariate_accumulators[thread_idx]); + // Construct extended univariates containers; one per thread + ExtendedUnivariatesTypeNoOptimisticSkipping extended_univariates; + + const size_t start = trace_usage_tracker.thread_ranges[thread_idx].first; + const size_t end = trace_usage_tracker.thread_ranges[thread_idx].second; + for (size_t idx = start; idx < end; idx++) { + if (trace_usage_tracker.check_is_active(idx)) { + // Instantiate univariates, possibly with skipping toto ignore computation in those indices (they + // are still available for skipping relations, but all derived univariate will ignore those + // evaluations) No need to initialise extended_univariates to 0, as it's assigned to. + constexpr size_t skip_count = 0; + extend_univariates(extended_univariates, keys, idx); + + const FF pow_challenge = gate_separators[idx]; + + // Accumulate the i-th row's univariate contribution. Note that the relation parameters passed to + // this function have already been folded. Moreover, linear-dependent relations that act over the + // entire execution trace rather than on rows, will not be multiplied by the pow challenge. + accumulate_relation_univariates_no_optimistic_skipping( + thread_univariate_accumulators[thread_idx], + extended_univariates, + relation_parameters, // these parameters have already been folded + pow_challenge); + } + } + }); + RelationUtils::zero_univariates(univariate_accumulators); + // Accumulate the per-thread univariate accumulators into a single set of accumulators + for (auto& accumulators : thread_univariate_accumulators) { + RelationUtils::add_nested_tuples(univariate_accumulators, accumulators); + } + // This does nothing if TupleOfTuples is TupleOfTuplesOfUnivariates + TupleOfTuplesOfUnivariatesNoOptimisticSkipping deoptimized_univariates = + deoptimise_univariates(univariate_accumulators); + // Batch the univariate contributions from each sub-relation to obtain the round univariate + return batch_over_relations(deoptimized_univariates, alphas); + } + + /** + * @brief Add the value of each relation over univariates to an appropriate accumulator + * + * @tparam TupleOfTuplesOfUnivariates_ A tuple of univariate accumulators, where the univariates may be optimized to + * avoid computation on some indices. + * @tparam ExtendedUnivariates_ T + * @tparam Parameters relation parameters type + * @tparam relation_idx The index of the relation + * @param univariate_accumulators + * @param extended_univariates + * @param relation_parameters + * @param scaling_factor + */ + template + BB_INLINE static void accumulate_relation_univariates_no_optimistic_skipping( + TupleOfTuplesOfUnivariatesNoOptimisticSkipping& univariate_accumulators, + const ExtendedUnivariatesTypeNoOptimisticSkipping& extended_univariates, + const UnivariateRelationParametersNoOptimisticSkipping& relation_parameters, + const FF& scaling_factor) + { + using Relation = std::tuple_element_t; + + // Check if the relation is skippable to speed up accumulation + if constexpr (!isSkippable) { + // If not, accumulate normally + Relation::accumulate(std::get(univariate_accumulators), + extended_univariates, + relation_parameters, + scaling_factor); + } else { + // If so, only compute the contribution if the relation is active + if (!Relation::skip(extended_univariates)) { + Relation::accumulate(std::get(univariate_accumulators), + extended_univariates, + relation_parameters, + scaling_factor); + } + } + + // Repeat for the next relation. + if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { + accumulate_relation_univariates_no_optimistic_skipping( + univariate_accumulators, extended_univariates, relation_parameters, scaling_factor); + } + } +}; // TODO(https://github.com/AztecProtocol/barretenberg/issues/780): Improve combiner tests to check more than the // arithmetic relation so we more than unit test folding relation parameters and alpha as well. TEST(Protogalaxy, CombinerOn2Keys) { - constexpr size_t NUM_KEYS = 2; using DeciderProvingKey = DeciderProvingKey_; using DeciderProvingKeys = DeciderProvingKeys_; - using PGInternal = ProtogalaxyProverInternal; const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { std::fill(polys.q_arith.coeffs().begin(), polys.q_arith.coeffs().end(), 1); @@ -34,7 +192,7 @@ TEST(Protogalaxy, CombinerOn2Keys) }; auto run_test = [&](bool is_random_input) { - PGInternal pg_internal; // instance of the PG internal prover + PGInternalTest pg_internal; // instance of the PG internal prover // Combiner test on prover polynomials containing random values, restricted to only the standard arithmetic // relation. @@ -53,10 +211,10 @@ TEST(Protogalaxy, CombinerOn2Keys) } DeciderProvingKeys keys{ keys_data }; - PGInternal::UnivariateRelationSeparator alphas; + PGInternalTest::UnivariateRelationSeparator alphas; alphas.fill(bb::Univariate(FF(0))); // focus on the arithmetic relation only GateSeparatorPolynomial gate_separators({ 2 }, /*log_num_monomials=*/1); - PGInternal::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; + PGInternalTest::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; auto result_no_skipping = pg_internal.compute_combiner_no_optimistic_skipping( keys, gate_separators, univariate_relation_parameters_no_skpping, alphas); // The expected_result values are computed by running the python script combiner_example_gen.py @@ -88,7 +246,7 @@ TEST(Protogalaxy, CombinerOn2Keys) } DeciderProvingKeys keys{ keys_data }; - PGInternal::UnivariateRelationSeparator alphas; + PGInternalTest::UnivariateRelationSeparator alphas; alphas.fill(bb::Univariate(FF(0))); // focus on the arithmetic relation only const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { @@ -136,8 +294,8 @@ TEST(Protogalaxy, CombinerOn2Keys) 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ GateSeparatorPolynomial gate_separators({ 2 }, /*log_num_monomials=*/1); - PGInternal::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; - PGInternal::UnivariateRelationParameters univariate_relation_parameters; + PGInternalTest::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; + PGInternalTest::UnivariateRelationParameters univariate_relation_parameters; auto result_no_skipping = pg_internal.compute_combiner_no_optimistic_skipping( keys, gate_separators, univariate_relation_parameters_no_skpping, alphas); auto result_with_skipping = @@ -156,10 +314,8 @@ TEST(Protogalaxy, CombinerOn2Keys) // Check that the optimized combiner computation yields a result consistent with the unoptimized version TEST(Protogalaxy, CombinerOptimizationConsistency) { - constexpr size_t NUM_KEYS = 2; using DeciderProvingKey = DeciderProvingKey_; using DeciderProvingKeys = DeciderProvingKeys_; - using PGInternal = ProtogalaxyProverInternal; using UltraArithmeticRelation = UltraArithmeticRelation; constexpr size_t UNIVARIATE_LENGTH = 12; @@ -175,7 +331,7 @@ TEST(Protogalaxy, CombinerOptimizationConsistency) }; auto run_test = [&](bool is_random_input) { - PGInternal pg_internal; // instance of the PG internal prover + PGInternalTest pg_internal; // instance of the PG internal prover // Combiner test on prover polynomisls containing random values, restricted to only the standard arithmetic // relation. @@ -195,7 +351,7 @@ TEST(Protogalaxy, CombinerOptimizationConsistency) } DeciderProvingKeys keys{ keys_data }; - PGInternal::UnivariateRelationSeparator alphas; + PGInternalTest::UnivariateRelationSeparator alphas; alphas.fill(bb::Univariate(FF(0))); // focus on the arithmetic relation only GateSeparatorPolynomial gate_separators({ 2 }, /*log_num_monomials=*/1); @@ -257,8 +413,8 @@ TEST(Protogalaxy, CombinerOptimizationConsistency) precomputed_result[idx] = std::get<0>(accumulator)[0]; } auto expected_result = Univariate(precomputed_result); - PGInternal::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; - PGInternal::UnivariateRelationParameters univariate_relation_parameters; + PGInternalTest::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; + PGInternalTest::UnivariateRelationParameters univariate_relation_parameters; auto result_no_skipping = pg_internal.compute_combiner_no_optimistic_skipping( keys, gate_separators, univariate_relation_parameters_no_skpping, alphas); auto result_with_skipping = @@ -281,7 +437,7 @@ TEST(Protogalaxy, CombinerOptimizationConsistency) } DeciderProvingKeys keys{ keys_data }; - PGInternal::UnivariateRelationSeparator alphas; + PGInternalTest::UnivariateRelationSeparator alphas; alphas.fill(bb::Univariate(FF(0))); // focus on the arithmetic relation only const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { @@ -329,8 +485,8 @@ TEST(Protogalaxy, CombinerOptimizationConsistency) 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ GateSeparatorPolynomial gate_separators({ 2 }, /*log_num_monomials=*/1); - PGInternal::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; - PGInternal::UnivariateRelationParameters univariate_relation_parameters; + PGInternalTest::UnivariateRelationParametersNoOptimisticSkipping univariate_relation_parameters_no_skpping; + PGInternalTest::UnivariateRelationParameters univariate_relation_parameters; auto result_no_skipping = pg_internal.compute_combiner_no_optimistic_skipping( keys, gate_separators, univariate_relation_parameters_no_skpping, alphas); auto result_with_skipping = diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 3b62b327134..aef9371ef62 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -13,8 +13,6 @@ template class ProtogalaxyProver_ { using FF = typename DeciderProvingKeys_::Flavor::FF; static constexpr size_t NUM_KEYS = DeciderProvingKeys_::NUM; using CombinerQuotient = Univariate; - using TupleOfTuplesOfUnivariatesNoOptimisticSkipping = - typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariatesNoOptimisticSkipping; using TupleOfTuplesOfUnivariates = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates; using UnivariateRelationParameters = bb::RelationParameters>; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp index 7c7bcd77ffb..221d732a796 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_internal.hpp @@ -44,18 +44,39 @@ template class ProtogalaxyProverInternal { using ExtendedUnivariateWithRandomization = Univariate; - // TODO: describe wtf is going on here - using ShortUnivariates = typename Flavor::template ProverUnivariates<2>; + /** + * @brief ShortUnivariates is an optimisation to improve the evaluation of Flavor relations when the output is a + * low-degree monomial + * @details Each Flavor relation is computed as a degree-Flavor::MAX_TOTAL_RELATION_LENGTH Univariate monomial in + * the Lagrange basis, however it is more efficient if the *input* monomials into the relation are not in this form, + * but are instead left as a degree-1 monomial using the *coefficient basis* (i.e. P(X) = a0 + a1.X) + * + * When computing relation algebra, it is typically more efficient to use the coefficient basis up to + * degree-2. If the degree must be extended beyond 2, then the monomials are converted into their higher-degree + * representation in the Lagrange basis. + * + * Not only is the relation algebra more efficient, but we do not have to perform a basis extension on all + * the Flavor polynomials each time the Flavor relation algebra is evaluated. + * Given the sparse representation of our circuits, many relations are skipped each row which means many polynomials + * can go unused. By skipping the basis extension entirely we avoid this unneccessary work. + * + * Tests indicates that utilizing ShortUnivariates speeds up the `benchmark_client_ivc.sh` benchmark by 10% + * @note This only works if DeciderPKs::NUM == 2. The whole protogalaxy class would require substantial revision to + * support more PKs so this should be adequate for now + */ + using ShortUnivariates = typename Flavor::template ProverUnivariates; - using ExtendedUnivariatesNoOptimisticSkipping = - typename Flavor::template ProverUnivariates; using ExtendedUnivariates = typename Flavor::template ProverUnivariatesWithOptimisticSkipping; + using ExtendedUnivariatesType = + std::conditional_t; + + using TupleOfTuplesOfUnivariates = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates; using TupleOfTuplesOfUnivariatesNoOptimisticSkipping = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariatesNoOptimisticSkipping; - using TupleOfTuplesOfUnivariates = typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates; + using RelationEvaluations = typename Flavor::TupleOfArraysOfValues; static constexpr size_t NUM_SUBRELATIONS = DeciderPKs::NUM_SUBRELATIONS; @@ -296,23 +317,17 @@ template class ProtogalaxyProverInternal { */ template - BB_INLINE static void extend_univariates( - std::conditional_t< - Flavor::USE_SHORT_MONOMIALS, - ShortUnivariates, - std::conditional_t>& - extended_univariates, - const DeciderPKs& keys, - const size_t row_idx) + BB_INLINE static void extend_univariates(ExtendedUnivariatesType& extended_univariates, + const DeciderPKs& keys, + const size_t row_idx) { PROFILE_THIS_NAME("PG::extend_univariates"); if constexpr (Flavor::USE_SHORT_MONOMIALS) { extended_univariates = std::move(keys.row_to_short_univariates(row_idx)); } else { - constexpr size_t _skip_count = Flavor::USE_SHORT_MONOMIALS ? 0 : skip_count; auto incoming_univariates = - keys.template row_to_univariates(row_idx); + keys.template row_to_univariates(row_idx); for (auto [extended_univariate, incoming_univariate] : zip_view(extended_univariates.get_all(), incoming_univariates)) { incoming_univariate.template self_extend_from(); @@ -334,13 +349,10 @@ template class ProtogalaxyProverInternal { * @param relation_parameters * @param scaling_factor */ - template - BB_INLINE static void accumulate_relation_univariates(TupleOfTuplesOfUnivariates_& univariate_accumulators, - const ExtendedUnivariates_& extended_univariates, - const Parameters& relation_parameters, + template + BB_INLINE static void accumulate_relation_univariates(TupleOfTuplesOfUnivariates& univariate_accumulators, + const ExtendedUnivariatesType& extended_univariates, + const UnivariateRelationParameters& relation_parameters, const FF& scaling_factor) { using Relation = std::tuple_element_t; @@ -364,10 +376,7 @@ template class ProtogalaxyProverInternal { // Repeat for the next relation. if constexpr (relation_idx + 1 < Flavor::NUM_RELATIONS) { - accumulate_relation_univariates( + accumulate_relation_univariates( univariate_accumulators, extended_univariates, relation_parameters, scaling_factor); } } @@ -383,18 +392,14 @@ template class ProtogalaxyProverInternal { * @param gate_separators * @return ExtendedUnivariateWithRandomization */ - template ExtendedUnivariateWithRandomization compute_combiner(const DeciderPKs& keys, const GateSeparatorPolynomial& gate_separators, - const Parameters& relation_parameters, + const UnivariateRelationParameters& relation_parameters, const UnivariateRelationSeparator& alphas, - TupleOfTuples& univariate_accumulators) + TupleOfTuplesOfUnivariates& univariate_accumulators) { PROFILE_THIS(); - // Whether to use univariates whose operators ignore some values which an honest prover would compute to be zero - constexpr bool skip_zero_computations = std::same_as; - // Determine the number of threads over which to distribute the work // The polynomial size is given by the virtual size since the computation includes // the incoming key which could have nontrivial values on the larger domain in case of overflow. @@ -403,14 +408,7 @@ template class ProtogalaxyProverInternal { // Univariates are optimised for usual PG, but we need the unoptimised version for tests (it's a version that // doesn't skip computation), so we need to define types depending on the template instantiation - using ThreadAccumulators = TupleOfTuples; - using ExtendedUnivatiatesType = - - std::conditional_t>; + using ThreadAccumulators = TupleOfTuplesOfUnivariates; // Construct univariate accumulator containers; one per thread std::vector thread_univariate_accumulators(num_threads); @@ -423,7 +421,7 @@ template class ProtogalaxyProverInternal { // Initialize the thread accumulator to 0 RelationUtils::zero_univariates(thread_univariate_accumulators[thread_idx]); // Construct extended univariates containers; one per thread - ExtendedUnivatiatesType extended_univariates; + ExtendedUnivariatesType extended_univariates; const size_t start = trace_usage_tracker.thread_ranges[thread_idx].first; const size_t end = trace_usage_tracker.thread_ranges[thread_idx].second; @@ -432,7 +430,7 @@ template class ProtogalaxyProverInternal { // Instantiate univariates, possibly with skipping toto ignore computation in those indices (they // are still available for skipping relations, but all derived univariate will ignore those // evaluations) No need to initialise extended_univariates to 0, as it's assigned to. - constexpr size_t skip_count = skip_zero_computations ? DeciderPKs::NUM - 1 : 0; + constexpr size_t skip_count = DeciderPKs::NUM - 1; extend_univariates(extended_univariates, keys, idx); const FF pow_challenge = gate_separators[idx]; @@ -460,20 +458,6 @@ template class ProtogalaxyProverInternal { return batch_over_relations(deoptimized_univariates, alphas); } - /** - * @brief Compute combiner using univariates that do not avoid zero computation in case of valid incoming indices. - * @details This is only used for testing the combiner calculation. - */ - ExtendedUnivariateWithRandomization compute_combiner_no_optimistic_skipping( - const DeciderPKs& keys, - const GateSeparatorPolynomial& gate_separators, - const UnivariateRelationParametersNoOptimisticSkipping& relation_parameters, - const UnivariateRelationSeparator& alphas) - { - TupleOfTuplesOfUnivariatesNoOptimisticSkipping accumulators; - return compute_combiner(keys, gate_separators, relation_parameters, alphas, accumulators); - } - ExtendedUnivariateWithRandomization compute_combiner(const DeciderPKs& keys, const GateSeparatorPolynomial& gate_separators, const UnivariateRelationParameters& relation_parameters, From 3e1065bde7cc09327a913802fd965ae87801d582 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 10 Dec 2024 14:10:23 +0000 Subject: [PATCH 25/30] Updated to reflect PR comments --- .../relations/auxiliary_relation.hpp | 6 +++ .../relations/databus_lookup_relation.hpp | 5 +- .../relations/ecc_op_queue_relation.hpp | 5 +- .../relations/permutation_relation.hpp | 22 -------- .../relations/ultra_arithmetic_relation.hpp | 53 ------------------- .../mega_recursive_flavor.hpp | 2 +- .../ultra_recursive_flavor.hpp | 2 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 4 +- .../barretenberg/ultra_honk/decider_keys.hpp | 4 +- 9 files changed, 18 insertions(+), 85 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index 1bce9ca64b6..84b705d7aff 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -170,6 +170,12 @@ template class AuxiliaryRelationImpl { limb_subproduct += (w_1_shift_m * w_2_shift_m); auto non_native_field_gate_1_m = limb_subproduct; non_native_field_gate_1_m -= (w_3_m + w_4_m); + // We transform into ShortAccumulator to extend the degree of `non_native_field_gate_1` beyond degree-2 + // (MonomialAccumulator only supports Monomials of up to degree 2 as it is not efficient to peform higher-degree + // computations in the coefficient basis) + // We use ShortAccumulator instead of Accumulator, because this term is only used in subrelations that have the + // same degree as subrelation `0` (which can be lower than the degree of subrelation `3`, which is how + // `Accumulator` is defined) auto non_native_field_gate_1 = ShortAccumulator(non_native_field_gate_1_m) * ShortAccumulator(q_3_m); auto non_native_field_gate_3_m = limb_subproduct; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 39d0821aa3a..26b3a6400b1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -186,9 +186,8 @@ template class DatabusLookupRelationImpl { static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) { using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using View = typename Accumulator::View; - using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + using ParameterMonomialAccumulator = + typename GetParameterView::MonomialAccumulator; const auto& id = MonomialAccumulator(in.databus_id); const auto& value = MonomialAccumulator(BusData::values(in)); diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp index 74b2949afb5..d16c3a4bc5e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp @@ -68,7 +68,10 @@ template class EccOpQueueRelationImpl { PROFILE_THIS_NAME("EccOp::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - + // We skip using the MonomialAccumulator type in this relation, as the overall relation degree is low (deg 3). + // To do a degree-1 multiplication in the coefficient basis requires 3 Fp muls and 4 Fp adds (karatsuba + // multiplication). But a multiplication of a degree-3 Univariate only requires 3 Fp muls. + // We still cast to MonomialAccumulator so that the degree is extended to degree-3 from degree-1 auto w_1 = Accumulator(MonomialAccumulator(in.w_l)); auto w_2 = Accumulator(MonomialAccumulator(in.w_r)); auto w_3 = Accumulator(MonomialAccumulator(in.w_o)); diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index a6314a82cbd..e4efc0884f8 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -157,28 +157,6 @@ template class UltraPermutationRelationImpl { const auto w_3_plus_gamma = w_3_m + gamma_m; const auto w_4_plus_gamma = w_4_m + gamma_m; - // improvements... when multiplying, `(a0 + a1) * (b0 + b1)` can be done without additions - // because a0 + a1 is equivalent to `evaluations[1]` of an Accumlulator or View object - // would save 32 additions - - // 24 adds - // karatsuba = 2 * 8 = 16 adds - // converting 14 entities into monomial accs = 14 adds - // 54 adds - // equiv of 5 degree-11 adds - // previously we had 16 degree-11 adds - - // we convert 8 acumulators - // each accumulator conversion requires degree * 2 adds which is 22 adds - // equivalent to 16 degree-11 adds - - // so in terms of additions we're down by 5 degree-11 adds - // previously we had 8 degree-11 muls - // new version we have 8 karatsuba muls which is 3 * 8 = 24 muls - // 8 * 11 = 88 (actually 80). diff = 56 muls - - // however we no longer need to construct accumulators out of sigmas and ids. 8 polynomials = 8 degree-11 - // adds however we do these automatically atm? in theory we could remove about 80 additions- auto t1 = (id_1_m * beta_m); t1 += w_1_plus_gamma; t1 *= scaling_factor; diff --git a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp index f5203163413..bfae432f06e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp @@ -95,32 +95,6 @@ template class UltraArithmeticRelationImpl { auto scaled_q_arith = q_arith_m * scaling_factor; { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - // auto w_l = View(in.w_l); - // auto w_r = View(in.w_r); - // auto w_o = View(in.w_o); - // auto w_4 = View(in.w_4); - // auto w_4_shift = View(in.w_4_shift); - // auto q_m = View(in.q_m); - // auto q_l = View(in.q_l); - // auto q_r = View(in.q_r); - // auto q_o = View(in.q_o); - // auto q_4 = View(in.q_4); - // auto q_c = View(in.q_c); - // auto q_arith = View(in.q_arith); - - // static const FF neg_half = FF(-2).invert(); - - // auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; - // tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; - // tmp += (q_arith - 1) * w_4_shift; - // tmp *= q_arith; - // tmp *= scaling_factor; - // std::get<0>(evals) += tmp; - - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - // auto w_l_m = MonomialAccumulator(in.w_l); - // auto w_r_m = MonomialAccumulator(in.w_r); - // auto q_m_m = MonomialAccumulator(in.q_m); auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); auto w_r_m = MonomialAccumulator(in.w_r); @@ -133,40 +107,13 @@ template class UltraArithmeticRelationImpl { static const FF neg_half = FF(-2).invert(); - // auto tmp0 = (q_arith - 3) * q_m * Accumulator(w_r_m * w_l_m); - // tmp0 *= neg_half; - // tmp0 += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; - // tmp0 += (q_arith - 1) * w_4_shift; - // tmp0 *= q_arith; - // tmp0 *= scaling_factor; - - // std::get<0>(evals) += tmp0; - auto tmp0 = Accumulator(w_r_m * w_l_m * neg_half) * Accumulator((q_arith_m - 3) * q_m_m); auto tmp1 = (q_l_m * w_l_m) + (q_r_m * w_r_m) + (q_o_m * w_o_m) + (q_4_m * w_4_m) + q_c_m; tmp1 += q_arith_sub_1 * w_4_shift_m; std::get<0>(evals) += (tmp0 + Accumulator(tmp1)) * Accumulator(scaled_q_arith); - // auto tmp = (q_arith - 3) * (q_m * w_r * w_l) * neg_half; - // tmp += (q_l * w_l) + (q_r * w_r) + (q_o * w_o) + (q_4 * w_4) + q_c; - // tmp += (q_arith - 1) * w_4_shift; - // tmp *= q_arith; - // tmp *= scaling_factor; - // std::get<0>(evals) += tmp; } { - // using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - // // using View = typename Accumulator::View; - // using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - // auto w_l = MonomialAccumulator(in.w_l); - // auto w_4 = MonomialAccumulator(in.w_4); - // auto w_l_shift = MonomialAccumulator(in.w_l_shift); - // auto q_m = MonomialAccumulator(in.q_m); - // auto q_arith = MonomialAccumulator(in.q_arith); - - // auto tmp0 = (w_l + w_4 - w_l_shift + q_m) * (q_arith - 2); - // auto tmp1 = (q_arith - 1) * q_arith * scaling_factor; - // std::get<1>(evals) += Accumulator(tmp0) * Accumulator(tmp1); using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp index 39db9c183b0..2be8002ae47 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp @@ -41,7 +41,7 @@ template class MegaRecursiveFlavor_ { using NativeVerificationKey = NativeFlavor::VerificationKey; // indicates when evaluating sumcheck, edges can be left as degree-1 monomials - static constexpr bool USE_SHORT_MONOMIALS = true; + static constexpr bool USE_SHORT_MONOMIALS = MegaFlavor::USE_SHORT_MONOMIALS; // Note(luke): Eventually this may not be needed at all using VerifierCommitmentKey = bb::VerifierCommitmentKey; // Indicates that this flavor runs with non-ZK Sumcheck. diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp index 31bdec750e0..2e19373a8c6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp @@ -55,7 +55,7 @@ template class UltraRecursiveFlavor_ { using NativeVerificationKey = NativeFlavor::VerificationKey; // indicates when evaluating sumcheck, edges can be left as degree-1 monomials - static constexpr bool USE_SHORT_MONOMIALS = true; + static constexpr bool USE_SHORT_MONOMIALS = UltraFlavor::USE_SHORT_MONOMIALS; // Note(luke): Eventually this may not be needed at all using VerifierCommitmentKey = bb::VerifierCommitmentKey; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 220ec0838df..adb87ef96c7 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -115,10 +115,10 @@ transcript. These operations are taken care of by \ref bb::BaseTranscript "Trans The Sumcheck output is specified by \ref bb::SumcheckOutput< Flavor >. */ template class SumcheckProver { - // PartiallyEvaluatedMultivariates OR ProverPolynomials - // both inherit from AllEntities public: using FF = typename Flavor::FF; + // PartiallyEvaluatedMultivariates OR ProverPolynomials + // both inherit from AllEntities using ProverPolynomials = typename Flavor::ProverPolynomials; using PartiallyEvaluatedMultivariates = typename Flavor::PartiallyEvaluatedMultivariates; using ClaimedEvaluations = typename Flavor::AllValues; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index c7bb902b711..5252e5726d8 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -75,8 +75,8 @@ template struct DeciderProvingKeys_ { typename Flavor::template ProverUnivariates<2> results; // Set the size corresponding to the number of rows in the execution trace // Iterate over the prover polynomials' views corresponding to each proving key - for (size_t dpk_idx = 0; auto& get_all : prover_polynomials_views) { - // Iterate over all columns in the trace execution of an proving key and extract their value at row_idx. + for (size_t dpk_idx = 0; const auto& get_all : prover_polynomials_views) { + // Iterate over all columns in the trace execution of a proving key and extract their value at row_idx. for (auto [result, poly_ptr] : zip_view(results.get_all(), get_all)) { result.evaluations[dpk_idx] = poly_ptr[row_idx]; } From 12959efb371e26d25c058eeef9a0664137dba536 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 10 Dec 2024 14:12:45 +0000 Subject: [PATCH 26/30] more PR feedback --- .../stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp | 3 +++ .../translator_vm_verifier/translator_recursive_flavor.hpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp index 637fe115c07..e1b7703e14e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp @@ -33,6 +33,9 @@ template class ECCVMRecursiveFlavor_ { using NativeVerificationKey = NativeFlavor::VerificationKey; using PCS = IPA; + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = ECCVMFlavor::USE_SHORT_MONOMIALS; + // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = true; static constexpr size_t NUM_WIRES = ECCVMFlavor::NUM_WIRES; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp index ffbf91dea89..13520792bb5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp @@ -41,6 +41,10 @@ template class TranslatorRecursiveFlavor_ { using NativeVerificationKey = NativeFlavor::VerificationKey; using VerifierCommitmentKey = bb::VerifierCommitmentKey; + + // indicates when evaluating sumcheck, edges must be extended to be MAX_TOTAL_RELATION_LENGTH + static constexpr bool USE_SHORT_MONOMIALS = TranslatorFlavor::USE_SHORT_MONOMIALS; + // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = true; static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; From 4e4aa74e54b548ad4fafe6a1e04f1f3c4fff50b3 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Tue, 10 Dec 2024 14:22:38 +0000 Subject: [PATCH 27/30] more PR feedback --- .../polynomials/univariate_monomial.hpp | 24 ++++++++++++------- .../relations/auxiliary_relation.hpp | 1 - 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp index a7d465e8a94..cd9f6f9a834 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp @@ -19,6 +19,15 @@ namespace bb { * memory efficiency purposes, we store the coefficients in an array starting from 0 and make the mapping to the right * domain under the hood. * + * @details We represent a UnivariateMonomial as a polynomial P(X) = a0 + a1.X + a2.X^2 + * @tparam has_a0_plus_a1: This is true if we know the sum of the above coefficients `a0 + a1` + * This is an optimisation to improve the performance of Karatsuba polynomial multiplication, which requires + * this term. When converting from a degree-1 Monomial in the Lagrange basis, into a UnivariateMonomial, we can get `a0 + * + a1` for free. i.e. for a Lagrange-basis poly, we have P(X) = v0.L0(X) + v1.L1(X) = v0.(1 - X) + v1.X = v0 + (v1 - + * v0).X From this we can see that a0 = v0, a1 = v1 - v0 and therefore (a0 + a1) = v1 + * @note `has_a0_plus_a1` should only be true in the case where `LENGTH == 2` as this is the only case where we can + * acquire this term for free + * @note After performing any arithmetic operation on UnivaraiteMonomial, the output will have `has_a0_plus_a1 = false` */ template class UnivariateMonomial { public: @@ -26,6 +35,13 @@ template class UnivariateMono static_assert(LENGTH == 2 || LENGTH == 3); using value_type = Fr; // used to get the type of the elements consistently with std::array + /** + * @brief coefficients is a length-3 array with the following representation: + * @details This class represents a polynomial P(X) = a0 + a1.X + a2.X^2 + * We define `coefficients[0] = a0` and `coefficients[1] = a1` + * If LENGTH == 2 AND `has_a0_plus_a1 = true` then `coefficients[2] = a0 + a1` + * If LENGTH == 3 then `coefficients[3] = a2` + */ std::array coefficients; UnivariateMonomial() = default; @@ -172,14 +188,6 @@ template class UnivariateMono return result; } - // UnivariateMonomial& self_sqr() - // { - // coefficients[0].self_sqr(); - // for (size_t i = skip_count + 1; i < LENGTH; ++i) { - // coefficients[i].self_sqr(); - // } - // return *this; - // } template UnivariateMonomial operator+( const UnivariateMonomial& other) const diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index 84b705d7aff..186678c0567 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -376,7 +376,6 @@ template class AuxiliaryRelationImpl { auto memory_identity = ROM_consistency_check_identity; // deg 3 or 4 memory_identity += RAM_timestamp_check_identity * ShortAccumulator(q_4_m * q_1_m); // deg 4 memory_identity += memory_record_check * ShortAccumulator(q_m_m * q_1_m); // deg 3 or 4 - // memory_identity += RAM_consistency_check_identity; // deg 3 or 5 // (deg 3 or 5) + (deg 4) + (deg 3) auto auxiliary_identity = memory_identity + non_native_field_identity + limb_accumulator_identity; From f05172847798e562fe78ed7970a32fca10c792b8 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 11 Dec 2024 15:16:03 +0000 Subject: [PATCH 28/30] added tests for UnivariateMonomial --- .../polynomials/univariate_monomial.test.cpp | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp new file mode 100644 index 00000000000..b9f92d6b53f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp @@ -0,0 +1,74 @@ +#include "univariate_monomial.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "univariate.hpp" +#include + +using namespace bb; + +template class UnivariateMonomialTest : public testing::Test { + public: + template using UnivariateView = UnivariateView; +}; + +using FieldTypes = testing::Types; +TYPED_TEST_SUITE(UnivariateMonomialTest, FieldTypes); + +TYPED_TEST(UnivariateMonomialTest, Conversion) +{ + fr a0 = fr::random_element(); + fr a1 = fr::random_element(); + + Univariate expected({ a0, a1 }); + UnivariateMonomial uni_m(expected); + Univariate result(uni_m); + EXPECT_EQ(result, expected); +} + +TYPED_TEST(UnivariateMonomialTest, Addition) +{ + Univariate f1{ { 1, 2 } }; + Univariate f2{ { 3, 4 } }; + UnivariateMonomial f1_m(f1); + UnivariateMonomial f2_m(f2); + + Univariate result(f1_m + f2_m); + Univariate expected = f1 + f2; + EXPECT_EQ(result, expected); +} + +TYPED_TEST(UnivariateMonomialTest, Multiplication) +{ + + Univariate f1({ 1, 2 }); + Univariate f2({ 3, 4 }); + UnivariateMonomial f1_m(f1); + UnivariateMonomial f2_m(f2); + + Univariate result(f1_m * f2_m); + Univariate expected = (f1.template extend_to<3>()) * (f2.template extend_to<3>()); + EXPECT_EQ(result, expected); +} + +TYPED_TEST(UnivariateMonomialTest, Serialization) +{ + const size_t LENGTH = 2; + std::array evaluations; + + for (size_t i = 0; i < LENGTH; ++i) { + evaluations[i] = fr::random_element(); + } + + // Instantiate a Univariate from the evaluations + auto univariate = Univariate(evaluations); + UnivariateMonomial univariate_m(univariate); + // Serialize univariate to buffer + std::vector buffer = univariate_m.to_buffer(); + + // Deserialize + auto deserialized_univariate = + Univariate(UnivariateMonomial::serialize_from_buffer(&buffer[0])); + + for (size_t i = 0; i < LENGTH; ++i) { + EXPECT_EQ(univariate.value_at(i), deserialized_univariate.value_at(i)); + } +} From a0998092a272bbb142e03b1de2a5d457e45d821f Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Wed, 11 Dec 2024 15:22:39 +0000 Subject: [PATCH 29/30] renamed "UnivariateMonomial" to "UnivariateCoefficientBasis" renamed "MonomialAccumulator" to "CoefficientAccumulator" --- .../relations_bench/relations.bench.cpp | 6 +- .../ecc/fields/field_declarations.hpp | 2 +- .../barretenberg/polynomials/univariate.hpp | 24 ++-- ...l.hpp => univariate_coefficient_basis.hpp} | 105 +++++++++--------- ... => univariate_coefficient_basis.test.cpp} | 28 ++--- .../relations/auxiliary_relation.hpp | 59 +++++----- .../relations/databus_lookup_relation.hpp | 50 ++++----- .../delta_range_constraint_relation.hpp | 14 +-- .../relations/ecc_op_queue_relation.hpp | 26 ++--- .../relations/elliptic_relation.hpp | 20 ++-- .../relations/logderiv_lookup_relation.hpp | 70 ++++++------ .../relations/permutation_relation.hpp | 46 ++++---- .../relations/poseidon2_external_relation.hpp | 28 ++--- .../relations/poseidon2_internal_relation.hpp | 22 ++-- .../relations/ultra_arithmetic_relation.hpp | 28 ++--- .../stdlib/primitives/bigfield/bigfield.hpp | 2 +- .../stdlib/primitives/field/field.hpp | 2 +- 17 files changed, 266 insertions(+), 266 deletions(-) rename barretenberg/cpp/src/barretenberg/polynomials/{univariate_monomial.hpp => univariate_coefficient_basis.hpp} (73%) rename barretenberg/cpp/src/barretenberg/polynomials/{univariate_monomial.test.cpp => univariate_coefficient_basis.test.cpp} (62%) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp index 6ea39cbc4ae..91deb88113a 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp @@ -54,9 +54,9 @@ template void execute_relation_for_univaria template void execute_relation_for_pg_univariates(::benchmark::State& state) { using DeciderProvingKeys = DeciderProvingKeys_; - using Input = ProtogalaxyProverInternal::ExtendedUnivariatesNoOptimisticSkipping; - using Accumulator = typename Relation::template ProtogalaxyTupleOfUnivariatesOverSubrelationsNoOptimisticSkipping< - DeciderProvingKeys::NUM>; + using Input = ProtogalaxyProverInternal::ExtendedUnivariates; + using Accumulator = + typename Relation::template ProtogalaxyTupleOfUnivariatesOverSubrelations; execute_relation(state); } diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp index ff5a2c972f6..50d01844e0e 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp @@ -29,7 +29,7 @@ namespace bb { template struct alignas(32) field { public: using View = field; - using MonomialAccumulator = field; + using CoefficientAccumulator = field; using Params = Params_; using in_buf = const uint8_t*; using vec_in_buf = const uint8_t*; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 5555a917d46..7eba6ca4410 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -2,7 +2,7 @@ #include "barretenberg/common/assert.hpp" #include "barretenberg/common/serialize.hpp" #include "barretenberg/polynomials/barycentric.hpp" -#include "barretenberg/polynomials/univariate_monomial.hpp" +#include "barretenberg/polynomials/univariate_coefficient_basis.hpp" #include namespace bb { @@ -32,7 +32,7 @@ template ; static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; - using MonomialAccumulator = UnivariateMonomial; + using CoefficientAccumulator = UnivariateCoefficientBasis; using value_type = Fr; // used to get the type of the elements consistently with std::array @@ -50,20 +50,20 @@ template () const + explicit operator UnivariateCoefficientBasis() const requires(LENGTH > 1) { static_assert(domain_end >= 2); static_assert(domain_start == 0); - UnivariateMonomial result; + UnivariateCoefficientBasis result; result.coefficients[0] = evaluations[0]; result.coefficients[1] = evaluations[1] - evaluations[0]; result.coefficients[2] = evaluations[1]; return result; } - template Univariate(UnivariateMonomial monomial) + template Univariate(UnivariateCoefficientBasis monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; @@ -80,7 +80,7 @@ template Univariate(UnivariateMonomial monomial) + template Univariate(UnivariateCoefficientBasis monomial) { static_assert(domain_start == 0); Fr to_add = monomial.coefficients[1]; // a1 + a2 @@ -102,17 +102,17 @@ template () const + // explicit operator UnivariateCoefficientBasis() const // { // static_assert(domain_end >= 2); // static_assert(domain_start == 0); // // (1 - X)a0 + Xa1 // // a0 // if constexpr (skip_count > 0) { - // UnivariateMonomial result{ .evaluations = { evaluations[0], 0 } }; + // UnivariateCoefficientBasis result{ .evaluations = { evaluations[0], 0 } }; // return result; // } else { - // UnivariateMonomial result{ .evaluations = { evaluations[0], + // UnivariateCoefficientBasis result{ .evaluations = { evaluations[0], // evaluations[1] - evaluations[0] } }; // return result; // } @@ -651,7 +651,7 @@ template evaluations; static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1; - using MonomialAccumulator = UnivariateMonomial; + using CoefficientAccumulator = UnivariateCoefficientBasis; UnivariateView() = default; @@ -672,13 +672,13 @@ template & univariate_in) : evaluations(std::span(univariate_in.evaluations.data(), LENGTH)){}; - explicit operator UnivariateMonomial() const + explicit operator UnivariateCoefficientBasis() const requires(LENGTH > 1) { static_assert(domain_end >= 2); static_assert(domain_start == 0); - UnivariateMonomial result; + UnivariateCoefficientBasis result; result.coefficients[0] = evaluations[0]; result.coefficients[1] = evaluations[1] - evaluations[0]; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.hpp similarity index 73% rename from barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp rename to barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.hpp index cd9f6f9a834..f26de9f0a12 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.hpp @@ -19,17 +19,18 @@ namespace bb { * memory efficiency purposes, we store the coefficients in an array starting from 0 and make the mapping to the right * domain under the hood. * - * @details We represent a UnivariateMonomial as a polynomial P(X) = a0 + a1.X + a2.X^2 + * @details We represent a UnivariateCoefficientBasis as a polynomial P(X) = a0 + a1.X + a2.X^2 * @tparam has_a0_plus_a1: This is true if we know the sum of the above coefficients `a0 + a1` * This is an optimisation to improve the performance of Karatsuba polynomial multiplication, which requires - * this term. When converting from a degree-1 Monomial in the Lagrange basis, into a UnivariateMonomial, we can get `a0 + * this term. When converting from a degree-1 Monomial in the Lagrange basis, into a UnivariateCoefficientBasis, we can + * get `a0 * + a1` for free. i.e. for a Lagrange-basis poly, we have P(X) = v0.L0(X) + v1.L1(X) = v0.(1 - X) + v1.X = v0 + (v1 - * v0).X From this we can see that a0 = v0, a1 = v1 - v0 and therefore (a0 + a1) = v1 * @note `has_a0_plus_a1` should only be true in the case where `LENGTH == 2` as this is the only case where we can * acquire this term for free * @note After performing any arithmetic operation on UnivaraiteMonomial, the output will have `has_a0_plus_a1 = false` */ -template class UnivariateMonomial { +template class UnivariateCoefficientBasis { public: static constexpr size_t LENGTH = domain_end; static_assert(LENGTH == 2 || LENGTH == 3); @@ -44,9 +45,9 @@ template class UnivariateMono */ std::array coefficients; - UnivariateMonomial() = default; + UnivariateCoefficientBasis() = default; - UnivariateMonomial(const UnivariateMonomial& other) + UnivariateCoefficientBasis(const UnivariateCoefficientBasis& other) requires(!has_a0_plus_a1) { coefficients[0] = other.coefficients[0]; @@ -56,14 +57,14 @@ template class UnivariateMono } } - ~UnivariateMonomial() = default; - UnivariateMonomial(const UnivariateMonomial& other) = default; - UnivariateMonomial(UnivariateMonomial&& other) noexcept = default; - UnivariateMonomial& operator=(const UnivariateMonomial& other) = default; - UnivariateMonomial& operator=(UnivariateMonomial&& other) noexcept = default; + ~UnivariateCoefficientBasis() = default; + UnivariateCoefficientBasis(const UnivariateCoefficientBasis& other) = default; + UnivariateCoefficientBasis(UnivariateCoefficientBasis&& other) noexcept = default; + UnivariateCoefficientBasis& operator=(const UnivariateCoefficientBasis& other) = default; + UnivariateCoefficientBasis& operator=(UnivariateCoefficientBasis&& other) noexcept = default; template - UnivariateMonomial(const UnivariateMonomial& other) + UnivariateCoefficientBasis(const UnivariateCoefficientBasis& other) requires(domain_end > other_domain_end) { coefficients[0] = other.coefficients[0]; @@ -75,14 +76,14 @@ template class UnivariateMono size_t size() { return coefficients.size(); }; - // Check if the UnivariateMonomial is identically zero + // Check if the UnivariateCoefficientBasis is identically zero bool is_zero() const requires(LENGTH == 2) { return coefficients[0].is_zero() || coefficients[1].is_zero(); } - // Check if the UnivariateMonomial is identically zero + // Check if the UnivariateCoefficientBasis is identically zero bool is_zero() const requires(LENGTH == 3) { @@ -95,39 +96,39 @@ template class UnivariateMono // Static method for creating a Univariate from a buffer // IMPROVEMENT: Could be made to identically match equivalent methods in e.g. field.hpp. Currently bypasses // unnecessary ::from_buffer call - static UnivariateMonomial serialize_from_buffer(uint8_t const* buffer) + static UnivariateCoefficientBasis serialize_from_buffer(uint8_t const* buffer) { - UnivariateMonomial result; + UnivariateCoefficientBasis result; std::read(buffer, result.coefficients); return result; } - static UnivariateMonomial get_random() + static UnivariateCoefficientBasis get_random() { - auto output = UnivariateMonomial(); + auto output = UnivariateCoefficientBasis(); for (size_t i = 0; i < LENGTH; ++i) { output.value_at(i) = Fr::random_element(); } return output; }; - static UnivariateMonomial zero() + static UnivariateCoefficientBasis zero() { - auto output = UnivariateMonomial(); + auto output = UnivariateCoefficientBasis(); for (size_t i = 0; i != LENGTH; ++i) { output.coefficients[i] = Fr::zero(); } return output; } - static UnivariateMonomial random_element() { return get_random(); }; + static UnivariateCoefficientBasis random_element() { return get_random(); }; - // Operations between UnivariateMonomial and other UnivariateMonomial - bool operator==(const UnivariateMonomial& other) const = default; + // Operations between UnivariateCoefficientBasis and other UnivariateCoefficientBasis + bool operator==(const UnivariateCoefficientBasis& other) const = default; template - UnivariateMonomial& operator+=( - const UnivariateMonomial& other) + UnivariateCoefficientBasis& operator+=( + const UnivariateCoefficientBasis& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` // the output object therefore must have `other_has_a0_plus_a1` set to false. @@ -141,8 +142,8 @@ template class UnivariateMono } template - UnivariateMonomial& operator-=( - const UnivariateMonomial& other) + UnivariateCoefficientBasis& operator-=( + const UnivariateCoefficientBasis& other) { // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` // the output object therefore must have `other_has_a0_plus_a1` set to false. @@ -156,11 +157,11 @@ template class UnivariateMono } template - UnivariateMonomial operator*( - const UnivariateMonomial& other) const + UnivariateCoefficientBasis operator*( + const UnivariateCoefficientBasis& other) const requires(LENGTH == 2) { - UnivariateMonomial result; + UnivariateCoefficientBasis result; // result.coefficients[0] = a0 * a0; // result.coefficients[1] = a1 * a1 result.coefficients[0] = coefficients[0] * other.coefficients[0]; @@ -189,10 +190,10 @@ template class UnivariateMono } template - UnivariateMonomial operator+( - const UnivariateMonomial& other) const + UnivariateCoefficientBasis operator+( + const UnivariateCoefficientBasis& other) const { - UnivariateMonomial res(*this); + UnivariateCoefficientBasis res(*this); // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` // the output object therefore must have `other_has_a0_plus_a1` set to false. // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ @@ -205,10 +206,10 @@ template class UnivariateMono } template - UnivariateMonomial operator-( - const UnivariateMonomial& other) const + UnivariateCoefficientBasis operator-( + const UnivariateCoefficientBasis& other) const { - UnivariateMonomial res(*this); + UnivariateCoefficientBasis res(*this); // if both operands are degree-1, then we do not update coefficients[2], which represents `a1 + a0` // the output object therefore must have `other_has_a0_plus_a1` set to false. // i.e. the input also requires `other_has_a0_plus_a1`, otherwise use `operator+ @@ -220,9 +221,9 @@ template class UnivariateMono return res; } - UnivariateMonomial operator-() const + UnivariateCoefficientBasis operator-() const { - UnivariateMonomial res; + UnivariateCoefficientBasis res; res.coefficients[0] = -coefficients[0]; res.coefficients[1] = -coefficients[1]; if constexpr (domain_end == 3) { @@ -232,10 +233,10 @@ template class UnivariateMono return res; } - UnivariateMonomial sqr() const + UnivariateCoefficientBasis sqr() const requires(LENGTH == 2) { - UnivariateMonomial result; + UnivariateCoefficientBasis result; result.coefficients[0] = coefficients[0].sqr(); result.coefficients[2] = coefficients[1].sqr(); @@ -255,20 +256,20 @@ template class UnivariateMono } // Operations between Univariate and scalar - UnivariateMonomial& operator+=(const Fr& scalar) + UnivariateCoefficientBasis& operator+=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] += scalar; return *this; } - UnivariateMonomial& operator-=(const Fr& scalar) + UnivariateCoefficientBasis& operator-=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] -= scalar; return *this; } - UnivariateMonomial& operator*=(const Fr& scalar) + UnivariateCoefficientBasis& operator*=(const Fr& scalar) requires(!has_a0_plus_a1) { coefficients[0] *= scalar; @@ -279,23 +280,23 @@ template class UnivariateMono return *this; } - UnivariateMonomial operator+(const Fr& scalar) const + UnivariateCoefficientBasis operator+(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateCoefficientBasis res(*this); res += scalar; return res; } - UnivariateMonomial operator-(const Fr& scalar) const + UnivariateCoefficientBasis operator-(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateCoefficientBasis res(*this); res -= scalar; return res; } - UnivariateMonomial operator*(const Fr& scalar) const + UnivariateCoefficientBasis operator*(const Fr& scalar) const { - UnivariateMonomial res(*this); + UnivariateCoefficientBasis res(*this); res.coefficients[0] *= scalar; res.coefficients[1] *= scalar; if constexpr (domain_end == 3) { @@ -305,7 +306,7 @@ template class UnivariateMono } // Output is immediately parsable as a list of integers by Python. - friend std::ostream& operator<<(std::ostream& os, const UnivariateMonomial& u) + friend std::ostream& operator<<(std::ostream& os, const UnivariateCoefficientBasis& u) { os << "["; os << u.coefficients[0] << "," << std::endl; @@ -329,14 +330,14 @@ template class UnivariateMono }; template -inline void read(B& it, UnivariateMonomial& univariate) +inline void read(B& it, UnivariateCoefficientBasis& univariate) { using serialize::read; read(it, univariate.coefficients); } template -inline void write(B& it, UnivariateMonomial const& univariate) +inline void write(B& it, UnivariateCoefficientBasis const& univariate) { using serialize::write; write(it, univariate.coefficients); @@ -346,6 +347,6 @@ inline void write(B& it, UnivariateMonomial cons namespace std { template -struct tuple_size> : std::integral_constant {}; +struct tuple_size> : std::integral_constant {}; } // namespace std diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.test.cpp similarity index 62% rename from barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp rename to barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.test.cpp index b9f92d6b53f..5cd61eda8c2 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate_monomial.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate_coefficient_basis.test.cpp @@ -1,55 +1,55 @@ -#include "univariate_monomial.hpp" +#include "univariate_coefficient_basis.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "univariate.hpp" #include using namespace bb; -template class UnivariateMonomialTest : public testing::Test { +template class UnivariateCoefficientBasisTest : public testing::Test { public: template using UnivariateView = UnivariateView; }; using FieldTypes = testing::Types; -TYPED_TEST_SUITE(UnivariateMonomialTest, FieldTypes); +TYPED_TEST_SUITE(UnivariateCoefficientBasisTest, FieldTypes); -TYPED_TEST(UnivariateMonomialTest, Conversion) +TYPED_TEST(UnivariateCoefficientBasisTest, Conversion) { fr a0 = fr::random_element(); fr a1 = fr::random_element(); Univariate expected({ a0, a1 }); - UnivariateMonomial uni_m(expected); + UnivariateCoefficientBasis uni_m(expected); Univariate result(uni_m); EXPECT_EQ(result, expected); } -TYPED_TEST(UnivariateMonomialTest, Addition) +TYPED_TEST(UnivariateCoefficientBasisTest, Addition) { Univariate f1{ { 1, 2 } }; Univariate f2{ { 3, 4 } }; - UnivariateMonomial f1_m(f1); - UnivariateMonomial f2_m(f2); + UnivariateCoefficientBasis f1_m(f1); + UnivariateCoefficientBasis f2_m(f2); Univariate result(f1_m + f2_m); Univariate expected = f1 + f2; EXPECT_EQ(result, expected); } -TYPED_TEST(UnivariateMonomialTest, Multiplication) +TYPED_TEST(UnivariateCoefficientBasisTest, Multiplication) { Univariate f1({ 1, 2 }); Univariate f2({ 3, 4 }); - UnivariateMonomial f1_m(f1); - UnivariateMonomial f2_m(f2); + UnivariateCoefficientBasis f1_m(f1); + UnivariateCoefficientBasis f2_m(f2); Univariate result(f1_m * f2_m); Univariate expected = (f1.template extend_to<3>()) * (f2.template extend_to<3>()); EXPECT_EQ(result, expected); } -TYPED_TEST(UnivariateMonomialTest, Serialization) +TYPED_TEST(UnivariateCoefficientBasisTest, Serialization) { const size_t LENGTH = 2; std::array evaluations; @@ -60,13 +60,13 @@ TYPED_TEST(UnivariateMonomialTest, Serialization) // Instantiate a Univariate from the evaluations auto univariate = Univariate(evaluations); - UnivariateMonomial univariate_m(univariate); + UnivariateCoefficientBasis univariate_m(univariate); // Serialize univariate to buffer std::vector buffer = univariate_m.to_buffer(); // Deserialize auto deserialized_univariate = - Univariate(UnivariateMonomial::serialize_from_buffer(&buffer[0])); + Univariate(UnivariateCoefficientBasis::serialize_from_buffer(&buffer[0])); for (size_t i = 0; i < LENGTH; ++i) { EXPECT_EQ(univariate.value_at(i), deserialized_univariate.value_at(i)); diff --git a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp index 186678c0567..075d7ec608e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/auxiliary_relation.hpp @@ -115,37 +115,37 @@ template class AuxiliaryRelationImpl { // whereas in ZK Flavors, the accumulator corresponding to RAM consistency sub-relation 1 is the longest using Accumulator = typename std::tuple_element_t<3, ContainerOverSubrelations>; using View = typename Accumulator::View; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; // allows to re-use the values accumulated by accumulators of the sizes smaller or equal to // the size of Accumulator declared above using ShortAccumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using ShortView = typename std::tuple_element_t<0, ContainerOverSubrelations>::View; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - - const auto& eta_m = ParameterMonomialAccumulator(params.eta); - const auto& eta_two_m = ParameterMonomialAccumulator(params.eta_two); - const auto& eta_three_m = ParameterMonomialAccumulator(params.eta_three); - - auto w_1_m = MonomialAccumulator(in.w_l); - auto w_2_m = MonomialAccumulator(in.w_r); - auto w_3_m = MonomialAccumulator(in.w_o); - auto w_4_m = MonomialAccumulator(in.w_4); - auto w_1_shift_m = MonomialAccumulator(in.w_l_shift); - auto w_2_shift_m = MonomialAccumulator(in.w_r_shift); - auto w_3_shift_m = MonomialAccumulator(in.w_o_shift); - auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); - - auto q_1_m = MonomialAccumulator(in.q_l); - auto q_2_m = MonomialAccumulator(in.q_r); - auto q_3_m = MonomialAccumulator(in.q_o); - auto q_4_m = MonomialAccumulator(in.q_4); - auto q_m_m = MonomialAccumulator(in.q_m); - auto q_c_m = MonomialAccumulator(in.q_c); - auto q_arith_m = MonomialAccumulator(in.q_arith); - - auto q_aux_m = MonomialAccumulator(in.q_aux); + using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator; + + const auto& eta_m = ParameterCoefficientAccumulator(params.eta); + const auto& eta_two_m = ParameterCoefficientAccumulator(params.eta_two); + const auto& eta_three_m = ParameterCoefficientAccumulator(params.eta_three); + + auto w_1_m = CoefficientAccumulator(in.w_l); + auto w_2_m = CoefficientAccumulator(in.w_r); + auto w_3_m = CoefficientAccumulator(in.w_o); + auto w_4_m = CoefficientAccumulator(in.w_4); + auto w_1_shift_m = CoefficientAccumulator(in.w_l_shift); + auto w_2_shift_m = CoefficientAccumulator(in.w_r_shift); + auto w_3_shift_m = CoefficientAccumulator(in.w_o_shift); + auto w_4_shift_m = CoefficientAccumulator(in.w_4_shift); + + auto q_1_m = CoefficientAccumulator(in.q_l); + auto q_2_m = CoefficientAccumulator(in.q_r); + auto q_3_m = CoefficientAccumulator(in.q_o); + auto q_4_m = CoefficientAccumulator(in.q_4); + auto q_m_m = CoefficientAccumulator(in.q_m); + auto q_c_m = CoefficientAccumulator(in.q_c); + auto q_arith_m = CoefficientAccumulator(in.q_arith); + + auto q_aux_m = CoefficientAccumulator(in.q_aux); const FF LIMB_SIZE(uint256_t(1) << 68); const FF SUBLIMB_SHIFT(uint256_t(1) << 14); @@ -171,11 +171,10 @@ template class AuxiliaryRelationImpl { auto non_native_field_gate_1_m = limb_subproduct; non_native_field_gate_1_m -= (w_3_m + w_4_m); // We transform into ShortAccumulator to extend the degree of `non_native_field_gate_1` beyond degree-2 - // (MonomialAccumulator only supports Monomials of up to degree 2 as it is not efficient to peform higher-degree - // computations in the coefficient basis) - // We use ShortAccumulator instead of Accumulator, because this term is only used in subrelations that have the - // same degree as subrelation `0` (which can be lower than the degree of subrelation `3`, which is how - // `Accumulator` is defined) + // (CoefficientAccumulator only supports Monomials of up to degree 2 as it is not efficient to peform + // higher-degree computations in the coefficient basis) We use ShortAccumulator instead of Accumulator, because + // this term is only used in subrelations that have the same degree as subrelation `0` (which can be lower than + // the degree of subrelation `3`, which is how `Accumulator` is defined) auto non_native_field_gate_1 = ShortAccumulator(non_native_field_gate_1_m) * ShortAccumulator(q_3_m); auto non_native_field_gate_3_m = limb_subproduct; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 26b3a6400b1..1283b417f68 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -153,11 +153,11 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_inverse_exists(const AllEntities& in) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; const auto is_read_gate = get_read_selector(in); // is this a read gate const auto read_tag_m = - MonomialAccumulator(BusData::read_tags(in)); // does row contain data being read + CoefficientAccumulator(BusData::read_tags(in)); // does row contain data being read const Accumulator read_tag(read_tag_m); return is_read_gate + read_tag - (is_read_gate * read_tag); } @@ -170,10 +170,10 @@ template class DatabusLookupRelationImpl { template static Accumulator get_read_selector(const AllEntities& in) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - auto q_busread = MonomialAccumulator(in.q_busread); - auto column_selector = MonomialAccumulator(BusData::selector(in)); + auto q_busread = CoefficientAccumulator(in.q_busread); + auto column_selector = CoefficientAccumulator(BusData::selector(in)); return Accumulator(q_busread * column_selector); } @@ -185,14 +185,14 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - using ParameterMonomialAccumulator = - typename GetParameterView::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; + using ParameterCoefficientAccumulator = + typename GetParameterView::CoefficientAccumulator; - const auto& id = MonomialAccumulator(in.databus_id); - const auto& value = MonomialAccumulator(BusData::values(in)); - const auto& gamma = ParameterMonomialAccumulator(params.gamma); - const auto& beta = ParameterMonomialAccumulator(params.beta); + const auto& id = CoefficientAccumulator(in.databus_id); + const auto& value = CoefficientAccumulator(BusData::values(in)); + const auto& gamma = ParameterCoefficientAccumulator(params.gamma); + const auto& beta = ParameterCoefficientAccumulator(params.beta); // Construct value_i + idx_i*\beta + \gamma return Accumulator(id * beta + value + gamma); // degree 1 @@ -206,16 +206,16 @@ template class DatabusLookupRelationImpl { template static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; using View = typename Accumulator::View; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; + using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator; // Bus value stored in w_1, index into bus column stored in w_2 - const auto& w_1 = MonomialAccumulator(in.w_l); - const auto& w_2 = MonomialAccumulator(in.w_r); - const auto& gamma = ParameterMonomialAccumulator(params.gamma); - const auto& beta = ParameterMonomialAccumulator(params.beta); + const auto& w_1 = CoefficientAccumulator(in.w_l); + const auto& w_2 = CoefficientAccumulator(in.w_r); + const auto& gamma = ParameterCoefficientAccumulator(params.gamma); + const auto& beta = ParameterCoefficientAccumulator(params.beta); // Construct value + index*\beta + \gamma return Accumulator((w_2 * beta) + w_1 + gamma); @@ -288,15 +288,15 @@ template class DatabusLookupRelationImpl { { PROFILE_THIS_NAME("DatabusRead::accumulate"); using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - const auto inverses_m = MonomialAccumulator(BusData::inverses(in)); // Degree 1 + const auto inverses_m = CoefficientAccumulator(BusData::inverses(in)); // Degree 1 Accumulator inverses(inverses_m); - const auto read_counts_m = MonomialAccumulator(BusData::read_counts(in)); // Degree 1 - const auto read_term = compute_read_term(in, params); // Degree 1 (2) - const auto write_term = compute_write_term(in, params); // Degree 1 (2) - const auto inverse_exists = compute_inverse_exists(in); // Degree 2 - const auto read_selector = get_read_selector(in); // Degree 2 + const auto read_counts_m = CoefficientAccumulator(BusData::read_counts(in)); // Degree 1 + const auto read_term = compute_read_term(in, params); // Degree 1 (2) + const auto write_term = compute_write_term(in, params); // Degree 1 (2) + const auto inverse_exists = compute_inverse_exists(in); // Degree 2 + const auto read_selector = get_read_selector(in); // Degree 2 // Determine which pair of subrelations to update based on which bus column is being read constexpr size_t subrel_idx_1 = 2 * bus_idx; diff --git a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp index 7ff51c02ee3..f8153988724 100644 --- a/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/delta_range_constraint_relation.hpp @@ -57,14 +57,14 @@ template class DeltaRangeConstraintRelationImpl { { PROFILE_THIS_NAME("DeltaRange::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - auto w_1 = MonomialAccumulator(in.w_l); - auto w_2 = MonomialAccumulator(in.w_r); - auto w_3 = MonomialAccumulator(in.w_o); - auto w_4 = MonomialAccumulator(in.w_4); - auto w_1_shift = MonomialAccumulator(in.w_l_shift); - auto q_delta_range_m = MonomialAccumulator(in.q_delta_range); + auto w_1 = CoefficientAccumulator(in.w_l); + auto w_2 = CoefficientAccumulator(in.w_r); + auto w_3 = CoefficientAccumulator(in.w_o); + auto w_4 = CoefficientAccumulator(in.w_4); + auto w_1_shift = CoefficientAccumulator(in.w_l_shift); + auto q_delta_range_m = CoefficientAccumulator(in.q_delta_range); auto q_delta_range_scaled_m = q_delta_range_m * scaling_factor; Accumulator q_delta_range_scaled(q_delta_range_scaled_m); diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp index d16c3a4bc5e..355efe8476e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_op_queue_relation.hpp @@ -67,20 +67,20 @@ template class EccOpQueueRelationImpl { { PROFILE_THIS_NAME("EccOp::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - // We skip using the MonomialAccumulator type in this relation, as the overall relation degree is low (deg 3). - // To do a degree-1 multiplication in the coefficient basis requires 3 Fp muls and 4 Fp adds (karatsuba + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; + // We skip using the CoefficientAccumulator type in this relation, as the overall relation degree is low (deg + // 3). To do a degree-1 multiplication in the coefficient basis requires 3 Fp muls and 4 Fp adds (karatsuba // multiplication). But a multiplication of a degree-3 Univariate only requires 3 Fp muls. - // We still cast to MonomialAccumulator so that the degree is extended to degree-3 from degree-1 - auto w_1 = Accumulator(MonomialAccumulator(in.w_l)); - auto w_2 = Accumulator(MonomialAccumulator(in.w_r)); - auto w_3 = Accumulator(MonomialAccumulator(in.w_o)); - auto w_4 = Accumulator(MonomialAccumulator(in.w_4)); - auto op_wire_1 = Accumulator(MonomialAccumulator(in.ecc_op_wire_1)); - auto op_wire_2 = Accumulator(MonomialAccumulator(in.ecc_op_wire_2)); - auto op_wire_3 = Accumulator(MonomialAccumulator(in.ecc_op_wire_3)); - auto op_wire_4 = Accumulator(MonomialAccumulator(in.ecc_op_wire_4)); - auto lagrange_ecc_op = Accumulator(MonomialAccumulator(in.lagrange_ecc_op)); + // We still cast to CoefficientAccumulator so that the degree is extended to degree-3 from degree-1 + auto w_1 = Accumulator(CoefficientAccumulator(in.w_l)); + auto w_2 = Accumulator(CoefficientAccumulator(in.w_r)); + auto w_3 = Accumulator(CoefficientAccumulator(in.w_o)); + auto w_4 = Accumulator(CoefficientAccumulator(in.w_4)); + auto op_wire_1 = Accumulator(CoefficientAccumulator(in.ecc_op_wire_1)); + auto op_wire_2 = Accumulator(CoefficientAccumulator(in.ecc_op_wire_2)); + auto op_wire_3 = Accumulator(CoefficientAccumulator(in.ecc_op_wire_3)); + auto op_wire_4 = Accumulator(CoefficientAccumulator(in.ecc_op_wire_4)); + auto lagrange_ecc_op = Accumulator(CoefficientAccumulator(in.lagrange_ecc_op)); // If lagrange_ecc_op is the indicator for ecc_op_gates, this is the indicator for the complement auto lagrange_by_scaling = lagrange_ecc_op * scaling_factor; diff --git a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp index 24cdc71a8c6..aa2812ec139 100644 --- a/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/elliptic_relation.hpp @@ -60,17 +60,17 @@ template class EllipticRelationImpl { PROFILE_THIS_NAME("Elliptic::accumulate"); using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - auto x_3_m = MonomialAccumulator(in.w_r_shift); - auto y_1_m = MonomialAccumulator(in.w_o); - auto y_2_m = MonomialAccumulator(in.w_4_shift); + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; + auto x_3_m = CoefficientAccumulator(in.w_r_shift); + auto y_1_m = CoefficientAccumulator(in.w_o); + auto y_2_m = CoefficientAccumulator(in.w_4_shift); - auto x_1_m = MonomialAccumulator(in.w_r); - auto x_2_m = MonomialAccumulator(in.w_l_shift); - auto y_3_m = MonomialAccumulator(in.w_o_shift); - auto q_elliptic_m = MonomialAccumulator(in.q_elliptic); - auto q_is_double_m = MonomialAccumulator(in.q_m); - auto q_sign_m = MonomialAccumulator(in.q_l); + auto x_1_m = CoefficientAccumulator(in.w_r); + auto x_2_m = CoefficientAccumulator(in.w_l_shift); + auto y_3_m = CoefficientAccumulator(in.w_o_shift); + auto q_elliptic_m = CoefficientAccumulator(in.q_elliptic); + auto q_is_double_m = CoefficientAccumulator(in.q_m); + auto q_sign_m = CoefficientAccumulator(in.q_l); // we need to efficiently construct the following: // 1. (x2 - x1) diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index 2f39f6460eb..98e3123f658 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -69,18 +69,18 @@ template class LogDerivLookupRelationImpl { template static Accumulator compute_inverse_exists(const AllEntities& in) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - const auto row_has_write = MonomialAccumulator(in.lookup_read_tags); - const auto row_has_read = MonomialAccumulator(in.q_lookup); + const auto row_has_write = CoefficientAccumulator(in.lookup_read_tags); + const auto row_has_read = CoefficientAccumulator(in.q_lookup); return Accumulator(-(row_has_write * row_has_read) + row_has_write + row_has_read); } template static Accumulator lookup_read_counts(const AllEntities& in) { - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - return Accumulator(MonomialAccumulator(in.lookup_read_counts)); + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; + return Accumulator(CoefficientAccumulator(in.lookup_read_counts)); } // Compute table_1 + gamma + table_2 * eta + table_3 * eta_2 + table_4 * eta_3 @@ -89,20 +89,20 @@ template class LogDerivLookupRelationImpl { { using View = typename Accumulator::View; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; static_assert(write_index < WRITE_TERMS); - const auto gamma = ParameterMonomialAccumulator(params.gamma); - const auto eta = ParameterMonomialAccumulator(params.eta); - const auto eta_two = ParameterMonomialAccumulator(params.eta_two); - const auto eta_three = ParameterMonomialAccumulator(params.eta_three); + const auto gamma = ParameterCoefficientAccumulator(params.gamma); + const auto eta = ParameterCoefficientAccumulator(params.eta); + const auto eta_two = ParameterCoefficientAccumulator(params.eta_two); + const auto eta_three = ParameterCoefficientAccumulator(params.eta_three); - auto table_1 = MonomialAccumulator(in.table_1); - auto table_2 = MonomialAccumulator(in.table_2); - auto table_3 = MonomialAccumulator(in.table_3); - auto table_4 = MonomialAccumulator(in.table_4); + auto table_1 = CoefficientAccumulator(in.table_1); + auto table_2 = CoefficientAccumulator(in.table_2); + auto table_3 = CoefficientAccumulator(in.table_3); + auto table_4 = CoefficientAccumulator(in.table_4); auto result = (table_2 * eta) + (table_3 * eta_two) + (table_4 * eta_three); result += table_1; @@ -115,26 +115,26 @@ template class LogDerivLookupRelationImpl { { using View = typename Accumulator::View; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - const auto gamma = ParameterMonomialAccumulator(params.gamma); - const auto eta = ParameterMonomialAccumulator(params.eta); - const auto eta_two = ParameterMonomialAccumulator(params.eta_two); - const auto eta_three = ParameterMonomialAccumulator(params.eta_three); + const auto gamma = ParameterCoefficientAccumulator(params.gamma); + const auto eta = ParameterCoefficientAccumulator(params.eta); + const auto eta_two = ParameterCoefficientAccumulator(params.eta_two); + const auto eta_three = ParameterCoefficientAccumulator(params.eta_three); - auto w_1 = MonomialAccumulator(in.w_l); - auto w_2 = MonomialAccumulator(in.w_r); - auto w_3 = MonomialAccumulator(in.w_o); + auto w_1 = CoefficientAccumulator(in.w_l); + auto w_2 = CoefficientAccumulator(in.w_r); + auto w_3 = CoefficientAccumulator(in.w_o); - auto w_1_shift = MonomialAccumulator(in.w_l_shift); - auto w_2_shift = MonomialAccumulator(in.w_r_shift); - auto w_3_shift = MonomialAccumulator(in.w_o_shift); + auto w_1_shift = CoefficientAccumulator(in.w_l_shift); + auto w_2_shift = CoefficientAccumulator(in.w_r_shift); + auto w_3_shift = CoefficientAccumulator(in.w_o_shift); - auto table_index = MonomialAccumulator(in.q_o); - auto negative_column_1_step_size = MonomialAccumulator(in.q_r); - auto negative_column_2_step_size = MonomialAccumulator(in.q_m); - auto negative_column_3_step_size = MonomialAccumulator(in.q_c); + auto table_index = CoefficientAccumulator(in.q_o); + auto negative_column_1_step_size = CoefficientAccumulator(in.q_r); + auto negative_column_2_step_size = CoefficientAccumulator(in.q_m); + auto negative_column_3_step_size = CoefficientAccumulator(in.q_c); // The wire values for lookup gates are accumulators structured in such a way that the differences w_i - // step_size*w_i_shift result in values present in column i of a corresponding table. See the documentation in @@ -231,15 +231,15 @@ template class LogDerivLookupRelationImpl { using ShortView = typename ShortAccumulator::View; using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; // allows to re-use the values accumulated by the accumulator of the size smaller than // the size of Accumulator declared above - const auto inverses_m = MonomialAccumulator(in.lookup_inverses); // Degree 1 + const auto inverses_m = CoefficientAccumulator(in.lookup_inverses); // Degree 1 const Accumulator inverses(inverses_m); - const auto read_counts_m = MonomialAccumulator(in.lookup_read_counts); // Degree 1 - const auto read_selector_m = MonomialAccumulator(in.q_lookup); // Degree 1 + const auto read_counts_m = CoefficientAccumulator(in.lookup_read_counts); // Degree 1 + const auto read_selector_m = CoefficientAccumulator(in.q_lookup); // Degree 1 const auto inverse_exists = compute_inverse_exists(in); // Degree 2 const auto read_term = compute_read_term(in, params); // Degree 2 (3) diff --git a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp index e4efc0884f8..58438a3c03d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/permutation_relation.hpp @@ -132,25 +132,25 @@ template class UltraPermutationRelationImpl { // Contribution (1) using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; using View = typename Accumulator::View; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; using ParameterView = GetParameterView; - using ParameterMonomialAccumulator = typename ParameterView::MonomialAccumulator; - - const MonomialAccumulator w_1_m(in.w_l); - const MonomialAccumulator w_2_m(in.w_r); - const MonomialAccumulator w_3_m(in.w_o); - const MonomialAccumulator w_4_m(in.w_4); - const MonomialAccumulator id_1_m(in.id_1); - const MonomialAccumulator id_2_m(in.id_2); - const MonomialAccumulator id_3_m(in.id_3); - const MonomialAccumulator id_4_m(in.id_4); - const MonomialAccumulator sigma_1_m(in.sigma_1); - const MonomialAccumulator sigma_2_m(in.sigma_2); - const MonomialAccumulator sigma_3_m(in.sigma_3); - const MonomialAccumulator sigma_4_m(in.sigma_4); - - const ParameterMonomialAccumulator gamma_m(params.gamma); - const ParameterMonomialAccumulator beta_m(params.beta); + using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator; + + const CoefficientAccumulator w_1_m(in.w_l); + const CoefficientAccumulator w_2_m(in.w_r); + const CoefficientAccumulator w_3_m(in.w_o); + const CoefficientAccumulator w_4_m(in.w_4); + const CoefficientAccumulator id_1_m(in.id_1); + const CoefficientAccumulator id_2_m(in.id_2); + const CoefficientAccumulator id_3_m(in.id_3); + const CoefficientAccumulator id_4_m(in.id_4); + const CoefficientAccumulator sigma_1_m(in.sigma_1); + const CoefficientAccumulator sigma_2_m(in.sigma_2); + const CoefficientAccumulator sigma_3_m(in.sigma_3); + const CoefficientAccumulator sigma_4_m(in.sigma_4); + + const ParameterCoefficientAccumulator gamma_m(params.gamma); + const ParameterCoefficientAccumulator beta_m(params.beta); const auto w_1_plus_gamma = w_1_m + gamma_m; const auto w_2_plus_gamma = w_2_m + gamma_m; @@ -187,11 +187,11 @@ template class UltraPermutationRelationImpl { denominator *= Accumulator(t7); denominator *= Accumulator(t8); - const ParameterMonomialAccumulator public_input_delta_m(params.public_input_delta); - const auto z_perm_m = MonomialAccumulator(in.z_perm); - const auto z_perm_shift_m = MonomialAccumulator(in.z_perm_shift); - const auto lagrange_first_m = MonomialAccumulator(in.lagrange_first); - const auto lagrange_last_m = MonomialAccumulator(in.lagrange_last); + const ParameterCoefficientAccumulator public_input_delta_m(params.public_input_delta); + const auto z_perm_m = CoefficientAccumulator(in.z_perm); + const auto z_perm_shift_m = CoefficientAccumulator(in.z_perm_shift); + const auto lagrange_first_m = CoefficientAccumulator(in.lagrange_first); + const auto lagrange_last_m = CoefficientAccumulator(in.lagrange_last); auto public_input_term_m = lagrange_last_m * public_input_delta_m; public_input_term_m += z_perm_shift_m; diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp index 5719455fd1e..9bd988d273f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp @@ -65,20 +65,20 @@ template class Poseidon2ExternalRelationImpl { { PROFILE_THIS_NAME("PoseidonExt::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; - auto w_l = MonomialAccumulator(in.w_l); - auto w_r = MonomialAccumulator(in.w_r); - auto w_o = MonomialAccumulator(in.w_o); - auto w_4 = MonomialAccumulator(in.w_4); - auto w_l_shift = MonomialAccumulator(in.w_l_shift); - auto w_r_shift = MonomialAccumulator(in.w_r_shift); - auto w_o_shift = MonomialAccumulator(in.w_o_shift); - auto w_4_shift = MonomialAccumulator(in.w_4_shift); - auto q_l = MonomialAccumulator(in.q_l); - auto q_r = MonomialAccumulator(in.q_r); - auto q_o = MonomialAccumulator(in.q_o); - auto q_4 = MonomialAccumulator(in.q_4); - auto q_poseidon2_external = MonomialAccumulator(in.q_poseidon2_external); + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; + auto w_l = CoefficientAccumulator(in.w_l); + auto w_r = CoefficientAccumulator(in.w_r); + auto w_o = CoefficientAccumulator(in.w_o); + auto w_4 = CoefficientAccumulator(in.w_4); + auto w_l_shift = CoefficientAccumulator(in.w_l_shift); + auto w_r_shift = CoefficientAccumulator(in.w_r_shift); + auto w_o_shift = CoefficientAccumulator(in.w_o_shift); + auto w_4_shift = CoefficientAccumulator(in.w_4_shift); + auto q_l = CoefficientAccumulator(in.q_l); + auto q_r = CoefficientAccumulator(in.q_r); + auto q_o = CoefficientAccumulator(in.q_o); + auto q_4 = CoefficientAccumulator(in.q_4); + auto q_poseidon2_external = CoefficientAccumulator(in.q_poseidon2_external); // add round constants which are loaded in selectors auto s1 = Accumulator(w_l + q_l); diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp index c737415ba71..8f9d2ec7baa 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp @@ -62,15 +62,15 @@ template class Poseidon2InternalRelationImpl { { PROFILE_THIS_NAME("PoseidonInt::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - auto w_l_m = MonomialAccumulator(in.w_l); - auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); - auto w_r_shift_m = MonomialAccumulator(in.w_r_shift); - auto w_o_shift_m = MonomialAccumulator(in.w_o_shift); - auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); - auto q_l_m = MonomialAccumulator(in.q_l); - auto q_poseidon2_internal_m = MonomialAccumulator(in.q_poseidon2_internal); + auto w_l_m = CoefficientAccumulator(in.w_l); + auto w_l_shift_m = CoefficientAccumulator(in.w_l_shift); + auto w_r_shift_m = CoefficientAccumulator(in.w_r_shift); + auto w_o_shift_m = CoefficientAccumulator(in.w_o_shift); + auto w_4_shift_m = CoefficientAccumulator(in.w_4_shift); + auto q_l_m = CoefficientAccumulator(in.q_l); + auto q_poseidon2_internal_m = CoefficientAccumulator(in.q_poseidon2_internal); // add round constants auto s1 = Accumulator(w_l_m + q_l_m); @@ -79,9 +79,9 @@ template class Poseidon2InternalRelationImpl { auto u1 = s1.sqr(); u1 = u1.sqr(); u1 *= s1; - auto u2_m = MonomialAccumulator(in.w_r); - auto u3_m = MonomialAccumulator(in.w_o); - auto u4_m = MonomialAccumulator(in.w_4); + auto u2_m = CoefficientAccumulator(in.w_r); + auto u3_m = CoefficientAccumulator(in.w_o); + auto u4_m = CoefficientAccumulator(in.w_4); auto q_pos_by_scaling_m = (q_poseidon2_internal_m * scaling_factor); auto q_pos_by_scaling = Accumulator(q_pos_by_scaling_m); diff --git a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp index bfae432f06e..dfb74d3a512 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ultra_arithmetic_relation.hpp @@ -84,26 +84,26 @@ template class UltraArithmeticRelationImpl { { PROFILE_THIS_NAME("Arithmetic::accumulate"); using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using MonomialAccumulator = typename Accumulator::MonomialAccumulator; + using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator; - auto w_l_m = MonomialAccumulator(in.w_l); - auto w_4_m = MonomialAccumulator(in.w_4); - auto q_arith_m = MonomialAccumulator(in.q_arith); - auto q_m_m = MonomialAccumulator(in.q_m); + auto w_l_m = CoefficientAccumulator(in.w_l); + auto w_4_m = CoefficientAccumulator(in.w_4); + auto q_arith_m = CoefficientAccumulator(in.q_arith); + auto q_m_m = CoefficientAccumulator(in.q_m); auto q_arith_sub_1 = q_arith_m - FF(1); auto scaled_q_arith = q_arith_m * scaling_factor; { using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - auto w_4_shift_m = MonomialAccumulator(in.w_4_shift); - auto w_r_m = MonomialAccumulator(in.w_r); - auto w_o_m = MonomialAccumulator(in.w_o); - auto q_l_m = MonomialAccumulator(in.q_l); - auto q_r_m = MonomialAccumulator(in.q_r); - auto q_o_m = MonomialAccumulator(in.q_o); - auto q_4_m = MonomialAccumulator(in.q_4); - auto q_c_m = MonomialAccumulator(in.q_c); + auto w_4_shift_m = CoefficientAccumulator(in.w_4_shift); + auto w_r_m = CoefficientAccumulator(in.w_r); + auto w_o_m = CoefficientAccumulator(in.w_o); + auto q_l_m = CoefficientAccumulator(in.q_l); + auto q_r_m = CoefficientAccumulator(in.q_r); + auto q_o_m = CoefficientAccumulator(in.q_o); + auto q_4_m = CoefficientAccumulator(in.q_4); + auto q_c_m = CoefficientAccumulator(in.q_c); static const FF neg_half = FF(-2).invert(); @@ -116,7 +116,7 @@ template class UltraArithmeticRelationImpl { { using ShortAccumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - auto w_l_shift_m = MonomialAccumulator(in.w_l_shift); + auto w_l_shift_m = CoefficientAccumulator(in.w_l_shift); auto tmp_0 = w_l_m + w_4_m - w_l_shift_m + q_m_m; auto tmp_1 = tmp_0 * (q_arith_m - FF(2)); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index 5d0ebebf851..62a8e989016 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -15,7 +15,7 @@ template class bigfield { public: using View = bigfield; - using MonomialAccumulator = bigfield; + using CoefficientAccumulator = bigfield; using TParams = T; using native = bb::field; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp index da70b430656..f677415a215 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field.hpp @@ -11,7 +11,7 @@ template class bool_t; template class field_t { public: using View = field_t; - using MonomialAccumulator = field_t; + using CoefficientAccumulator = field_t; using native = bb::fr; field_t(Builder* parent_context = nullptr); From 2a627df025f9dc90a223f312d2f5c86a9c0af6bd Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Thu, 12 Dec 2024 11:38:17 +0000 Subject: [PATCH 30/30] PR comments --- .../src/barretenberg/polynomials/univariate.hpp | 15 --------------- .../src/barretenberg/ultra_honk/decider_keys.hpp | 4 ++-- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 7eba6ca4410..1840a9204c5 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -102,21 +102,6 @@ template () const - // { - // static_assert(domain_end >= 2); - // static_assert(domain_start == 0); - // // (1 - X)a0 + Xa1 - // // a0 - // if constexpr (skip_count > 0) { - // UnivariateCoefficientBasis result{ .evaluations = { evaluations[0], 0 } }; - // return result; - // } else { - // UnivariateCoefficientBasis 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) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 5252e5726d8..ca8d1aac4e3 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -75,9 +75,9 @@ template struct DeciderProvingKeys_ { typename Flavor::template ProverUnivariates<2> results; // Set the size corresponding to the number of rows in the execution trace // Iterate over the prover polynomials' views corresponding to each proving key - for (size_t dpk_idx = 0; const auto& get_all : prover_polynomials_views) { + for (size_t dpk_idx = 0; const auto& view : prover_polynomials_views) { // Iterate over all columns in the trace execution of a proving key and extract their value at row_idx. - for (auto [result, poly_ptr] : zip_view(results.get_all(), get_all)) { + for (auto [result, poly_ptr] : zip_view(results.get_all(), view)) { result.evaluations[dpk_idx] = poly_ptr[row_idx]; } dpk_idx++;