Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
gate_separator.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
12
13#include <cstddef>
14#include <vector>
15namespace bb {
16
17template <typename FF> struct GateSeparatorPolynomial {
22 std::vector<FF> betas;
23
29 std::vector<FF> beta_products;
40 size_t periodicity = 2;
49
56 GateSeparatorPolynomial(const std::vector<FF>& betas, const size_t log_num_monomials)
57 : betas(betas)
58 , beta_products(compute_beta_products(betas, log_num_monomials))
59 {}
60
67 GateSeparatorPolynomial(const std::vector<FF>& betas)
68 : betas(betas)
69 {}
70
76 GateSeparatorPolynomial(const std::vector<FF>& betas, const std::vector<FF>& challenge)
77 : betas(betas)
78 {
79 for (const auto& u_k : challenge) {
81 }
82 }
83
90 FF const& operator[](size_t idx) const { return beta_products[idx]; }
97
101 FF univariate_eval(FF challenge) const { return (FF(1) + (challenge * (betas[current_element_idx] - FF(1)))); };
102
109 void partially_evaluate(FF challenge)
110 {
111 FF current_univariate_eval = univariate_eval(challenge);
112 partial_evaluation_result *= current_univariate_eval;
114 periodicity *= 2;
115 }
116
125 void partially_evaluate(const FF& challenge, const FF& indicator)
126 {
127 FF current_univariate_eval = univariate_eval(challenge);
128 // If dummy round, make no update to the partial_evaluation_result
130 indicator * partial_evaluation_result * current_univariate_eval;
132 periodicity *= 2;
133 }
134
143 BB_PROFILE static std::vector<FF> compute_beta_products(const std::vector<FF>& betas,
144 const size_t log_num_monomials)
145 {
146
147 size_t pow_size = 1 << log_num_monomials;
148 std::vector<FF> beta_products(pow_size);
149
150 // Determine number of threads for multithreading.
151 // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based
152 // on a specified minimum number of iterations per thread. This eventually leads to the use of a single thread.
153 // For now we use a power of 2 number of threads simply to ensure the round size is evenly divided.
154 size_t max_num_threads = get_num_cpus_pow2(); // number of available threads (power of 2)
155 size_t min_iterations_per_thread = 1 << 6; // min number of iterations for which we'll spin up a unique thread
156 size_t desired_num_threads = pow_size / min_iterations_per_thread;
157 size_t num_threads = std::min(desired_num_threads, max_num_threads); // fewer than max if justified
158 num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1
159 size_t iterations_per_thread = pow_size / num_threads; // actual iterations per thread
160
161 // TODO(https://github.com/AztecProtocol/barretenberg/issues/864): This computation is asymtotically slow as it
162 // does pow_size * log(pow_size) work. However, in practice, its super efficient because its trivially
163 // parallelizable and only takes 45ms for the whole 6 iter IVC benchmark. Its also very readable, so we're
164 // leaving it unoptimized for now.
165 parallel_for(num_threads, [&](size_t thread_idx) {
166 size_t start = thread_idx * iterations_per_thread;
167 size_t end = (thread_idx + 1) * iterations_per_thread;
168 for (size_t i = start; i < end; i++) {
169 auto res = FF(1);
170 for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) {
171 if ((j & 1) == 1) {
172 res *= betas[beta_idx];
173 }
174 }
175 beta_products[i] = res;
176 }
177 });
178
179 return beta_products;
180 }
181};
250} // namespace bb
#define BB_PROFILE
Entry point for Barretenberg command-line interface.
size_t get_num_cpus_pow2()
Definition thread.hpp:18
typename Flavor::FF FF
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:72
Implementation of the methods for the -polynomials used in Protogalaxy and -polynomials used in Sumch...
std::vector< FF > beta_products
The consecutive evaluations for identified with the integers .
GateSeparatorPolynomial(const std::vector< FF > &betas)
Construct a new GateSeparatorPolynomial object without expanding to a vector of monomials.
static BB_PROFILE std::vector< FF > compute_beta_products(const std::vector< FF > &betas, const size_t log_num_monomials)
Given compute for .
size_t periodicity
In Round of Sumcheck, the periodicity equals to and represents the fixed interval at which elements...
GateSeparatorPolynomial(const std::vector< FF > &betas, const size_t log_num_monomials)
Construct a new GateSeparatorPolynomial.
std::vector< FF > betas
The challenges .
FF current_element() const
Computes the component at index current_element_idx in betas.
FF const & operator[](size_t idx) const
Retruns the element in beta_products at place #idx.
void partially_evaluate(FF challenge)
Partially evaluate the -polynomial at the new challenge and update .
FF univariate_eval(FF challenge) const
Evaluate at the challenge point .
GateSeparatorPolynomial(const std::vector< FF > &betas, const std::vector< FF > &challenge)
Constructs a virtual GateSeparator used by the prover in rounds k > d - 1, and computes its partial e...
FF partial_evaluation_result
The value obtained by partially evaluating one variable in the power polynomial at each round....
void partially_evaluate(const FF &challenge, const FF &indicator)
Partially evaluate the -polynomial at the new challenge and update .
size_t current_element_idx
In Round of Sumcheck, it points to the -th element in .