-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Relations vs widgets benchmarking #3931
Changes from all commits
42e79d7
fa092d7
d92c20a
97a8972
e280b26
157b4d5
559cb13
326817d
84a086a
5a50886
d976b8e
e6b70e5
3a8d971
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,15 +3,32 @@ | |
#include "barretenberg/flavor/ultra.hpp" | ||
#include "barretenberg/plonk/composer/standard_composer.hpp" | ||
#include "barretenberg/plonk/composer/ultra_composer.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/random_widgets/plookup_widget.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/transition_widgets/elliptic_widget.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/transition_widgets/genperm_sort_widget.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/transition_widgets/plookup_arithmetic_widget.hpp" | ||
#include "barretenberg/plonk/proof_system/widgets/transition_widgets/plookup_auxiliary_widget.hpp" | ||
#include <benchmark/benchmark.h> | ||
|
||
// The widgets are implemented in a non-uniform way where the transition widgets provide a per-row execution function | ||
// `accumulate_contribution` while the random widgets do not. Defining this preprocessor variable allows to derive a | ||
// per-row exeuction cost that is suitable for comparing against the cost of executing the Honk relations. For | ||
// validation, we also directly benchmark the available `accumulate_contribution` functions. | ||
// | ||
// NOTE: this code is to be run singly threaded via taskset, e.g. taskset -c 0 | ||
// #define GET_PER_ROW_TIME | ||
|
||
namespace { | ||
auto& engine = numeric::random::get_debug_engine(); | ||
} | ||
|
||
namespace proof_system::plonk { | ||
|
||
#ifdef GET_PER_ROW_TIME | ||
constexpr size_t LARGE_DOMAIN_SIZE = 4; | ||
constexpr size_t WIDGET_BENCH_TEST_CIRCUIT_SIZE = 1 << 16; | ||
#endif | ||
|
||
struct BasicPlonkKeyAndTranscript { | ||
std::shared_ptr<proving_key> key; | ||
transcript::StandardTranscript transcript; | ||
|
@@ -22,8 +39,13 @@ BasicPlonkKeyAndTranscript get_plonk_key_and_transcript() | |
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
auto inner_composer = plonk::UltraComposer(); | ||
auto builder = typename plonk::UltraComposer::CircuitBuilder(); | ||
bench_utils::generate_basic_arithmetic_circuit(builder, 80); | ||
bench_utils::generate_basic_arithmetic_circuit(builder, 16); | ||
UltraProver inner_prover = inner_composer.create_prover(builder); | ||
#ifdef GET_PER_ROW_TIME | ||
if (!(inner_prover.key->circuit_size == WIDGET_BENCH_TEST_CIRCUIT_SIZE)) { | ||
throw_or_abort("Circit size changed; update value for accurate benchmarks"); | ||
} | ||
#endif | ||
inner_prover.construct_proof(); | ||
return { inner_composer.circuit_proving_key, inner_prover.transcript }; | ||
} | ||
|
@@ -36,34 +58,59 @@ template <typename Flavor, typename Widget> void execute_widget(::benchmark::Sta | |
widget.compute_quotient_contribution(barretenberg::fr::random_element(), data.transcript); | ||
} | ||
} | ||
void plookup_auxiliary_kernel(::benchmark::State& state) noexcept | ||
|
||
template <typename Widget> void quotient_contribution(::benchmark::State& state) noexcept | ||
{ | ||
BasicPlonkKeyAndTranscript data = get_plonk_key_and_transcript(); | ||
Widget widget(data.key.get()); | ||
for (auto _ : state) { | ||
#ifdef GET_PER_ROW_TIME | ||
auto start = std::chrono::high_resolution_clock::now(); | ||
#endif | ||
widget.compute_quotient_contribution(barretenberg::fr::random_element(), data.transcript); | ||
#ifdef GET_PER_ROW_TIME | ||
auto end = std::chrono::high_resolution_clock::now(); | ||
auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start); | ||
state.SetIterationTime(elapsed_seconds.count() / (LARGE_DOMAIN_SIZE * WIDGET_BENCH_TEST_CIRCUIT_SIZE)); | ||
#endif | ||
} | ||
} | ||
|
||
using FFTGetter = ProverPlookupAuxiliaryWidget<ultra_settings>::FFTGetter; | ||
using FFTKernel = ProverPlookupAuxiliaryWidget<ultra_settings>::FFTKernel; | ||
#ifdef GET_PER_ROW_TIME | ||
BENCHMARK(quotient_contribution<ProverPlookupArithmeticWidget<ultra_settings>>)->Iterations(1)->UseManualTime(); | ||
BENCHMARK(quotient_contribution<ProverGenPermSortWidget<ultra_settings>>)->Iterations(1)->UseManualTime(); | ||
BENCHMARK(quotient_contribution<ProverEllipticWidget<ultra_settings>>)->Iterations(1)->UseManualTime(); | ||
BENCHMARK(quotient_contribution<ProverPlookupAuxiliaryWidget<ultra_settings>>)->Iterations(1)->UseManualTime(); | ||
BENCHMARK(quotient_contribution<ProverPlookupWidget<4>>)->Iterations(1)->UseManualTime(); | ||
BENCHMARK(quotient_contribution<ProverPermutationWidget<4, true>>)->Iterations(1)->UseManualTime(); | ||
#else | ||
BENCHMARK(quotient_contribution<ProverPlookupArithmeticWidget<ultra_settings>>)->Iterations(1); | ||
BENCHMARK(quotient_contribution<ProverGenPermSortWidget<ultra_settings>>)->Iterations(1); | ||
BENCHMARK(quotient_contribution<ProverEllipticWidget<ultra_settings>>)->Iterations(1); | ||
BENCHMARK(quotient_contribution<ProverPlookupAuxiliaryWidget<ultra_settings>>)->Iterations(1); | ||
BENCHMARK(quotient_contribution<ProverPlookupWidget<4>>)->Iterations(1); | ||
BENCHMARK(quotient_contribution<ProverPermutationWidget<4, true>>)->Iterations(1); | ||
#endif | ||
|
||
template <typename Widget> void accumulate_contribution(::benchmark::State& state) noexcept | ||
{ | ||
BasicPlonkKeyAndTranscript data = get_plonk_key_and_transcript(); | ||
|
||
using FFTGetter = typename Widget::FFTGetter; | ||
using FFTKernel = typename Widget::FFTKernel; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't new to this PR but the (hidden) comment below: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed |
||
|
||
auto polynomials = FFTGetter::get_polynomials(data.key.get(), FFTKernel::get_required_polynomial_ids()); | ||
auto challenges = FFTGetter::get_challenges( | ||
data.transcript, barretenberg::fr::random_element(), FFTKernel::quotient_required_challenges); | ||
|
||
for (auto _ : state) { | ||
// NOTE: this simply calls the following 3 functions it does NOT try to replicate ProverPlookupAuxiliaryWidget | ||
// logic exactly | ||
barretenberg::fr result{ 0 }; | ||
FFTKernel::accumulate_contribution(polynomials, challenges, result, 0); | ||
} | ||
} | ||
BENCHMARK(plookup_auxiliary_kernel); | ||
|
||
void plookup_auxiliary_widget(::benchmark::State& state) noexcept | ||
{ | ||
BasicPlonkKeyAndTranscript data = get_plonk_key_and_transcript(); | ||
ProverPlookupAuxiliaryWidget<ultra_settings> widget(data.key.get()); | ||
for (auto _ : state) { | ||
widget.compute_quotient_contribution(barretenberg::fr::random_element(), data.transcript); | ||
} | ||
} | ||
BENCHMARK(plookup_auxiliary_widget); | ||
BENCHMARK(accumulate_contribution<ProverPlookupArithmeticWidget<ultra_settings>>); | ||
BENCHMARK(accumulate_contribution<ProverGenPermSortWidget<ultra_settings>>); | ||
BENCHMARK(accumulate_contribution<ProverEllipticWidget<ultra_settings>>); | ||
BENCHMARK(accumulate_contribution<ProverPlookupAuxiliaryWidget<ultra_settings>>); | ||
|
||
} // namespace proof_system::plonk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale with making them all iterations 1? just that it takes long? (the way I did rounds was pretty inefficient but simpler with how googlebench is setup)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I got impatient while working on it, will revert.