-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: goblin and eccvm bench (#3606)
Benchmark ECCVM and Goblin. --------- Co-authored-by: ludamad <[email protected]> Co-authored-by: codygunton <[email protected]> Co-authored-by: ledwards2225 <[email protected]>
- Loading branch information
1 parent
e893675
commit 1fe63b2
Showing
19 changed files
with
309 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
barretenberg/cpp/src/barretenberg/benchmark/honk_bench/eccvm.bench.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#include <benchmark/benchmark.h> | ||
|
||
#include "barretenberg/benchmark/honk_bench/benchmark_utilities.hpp" | ||
#include "barretenberg/eccvm/eccvm_composer.hpp" | ||
#include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp" | ||
|
||
using namespace benchmark; | ||
using namespace proof_system; | ||
|
||
using Flavor = honk::flavor::ECCVM; | ||
using Builder = ECCVMCircuitBuilder<Flavor>; | ||
using Composer = honk::ECCVMComposer; | ||
|
||
namespace { | ||
|
||
Builder generate_trace(size_t target_num_gates) | ||
{ | ||
Builder builder; | ||
using G1 = typename Flavor::CycleGroup; | ||
using Fr = typename G1::Fr; | ||
|
||
auto generators = G1::derive_generators("test generators", 2); | ||
|
||
typename G1::element a = generators[0]; | ||
typename G1::element b = generators[1]; | ||
Fr x = Fr::random_element(); | ||
Fr y = Fr::random_element(); | ||
|
||
typename G1::element expected_1 = (a * x) + a + a + (b * y) + (b * x) + (b * x); | ||
|
||
// Each loop adds 163 gates. Note: builder.get_num_gates() is very expensive here (bug?) and it's actually painful | ||
// to use a `while` loop | ||
size_t num_iterations = target_num_gates / 163; | ||
for (size_t _ = 0; _ < num_iterations; _++) { | ||
builder.add_accumulate(a); | ||
builder.mul_accumulate(a, x); | ||
builder.mul_accumulate(b, x); | ||
builder.mul_accumulate(b, y); | ||
builder.add_accumulate(a); | ||
builder.mul_accumulate(b, x); | ||
builder.eq_and_reset(expected_1); | ||
} | ||
return builder; | ||
} | ||
|
||
void eccvm_generate_prover(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
size_t target_num_gates = 1 << static_cast<size_t>(state.range(0)); | ||
for (auto _ : state) { | ||
Builder builder = generate_trace(target_num_gates); | ||
Composer composer; | ||
auto prover = composer.create_prover(builder); | ||
}; | ||
} | ||
|
||
void eccvm_prove(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
size_t target_num_gates = 1 << static_cast<size_t>(state.range(0)); | ||
Builder builder = generate_trace(target_num_gates); | ||
Composer composer; | ||
auto prover = composer.create_prover(builder); | ||
for (auto _ : state) { | ||
auto proof = prover.construct_proof(); | ||
}; | ||
} | ||
|
||
BENCHMARK(eccvm_generate_prover)->Unit(kMillisecond)->DenseRange(10, 20); | ||
BENCHMARK(eccvm_prove)->Unit(kMillisecond)->DenseRange(10, 20); | ||
} // namespace |
137 changes: 137 additions & 0 deletions
137
barretenberg/cpp/src/barretenberg/benchmark/honk_bench/goblin.bench.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
#include "barretenberg/benchmark/honk_bench/benchmark_utilities.hpp" | ||
#include "barretenberg/goblin/goblin.hpp" | ||
#include "barretenberg/goblin/mock_circuits.hpp" | ||
#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" | ||
#include "barretenberg/ultra_honk/ultra_composer.hpp" | ||
|
||
using namespace benchmark; | ||
using namespace barretenberg; | ||
using namespace proof_system; | ||
|
||
namespace { | ||
void goblin_full(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
Goblin goblin; | ||
|
||
// Construct an initial circuit; its proof will be recursively verified by the first kernel | ||
GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); | ||
Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); | ||
|
||
Goblin::Proof proof; | ||
for (auto _ : state) { | ||
// Construct a series of simple Goblin circuits; generate and verify their proofs | ||
size_t NUM_CIRCUITS = 1 << static_cast<size_t>(state.range(0)); | ||
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { | ||
// Construct a circuit with logic resembling that of the "kernel circuit" | ||
GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); | ||
|
||
// Construct proof of the current kernel circuit to be recursively verified by the next one | ||
kernel_input = goblin.accumulate(circuit_builder); | ||
} | ||
|
||
proof = goblin.prove(); | ||
// Verify the final ultra proof | ||
} | ||
honk::GoblinUltraVerifier ultra_verifier{ kernel_input.verification_key }; | ||
ultra_verifier.verify_proof(kernel_input.proof); | ||
// Verify the goblin proof (eccvm, translator, merge) | ||
goblin.verify(proof); | ||
} | ||
|
||
void goblin_accumulate(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
Goblin goblin; | ||
|
||
// Construct an initial circuit; its proof will be recursively verified by the first kernel | ||
GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); | ||
Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); | ||
|
||
// Construct a series of simple Goblin circuits; generate and verify their proofs | ||
size_t NUM_CIRCUITS = 1 << static_cast<size_t>(state.range(0)); | ||
for (auto _ : state) { | ||
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { | ||
// Construct a circuit with logic resembling that of the "kernel circuit" | ||
GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); | ||
|
||
// Construct proof of the current kernel circuit to be recursively verified by the next one | ||
kernel_input = goblin.accumulate(circuit_builder); | ||
} | ||
} | ||
} | ||
|
||
void goblin_eccvm_prove(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
Goblin goblin; | ||
|
||
// Construct an initial circuit; its proof will be recursively verified by the first kernel | ||
GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); | ||
Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); | ||
|
||
// Construct a series of simple Goblin circuits; generate and verify their proofs | ||
size_t NUM_CIRCUITS = 1 << static_cast<size_t>(state.range(0)); | ||
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { | ||
// Construct a circuit with logic resembling that of the "kernel circuit" | ||
GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); | ||
|
||
// Construct proof of the current kernel circuit to be recursively verified by the next one | ||
kernel_input = goblin.accumulate(circuit_builder); | ||
} | ||
|
||
for (auto _ : state) { | ||
goblin.prove_eccvm(); | ||
} | ||
} | ||
|
||
void goblin_translator_prove(State& state) noexcept | ||
{ | ||
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
|
||
Goblin goblin; | ||
|
||
// Construct an initial circuit; its proof will be recursively verified by the first kernel | ||
GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); | ||
Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); | ||
|
||
// Construct a series of simple Goblin circuits; generate and verify their proofs | ||
size_t NUM_CIRCUITS = 1 << static_cast<size_t>(state.range(0)); | ||
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { | ||
// Construct a circuit with logic resembling that of the "kernel circuit" | ||
GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; | ||
GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); | ||
|
||
// Construct proof of the current kernel circuit to be recursively verified by the next one | ||
kernel_input = goblin.accumulate(circuit_builder); | ||
} | ||
|
||
goblin.prove_eccvm(); | ||
for (auto _ : state) { | ||
goblin.prove_translator(); | ||
} | ||
} | ||
|
||
} // namespace | ||
|
||
BENCHMARK(goblin_full)->Unit(kMillisecond)->DenseRange(0, 7); | ||
BENCHMARK(goblin_accumulate)->Unit(kMillisecond)->DenseRange(0, 7); | ||
BENCHMARK(goblin_eccvm_prove)->Unit(kMillisecond)->DenseRange(0, 7); | ||
BENCHMARK(goblin_translator_prove)->Unit(kMillisecond)->DenseRange(0, 7); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.