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