Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
commit.bench.cpp
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
12#include <benchmark/benchmark.h>
13
14namespace bb {
15
16template <typename Curve> CommitmentKey<Curve> create_commitment_key(const size_t num_points)
17{
19 std::string srs_path;
20 return CommitmentKey<Curve>(num_points);
21}
22
23// Generate a polynomial with a specified number of nonzero random coefficients
24template <typename FF> Polynomial<FF> sparse_random_poly(const size_t size, const size_t num_nonzero)
25{
27 auto polynomial = Polynomial<FF>(size);
28
29 for (size_t i = 0; i < num_nonzero; i++) {
30 size_t idx = engine.get_random_uint32() % size;
31 polynomial.at(idx) = FF::random_element();
32 }
33
34 return polynomial;
35}
36
41
42// Generate a polynomial with random coefficients organized in isolated blocks. (Mimics the wire polynomials
43// in the structured trace setting, or z_perm if non_zero_complement is set to true).
44template <typename FF> PolyData<FF> structured_random_poly(bool non_zero_complement = false)
45{
46 // An arbitrary but realistic test case taken from the actual structure of a wire in the client_ivc bench
47 std::vector<uint32_t> fixed_sizes = {
48 1 << 10, 1 << 7, 201000, 90000, 9000, 137000, 72000, 1 << 7, 2500, 11500,
49 };
50 std::vector<uint32_t> actual_sizes = {
51 10, 16, 48873, 18209, 4132, 23556, 35443, 3, 2, 2,
52 };
53
54 uint32_t full_size = 0;
55 for (auto size : fixed_sizes) {
56 full_size += size;
57 }
58
59 // In practice the polynomials will have a power-of-2 size
60 auto log2_n = static_cast<size_t>(numeric::get_msb(full_size));
61 if ((1UL << log2_n) != (full_size)) {
62 ++log2_n;
63 }
64 full_size = 1 << log2_n;
65
66 // Construct a polynomial with the prescribed structure; track the "active" regions
67 auto polynomial = Polynomial<FF>(full_size);
68 uint32_t start_idx = 0;
69 uint32_t end_idx = 0;
70 std::vector<std::pair<size_t, size_t>> active_range_endpoints;
71 for (auto [block_size, actual_size] : zip_view(fixed_sizes, actual_sizes)) {
72 end_idx = start_idx + actual_size;
73 for (size_t i = start_idx; i < end_idx; ++i) {
74 polynomial.at(i) = FF::random_element();
75 }
76 active_range_endpoints.emplace_back(start_idx, end_idx);
77 start_idx += block_size;
78 // If indicated, populate the active region complement with a random constant (mimicking z_perm)
79 if (non_zero_complement) {
80 FF const_random_coeff = FF::random_element();
81 for (size_t i = end_idx; i < start_idx; ++i) {
82 polynomial.at(i) = const_random_coeff;
83 }
84 }
85 }
86
87 return { polynomial, active_range_endpoints };
88}
89
90constexpr size_t MIN_LOG_NUM_POINTS = 16;
91constexpr size_t MAX_LOG_NUM_POINTS = 20;
92constexpr size_t MAX_NUM_POINTS = 1 << MAX_LOG_NUM_POINTS;
93constexpr size_t SPARSE_NUM_NONZERO = 100;
94
95// Commit to a zero polynomial
96template <typename Curve> void bench_commit_zero(::benchmark::State& state)
97{
98 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
99
100 const size_t num_points = 1 << state.range(0);
101 const auto polynomial = Polynomial<typename Curve::ScalarField>(num_points);
102 for (auto _ : state) {
103 key.commit(polynomial);
104 }
105}
106
107// Commit to a polynomial with sparse nonzero entries equal to 1
108template <typename Curve> void bench_commit_sparse(::benchmark::State& state)
109{
110 using Fr = typename Curve::ScalarField;
111 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
112
113 const size_t num_points = 1 << state.range(0);
114 const size_t num_nonzero = SPARSE_NUM_NONZERO;
115
116 auto polynomial = Polynomial<Fr>(num_points);
117 for (size_t i = 0; i < num_nonzero; i++) {
118 polynomial.at(i) = 1;
119 }
120
121 for (auto _ : state) {
122 key.commit(polynomial);
123 }
124}
125
126// Commit to a polynomial with sparse nonzero entries equal to 1 using the commit_sparse method to preprocess the input
127template <typename Curve> void bench_commit_sparse_preprocessed(::benchmark::State& state)
128{
129 using Fr = typename Curve::ScalarField;
130 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
131
132 const size_t num_points = 1 << state.range(0);
133 const size_t num_nonzero = SPARSE_NUM_NONZERO;
134
135 auto polynomial = Polynomial<Fr>(num_points);
136 for (size_t i = 0; i < num_nonzero; i++) {
137 polynomial.at(i) = 1;
138 }
139
140 for (auto _ : state) {
141 key.commit(polynomial);
142 }
143}
144
145// Commit to a polynomial with sparse random nonzero entries
146template <typename Curve> void bench_commit_sparse_random(::benchmark::State& state)
147{
148 using Fr = typename Curve::ScalarField;
149 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
150
151 const size_t num_points = 1 << state.range(0);
152 const size_t num_nonzero = SPARSE_NUM_NONZERO;
153
154 auto polynomial = sparse_random_poly<Fr>(num_points, num_nonzero);
155
156 for (auto _ : state) {
157 key.commit(polynomial);
158 }
159}
160
161// Commit to a polynomial with sparse random nonzero entries using the commit_sparse method to preprocess the input
162template <typename Curve> void bench_commit_sparse_random_preprocessed(::benchmark::State& state)
163{
164 using Fr = typename Curve::ScalarField;
165 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
166
167 const size_t num_points = 1 << state.range(0);
168 const size_t num_nonzero = SPARSE_NUM_NONZERO;
169
170 auto polynomial = sparse_random_poly<Fr>(num_points, num_nonzero);
171
172 for (auto _ : state) {
173 key.commit(polynomial);
174 }
175}
176
177// Commit to a polynomial with dense random nonzero entries
178template <typename Curve> void bench_commit_random(::benchmark::State& state)
179{
180 using Fr = typename Curve::ScalarField;
181 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
182
183 const size_t num_points = 1 << state.range(0);
184 Polynomial<Fr> polynomial = Polynomial<Fr>::random(num_points);
185 for (auto _ : state) {
186 key.commit(polynomial);
187 }
188}
189
190// Commit to a polynomial with dense random nonzero entries but NOT our happiest case of an exact power of 2
191// Note this used to be a 50% regression just subtracting a power of 2 by 1.
192template <typename Curve> void bench_commit_random_non_power_of_2(::benchmark::State& state)
193{
194 using Fr = typename Curve::ScalarField;
195 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
196
197 const size_t num_points = 1 << state.range(0);
198 Polynomial<Fr> polynomial = Polynomial<Fr>::random(num_points - 1);
199 for (auto _ : state) {
200 key.commit(polynomial);
201 }
202}
203
204// Commit to a polynomial with block structured random entries using the basic commit method
205template <typename Curve> void bench_commit_structured_random_poly(::benchmark::State& state)
206{
207 using Fr = typename Curve::ScalarField;
208 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
209
210 auto [polynomial, active_range_endpoints] = structured_random_poly<Fr>();
211
212 for (auto _ : state) {
213 key.commit(polynomial);
214 }
215}
216
217// Commit to a polynomial with block structured random entries using commit_structured
218template <typename Curve> void bench_commit_structured_random_poly_preprocessed(::benchmark::State& state)
219{
220 using Fr = typename Curve::ScalarField;
221 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
222
223 auto [polynomial, active_range_endpoints] = structured_random_poly<Fr>();
224
225 for (auto _ : state) {
226 key.commit_structured(polynomial, active_range_endpoints);
227 }
228}
229
230// Commit to a polynomial with block structured random entries and constant valued complement
231template <typename Curve> void bench_commit_mock_z_perm(::benchmark::State& state)
232{
233 using Fr = typename Curve::ScalarField;
234 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
235
236 auto [polynomial, active_range_endpoints] = structured_random_poly<Fr>(/*non_zero_complement=*/true);
237
238 for (auto _ : state) {
239 key.commit(polynomial);
240 }
241}
242
243// Commit to a polynomial with block structured random entries and constant valued complement using tailored method
244template <typename Curve> void bench_commit_mock_z_perm_preprocessed(::benchmark::State& state)
245{
246 using Fr = typename Curve::ScalarField;
247 auto key = create_commitment_key<Curve>(MAX_NUM_POINTS);
248
249 auto [polynomial, active_range_endpoints] = structured_random_poly<Fr>(/*non_zero_complement=*/true);
250
251 for (auto _ : state) {
252 key.commit_structured_with_nonzero_complement(polynomial, active_range_endpoints);
253 }
254}
255
256constexpr size_t MIN_LOG_NUM_GRUMPKIN_POINTS = 12;
257constexpr size_t MAX_LOG_NUM_GRUMPKIN_POINTS = 16;
259
266template <typename Curve> void bench_pippenger_without_endomorphism_basis_points(::benchmark::State& state)
267{
268 using Fr = typename Curve::ScalarField;
269 using Commitment = typename Curve::AffineElement;
270
273
274 for (auto _ : state) {
275 state.PauseTiming();
276 const size_t num_points = 1 << state.range(0);
277 Polynomial<Fr> s_poly = Polynomial<Fr>::random(num_points);
278
279 state.ResumeTiming();
280 std::span<const Commitment> srs_elements = pcs_verification_key->get_monomial_points();
281 std::vector<Commitment> G_vec_local(num_points);
283 num_points, [&](size_t i) { G_vec_local[i] = srs_elements[i * 2]; }, thread_heuristics::FF_COPY_COST * 2);
284
285 // IPA MSM
286 bb::scalar_multiplication::pippenger_unsafe<Curve>(s_poly, { &G_vec_local[0], num_points });
287 }
288}
289
290BENCHMARK(bench_pippenger_without_endomorphism_basis_points<curve::Grumpkin>)
292 ->Unit(benchmark::kMillisecond);
293
294BENCHMARK(bench_commit_zero<curve::BN254>)
296 ->Unit(benchmark::kMillisecond);
297BENCHMARK(bench_commit_sparse<curve::BN254>)
299 ->Unit(benchmark::kMillisecond);
300BENCHMARK(bench_commit_sparse_preprocessed<curve::BN254>)
302 ->Unit(benchmark::kMillisecond);
303BENCHMARK(bench_commit_sparse_random<curve::BN254>)
305 ->Unit(benchmark::kMillisecond);
306BENCHMARK(bench_commit_sparse_random_preprocessed<curve::BN254>)
308 ->Unit(benchmark::kMillisecond);
309BENCHMARK(bench_commit_random<curve::BN254>)
311 ->Unit(benchmark::kMillisecond);
312BENCHMARK(bench_commit_random_non_power_of_2<curve::BN254>)
314 ->Unit(benchmark::kMillisecond);
315BENCHMARK(bench_commit_structured_random_poly<curve::BN254>)->Unit(benchmark::kMillisecond);
316BENCHMARK(bench_commit_structured_random_poly_preprocessed<curve::BN254>)->Unit(benchmark::kMillisecond);
317BENCHMARK(bench_commit_mock_z_perm<curve::BN254>)->Unit(benchmark::kMillisecond);
318BENCHMARK(bench_commit_mock_z_perm_preprocessed<curve::BN254>)->Unit(benchmark::kMillisecond);
319
320} // namespace bb
321
CommitmentKey object over a pairing group 𝔾₁.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
typename Group::affine_element AffineElement
Definition grumpkin.hpp:56
virtual uint32_t get_random_uint32()=0
BENCHMARK_MAIN()
numeric::RNG & engine
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
constexpr size_t FF_COPY_COST
Definition thread.hpp:146
Entry point for Barretenberg command-line interface.
constexpr size_t MAX_NUM_GRUMPKIN_POINTS
CommitmentKey< Curve > create_commitment_key(const size_t num_points)
void bench_commit_structured_random_poly_preprocessed(::benchmark::State &state)
Polynomial< FF > sparse_random_poly(const size_t size, const size_t num_nonzero)
constexpr size_t MAX_LOG_NUM_POINTS
constexpr size_t MIN_LOG_NUM_GRUMPKIN_POINTS
void bench_commit_sparse_random(::benchmark::State &state)
void bench_commit_sparse_random_preprocessed(::benchmark::State &state)
constexpr size_t MAX_LOG_NUM_GRUMPKIN_POINTS
typename Flavor::FF FF
void bench_commit_random_non_power_of_2(::benchmark::State &state)
void bench_commit_random(::benchmark::State &state)
void bench_commit_mock_z_perm_preprocessed(::benchmark::State &state)
constexpr size_t MIN_LOG_NUM_POINTS
constexpr size_t MAX_NUM_POINTS
void bench_commit_mock_z_perm(::benchmark::State &state)
BENCHMARK(vector_of_evaluations) -> DenseRange(15, 21) ->Unit(kMillisecond) ->Iterations(1)
void bench_commit_sparse(::benchmark::State &state)
constexpr size_t SPARSE_NUM_NONZERO
void parallel_for_heuristic(size_t num_points, const std::function< void(size_t, size_t, size_t)> &func, size_t heuristic_cost)
Split a loop into several loops running in parallel based on operations in 1 iteration.
Definition thread.cpp:132
void bench_commit_sparse_preprocessed(::benchmark::State &state)
void bench_commit_zero(::benchmark::State &state)
void bench_commit_structured_random_poly(::benchmark::State &state)
void bench_pippenger_without_endomorphism_basis_points(::benchmark::State &state)
Benchmark pippenger_without_endomorphism_basis_points function, which is used notably in the IPA veri...
PolyData< FF > structured_random_poly(bool non_zero_complement=false)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< std::pair< size_t, size_t > > active_range_endpoints
Polynomial< FF > polynomial
static field random_element(numeric::RNG *engine=nullptr) noexcept