-
Notifications
You must be signed in to change notification settings - Fork 316
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: AztecIvc benchmark suite (#7864)
Adds new benchmark for `AztecIvc` (very similar to the old bench for `ClientIvc`). Bench/analysis scripts updated accordingly (but nothing for `ClientIvc` has been removed yet). `AztecIvc` will soon replace `ClientIvc` altogether. (It might just take over the name 'ClientIvc'). The major difference is that AztecIvc only appends recursive verifiers to kernel circuits, whereas `ClientIvc` appends stuff to every circuit being accumulated (a model that turns out not to work). This is in prep for the model where noir actually specifies recursion via `verify_proof()` calls. `AztecIvc` also incorporates databus consistency checks, which `ClientIvc` does not. The other major difference is that the `AztecIvc` bench now incorporates the $2^{19}$ circuit that was always called for in the 'medium complexity transaction' spec. This significantly increases the bench time but gives us a more realistic picture. The benchmark introduced here is the one that should guide our decision making on optimizations (both memory and computation) moving forward. See comment below for detailed benchmarks and discussion.
- Loading branch information
1 parent
87c940d
commit b7276ab
Showing
10 changed files
with
261 additions
and
21 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,35 @@ | ||
#!/usr/bin/env bash | ||
set -eu | ||
|
||
TARGET="client_ivc_bench" | ||
# Note: to run structured trace version, change "Full" to "FullStructured" here and in analyze script | ||
FILTER="ClientIVCBench/Full/6$" | ||
BUILD_DIR=build-op-count-time | ||
TARGET=${1:-"client_ivc_bench"} | ||
|
||
if [ "$TARGET" = "client_ivc_bench" ]; then | ||
BENCHMARK="ClientIVCBench/Full/6" | ||
elif [ "$TARGET" = "aztec_ivc_bench" ]; then | ||
BENCHMARK="AztecIVCBench/FullStructured/6" | ||
else | ||
echo "Error: Unrecognized TARGET '$TARGET'." | ||
exit 1 | ||
fi | ||
|
||
BUILD_DIR="build-op-count-time" | ||
FILTER="${BENCHMARK}$" # '$' to ensure only specified bench is run | ||
|
||
# Move above script dir. | ||
cd $(dirname $0)/.. | ||
|
||
# Measure the benchmarks with ops time counting | ||
./scripts/benchmark_remote.sh client_ivc_bench\ | ||
"./client_ivc_bench --benchmark_filter=$FILTER\ | ||
--benchmark_out=$TARGET.json\ | ||
--benchmark_out_format=json"\ | ||
./scripts/benchmark_remote.sh "$TARGET"\ | ||
"./$TARGET --benchmark_filter=$FILTER\ | ||
--benchmark_out=$TARGET.json\ | ||
--benchmark_out_format=json"\ | ||
op-count-time\ | ||
build-op-count-time | ||
"$BUILD_DIR" | ||
|
||
# Retrieve output from benching instance | ||
cd $BUILD_DIR | ||
scp $BB_SSH_KEY $BB_SSH_INSTANCE:$BB_SSH_CPP_PATH/build/$TARGET.json . | ||
|
||
# Analyze the results | ||
cd ../ | ||
python3 ./scripts/analyze_client_ivc_bench.py | ||
python3 ./scripts/analyze_client_ivc_bench.py --json "$TARGET.json" --benchmark "$BENCHMARK" --prefix "$BUILD_DIR" |
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
1 change: 1 addition & 0 deletions
1
barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/CMakeLists.txt
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 @@ | ||
barretenberg_module(aztec_ivc_bench aztec_ivc stdlib_honk_recursion stdlib_sha256 crypto_merkle_tree stdlib_primitives) |
153 changes: 153 additions & 0 deletions
153
barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.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,153 @@ | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
#include "barretenberg/aztec_ivc/aztec_ivc.hpp" | ||
#include "barretenberg/common/op_count.hpp" | ||
#include "barretenberg/common/op_count_google_bench.hpp" | ||
#include "barretenberg/goblin/mock_circuits.hpp" | ||
#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" | ||
#include "barretenberg/ultra_honk/ultra_verifier.hpp" | ||
|
||
using namespace benchmark; | ||
using namespace bb; | ||
|
||
namespace { | ||
|
||
/** | ||
* @brief Benchmark suite for the aztec client PG-Goblin IVC scheme | ||
* | ||
*/ | ||
class AztecIVCBench : public benchmark::Fixture { | ||
public: | ||
using Builder = MegaCircuitBuilder; | ||
using VerifierInstance = VerifierInstance_<MegaFlavor>; | ||
using Proof = AztecIVC::Proof; | ||
|
||
// Number of function circuits to accumulate(based on Zacs target numbers) | ||
static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6; | ||
|
||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override | ||
{ | ||
bb::srs::init_crs_factory("../srs_db/ignition"); | ||
bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
} | ||
|
||
/** | ||
* @brief Verify an IVC proof | ||
* | ||
*/ | ||
static bool verify_ivc(Proof& proof, AztecIVC& ivc) | ||
{ | ||
auto verifier_inst = std::make_shared<VerifierInstance>(ivc.verification_queue[0].instance_vk); | ||
bool verified = ivc.verify(proof, { ivc.verifier_accumulator, verifier_inst }); | ||
|
||
// This is a benchmark, not a test, so just print success or failure to the log | ||
if (verified) { | ||
info("IVC successfully verified!"); | ||
} else { | ||
info("IVC failed to verify."); | ||
} | ||
return verified; | ||
} | ||
|
||
/** | ||
* @brief Precompute the verification keys for the bench given the number of circuits in the IVC | ||
* | ||
* @param ivc | ||
* @param num_function_circuits | ||
* @return auto | ||
*/ | ||
static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_circuits) | ||
{ | ||
// Produce the set of mocked circuits to be accumulated | ||
MockCircuitMaker mock_circuit_maker; | ||
std::vector<Builder> circuits; | ||
for (size_t circuit_idx = 0; circuit_idx < num_circuits; ++circuit_idx) { | ||
circuits.emplace_back(mock_circuit_maker.create_next_circuit(ivc)); | ||
} | ||
|
||
// Compute and return the corresponding set of verfication keys | ||
return ivc.precompute_folding_verification_keys(circuits); | ||
} | ||
|
||
/** | ||
* @brief Manage the construction of mock app/kernel circuits | ||
* @details Per the medium complexity benchmark spec, the first app circuit is size 2^19. Subsequent app and kernel | ||
* circuits are size 2^17. Circuits produced are alternatingly app and kernel. | ||
*/ | ||
class MockCircuitMaker { | ||
size_t circuit_counter = 0; | ||
|
||
public: | ||
Builder create_next_circuit(AztecIVC& ivc) | ||
{ | ||
circuit_counter++; | ||
|
||
bool is_kernel = (circuit_counter % 2 == 0); // Every other circuit is a kernel, starting from the second | ||
|
||
Builder circuit{ ivc.goblin.op_queue }; | ||
if (is_kernel) { // construct mock kernel | ||
GoblinMockCircuits::construct_mock_folding_kernel(circuit); | ||
} else { // construct mock app | ||
bool use_large_circuit = (circuit_counter == 1); | ||
GoblinMockCircuits::construct_mock_app_circuit(circuit, use_large_circuit); | ||
} | ||
return circuit; | ||
} | ||
}; | ||
|
||
/** | ||
* @brief Perform a specified number of circuit accumulation rounds | ||
* | ||
* @param NUM_CIRCUITS Number of circuits to accumulate (apps + kernels) | ||
*/ | ||
static void perform_ivc_accumulation_rounds(size_t NUM_CIRCUITS, AztecIVC& ivc, auto& precomputed_vks) | ||
{ | ||
ASSERT(precomputed_vks.size() == NUM_CIRCUITS); // ensure presence of a precomputed VK for each circuit | ||
|
||
MockCircuitMaker mock_circuit_maker; | ||
|
||
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { | ||
Builder circuit; | ||
{ | ||
BB_OP_COUNT_TIME_NAME("construct_circuits"); | ||
circuit = mock_circuit_maker.create_next_circuit(ivc); | ||
} | ||
|
||
ivc.accumulate(circuit, precomputed_vks[circuit_idx]); | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* @brief Benchmark the prover work for the full PG-Goblin IVC protocol | ||
* | ||
*/ | ||
BENCHMARK_DEFINE_F(AztecIVCBench, FullStructured)(benchmark::State& state) | ||
{ | ||
AztecIVC ivc; | ||
ivc.trace_structure = TraceStructure::AZTEC_IVC_BENCH; | ||
|
||
auto total_num_circuits = 2 * static_cast<size_t>(state.range(0)); // 2x accounts for kernel circuits | ||
|
||
// Precompute the verification keys for the benchmark circuits | ||
auto precomputed_vkeys = precompute_verification_keys(ivc, total_num_circuits); | ||
|
||
Proof proof; | ||
for (auto _ : state) { | ||
BB_REPORT_OP_COUNT_IN_BENCH(state); | ||
perform_ivc_accumulation_rounds(total_num_circuits, ivc, precomputed_vkeys); | ||
proof = ivc.prove(); | ||
} | ||
|
||
// For good measure, ensure the IVC verifies | ||
verify_ivc(proof, ivc); | ||
} | ||
|
||
#define ARGS Arg(AztecIVCBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) | ||
|
||
BENCHMARK_REGISTER_F(AztecIVCBench, FullStructured)->Unit(benchmark::kMillisecond)->ARGS; | ||
|
||
} // namespace | ||
|
||
BENCHMARK_MAIN(); |
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
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