From f753819817b8ec8d9856411b0b7630b0a495ce00 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 7 Aug 2024 23:15:32 +0000 Subject: [PATCH 1/9] Basic aztec ivc bench in place (and verifying) --- .../src/barretenberg/benchmark/CMakeLists.txt | 1 + .../benchmark/aztec_ivc_bench/CMakeLists.txt | 1 + .../aztec_ivc_bench/aztec_ivc.bench.cpp | 162 ++++++++++++++++++ .../arithmetization/arithmetization.hpp | 2 +- .../max_block_size_tracker.hpp | 1 + .../arithmetization/mega_arithmetization.hpp | 20 +++ .../arithmetization/ultra_arithmetization.hpp | 1 + 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/CMakeLists.txt create mode 100644 barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt index e76758ca571..ab990b18d9f 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory(basics_bench) add_subdirectory(decrypt_bench) add_subdirectory(goblin_bench) add_subdirectory(ipa_bench) +add_subdirectory(aztec_ivc_bench) add_subdirectory(client_ivc_bench) add_subdirectory(pippenger_bench) add_subdirectory(plonk_bench) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/CMakeLists.txt new file mode 100644 index 00000000000..e720a99f87e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(aztec_ivc_bench aztec_ivc stdlib_honk_recursion stdlib_sha256 crypto_merkle_tree stdlib_primitives) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp new file mode 100644 index 00000000000..0254a3604e0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -0,0 +1,162 @@ + +#include + +#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; + + // 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"); + } + + static Builder create_mock_circuit(AztecIVC& ivc, size_t log2_num_gates = 16) + { + Builder circuit{ ivc.goblin.op_queue }; + MockCircuits::construct_arithmetic_circuit(circuit, log2_num_gates); + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): We require goblin ops to be added to the + // function circuit because we cannot support zero commtiments. While the builder handles this at + // finalisation stage via the add_gates_to_ensure_all_polys_are_non_zero function for other MegaHonk + // circuits (where we don't explicitly need to add goblin ops), in AztecIVC merge proving happens prior to + // folding where the absense of goblin ecc ops will result in zero commitments. + MockCircuits::construct_goblin_ecc_op_circuit(circuit); + return circuit; + } + + // static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_function_circuits) + // { + // // Populate the set of mock function and kernel circuits to be accumulated in the IVC + // std::vector circuits; + // Builder function_circuit{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + // circuits.emplace_back(function_circuit); + + // for (size_t idx = 1; idx < num_function_circuits; ++idx) { + // Builder function_circuit{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + // circuits.emplace_back(function_circuit); + + // Builder kernel_circuit{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit); + // circuits.emplace_back(kernel_circuit); + // } + + // // Compute and return the verfication keys corresponding to this set of circuits + // return ivc.precompute_folding_verification_keys(circuits); + // } + + class MockCircuitMaker { + public: + size_t circuit_counter = 0; + + Builder create_next_circuit(AztecIVC& ivc) + { + circuit_counter++; + + bool is_kernel = (circuit_counter % 2 == 0); + if (is_kernel) { + // return mock kernel circuit + return create_mock_circuit(ivc); + } else { + // return mock app circuit + return create_mock_circuit(ivc); + } + return Builder(); + } + }; + + /** + * @brief Perform a specified number of function circuit accumulation rounds + * @details + * + * @param NUM_CIRCUITS Number of function circuits to accumulate + */ + static void perform_ivc_accumulation_rounds(size_t NUM_CIRCUITS, AztecIVC& ivc) + { + 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); + } + } + // /** + // * @brief Perform a specified number of function circuit accumulation rounds + // * @details + // * + // * @param NUM_CIRCUITS Number of function circuits to accumulate + // */ + // 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 - 1; ++circuit_idx) { + // Builder circuit; + // { + // BB_OP_COUNT_TIME_NAME("construct_circuits"); + // circuit = mock_circuit_maker.create_next_circuit(ivc); + // } + + // ivc.accumulate(circuit); + // } + // } +}; + +/** + * @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 num_circuits = static_cast(state.range(0)); + + for (auto _ : state) { + perform_ivc_accumulation_rounds(num_circuits, ivc); + } + + bool result = ivc.prove_and_verify(); + if (result) { + info("VERIFIED!"); + } else { + info("failure."); + } +} + +#define ARGS Arg(AztecIVCBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) + +BENCHMARK_REGISTER_F(AztecIVCBench, FullStructured)->Unit(benchmark::kMillisecond)->ARGS; + +} // namespace + +BENCHMARK_MAIN(); diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp index a32d7d83f09..14789bfa263 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp @@ -28,7 +28,7 @@ struct StackTraces { // A set of fixed block size conigurations to be used with the structured execution trace. The actual block sizes // corresponding to these settings are defined in the corresponding arithmetization classes (Ultra/Mega). For efficiency // it is best to use the smallest possible block sizes to accommodate a given situation. -enum class TraceStructure { NONE, SMALL_TEST, CLIENT_IVC_BENCH, E2E_FULL_TEST }; +enum class TraceStructure { NONE, SMALL_TEST, CLIENT_IVC_BENCH, AZTEC_IVC_BENCH, E2E_FULL_TEST }; /** * @brief Basic structure for storing gate data in a builder diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp index b9d1f64f721..20664322391 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp @@ -37,6 +37,7 @@ struct MaxBlockSizeTracker { { info("Minimum required block sizes for structured trace: "); for (auto [label, max_size] : zip_view(block_labels, max_sizes.get())) { + info(label + ": ", max_size); std::cout << std::left << std::setw(20) << (label + ":") << max_size << std::endl; } info(""); diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp index c27a53e8deb..1ecb1875e54 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp @@ -77,6 +77,23 @@ template class MegaArith { } }; + // A minimal structuring specifically tailored to the medium complexity transaction for the AztecIvc benchmark + struct AztecIvcBenchStructuredBlockSizes : public MegaTraceBlocks { + AztecIvcBenchStructuredBlockSizes() + { + this->ecc_op = 1 << 10; + this->pub_inputs = 1 << 7; + this->arithmetic = 1 << 17; + this->delta_range = 1 << 15; + this->elliptic = 1 << 7; + this->aux = 1 << 15; + this->lookup = 1 << 7; + this->busread = 1 << 7; + this->poseidon_external = 1 << 13; + this->poseidon_internal = 1 << 15; + } + }; + // Structuring tailored to the full e2e TS test (TO BE UPDATED ACCORDINGLY) struct E2eStructuredBlockSizes : public MegaTraceBlocks { E2eStructuredBlockSizes() @@ -178,6 +195,9 @@ template class MegaArith { case TraceStructure::CLIENT_IVC_BENCH: fixed_block_sizes = ClientIvcBenchStructuredBlockSizes(); break; + case TraceStructure::AZTEC_IVC_BENCH: + fixed_block_sizes = AztecIvcBenchStructuredBlockSizes(); + break; case TraceStructure::E2E_FULL_TEST: fixed_block_sizes = E2eStructuredBlockSizes(); break; diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/ultra_arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/ultra_arithmetization.hpp index 402ce07f9e0..38d3028300d 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/ultra_arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/ultra_arithmetization.hpp @@ -90,6 +90,7 @@ template class UltraArith { // We don't use Ultra in ClientIvc so no need for anything other than sizing for simple unit tests case TraceStructure::SMALL_TEST: case TraceStructure::CLIENT_IVC_BENCH: + case TraceStructure::AZTEC_IVC_BENCH: case TraceStructure::E2E_FULL_TEST: fixed_block_sizes = SmallTestStructuredBlockSizes(); break; From d22cd858fe9edaffac7adf0eeab8fd34e4fdcf9c Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 8 Aug 2024 15:36:50 +0000 Subject: [PATCH 2/9] verifying with arith circuits and precomputed vks --- .../aztec_ivc_bench/aztec_ivc.bench.cpp | 93 ++++++++----------- 1 file changed, 40 insertions(+), 53 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index 0254a3604e0..2190ae0908c 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -20,6 +20,8 @@ namespace { class AztecIVCBench : public benchmark::Fixture { public: using Builder = MegaCircuitBuilder; + using VerifierInstance = VerifierInstance_; + using Proof = AztecIVC::Proof; // Number of function circuits to accumulate(based on Zacs target numbers) static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6; @@ -44,27 +46,35 @@ class AztecIVCBench : public benchmark::Fixture { return circuit; } - // static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_function_circuits) - // { - // // Populate the set of mock function and kernel circuits to be accumulated in the IVC - // std::vector circuits; - // Builder function_circuit{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - // circuits.emplace_back(function_circuit); + static bool verify_ivc(Proof& proof, AztecIVC& ivc) + { + auto verifier_inst = std::make_shared(ivc.verification_queue[0].instance_vk); + bool verified = ivc.verify(proof, { ivc.verifier_accumulator, verifier_inst }); + + if (verified) { + info("IVC successfully verified!"); + } else { + info("IVC failed to verify."); + } + + return verified; + } + + static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_function_circuits) + { + MockCircuitMaker mock_circuit_maker; - // for (size_t idx = 1; idx < num_function_circuits; ++idx) { - // Builder function_circuit{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - // circuits.emplace_back(function_circuit); + size_t total_num_circuits = num_function_circuits; + // size_t total_num_circuits = num_function_circuits * 2; - // Builder kernel_circuit{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit); - // circuits.emplace_back(kernel_circuit); - // } + std::vector circuits; + for (size_t circuit_idx = 0; circuit_idx < total_num_circuits; ++circuit_idx) { + circuits.emplace_back(mock_circuit_maker.create_next_circuit(ivc)); + } - // // Compute and return the verfication keys corresponding to this set of circuits - // return ivc.precompute_folding_verification_keys(circuits); - // } + // Compute and return the verfication keys corresponding to this set of circuits + return ivc.precompute_folding_verification_keys(circuits); + } class MockCircuitMaker { public: @@ -78,11 +88,9 @@ class AztecIVCBench : public benchmark::Fixture { if (is_kernel) { // return mock kernel circuit return create_mock_circuit(ivc); - } else { - // return mock app circuit - return create_mock_circuit(ivc); } - return Builder(); + // return mock app circuit + return create_mock_circuit(ivc); } }; @@ -92,8 +100,10 @@ class AztecIVCBench : public benchmark::Fixture { * * @param NUM_CIRCUITS Number of function circuits to accumulate */ - static void perform_ivc_accumulation_rounds(size_t NUM_CIRCUITS, AztecIVC& ivc) + 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) { @@ -103,31 +113,9 @@ class AztecIVCBench : public benchmark::Fixture { circuit = mock_circuit_maker.create_next_circuit(ivc); } - ivc.accumulate(circuit); + ivc.accumulate(circuit, precomputed_vks[circuit_idx]); } } - // /** - // * @brief Perform a specified number of function circuit accumulation rounds - // * @details - // * - // * @param NUM_CIRCUITS Number of function circuits to accumulate - // */ - // 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 - 1; ++circuit_idx) { - // Builder circuit; - // { - // BB_OP_COUNT_TIME_NAME("construct_circuits"); - // circuit = mock_circuit_maker.create_next_circuit(ivc); - // } - - // ivc.accumulate(circuit); - // } - // } }; /** @@ -140,17 +128,16 @@ BENCHMARK_DEFINE_F(AztecIVCBench, FullStructured)(benchmark::State& state) ivc.trace_structure = TraceStructure::AZTEC_IVC_BENCH; auto num_circuits = static_cast(state.range(0)); + auto precomputed_vkeys = precompute_verification_keys(ivc, num_circuits); + + Proof proof; for (auto _ : state) { - perform_ivc_accumulation_rounds(num_circuits, ivc); + perform_ivc_accumulation_rounds(num_circuits, ivc, precomputed_vkeys); + proof = ivc.prove(); } - bool result = ivc.prove_and_verify(); - if (result) { - info("VERIFIED!"); - } else { - info("failure."); - } + verify_ivc(proof, ivc); } #define ARGS Arg(AztecIVCBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) From 5111ff95585e6431fa19689ce88ba3f558b7f4b6 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 8 Aug 2024 19:51:50 +0000 Subject: [PATCH 3/9] f yeeaaahhh --- .../src/barretenberg/aztec_ivc/aztec_ivc.cpp | 8 +++++ .../aztec_ivc_bench/aztec_ivc.bench.cpp | 16 ++++++---- .../src/barretenberg/goblin/mock_circuits.hpp | 32 +++++++++++++++++++ .../arithmetization/mega_arithmetization.hpp | 24 ++++++++++---- .../relations/logderiv_lookup_relation.hpp | 4 +-- 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp index eda78fe0b3e..66d03fbcbd9 100644 --- a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp @@ -41,6 +41,11 @@ void AztecIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr(circuit, trace_structure); + info("Circuit count = ", circuit_count); + info("Num gates = ", circuit.get_num_gates()); + info("Circuit size = ", prover_instance->proving_key.circuit_size); + circuit.blocks.summarize(); + // Set the instance verification key from precomputed if available, else compute it if (precomputed_vk) { instance_vk = precomputed_vk; @@ -90,13 +95,16 @@ bool AztecIVC::verify(const Proof& proof, { // Goblin verification (merge, eccvm, translator) GoblinVerifier goblin_verifier{ eccvm_vk, translator_vk }; + info("Verify goblin."); bool goblin_verified = goblin_verifier.verify(proof.goblin_proof); // Decider verification AztecIVC::FoldingVerifier folding_verifier({ accumulator, final_verifier_instance }); + info("Verify fold."); auto verifier_accumulator = folding_verifier.verify_folding_proof(proof.folding_proof); AztecIVC::DeciderVerifier decider_verifier(verifier_accumulator); + info("Verify decider."); bool decision = decider_verifier.verify_proof(proof.decider_proof); return goblin_verified && decision; } diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index 2190ae0908c..c39049c275c 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -83,14 +83,16 @@ class AztecIVCBench : public benchmark::Fixture { Builder create_next_circuit(AztecIVC& ivc) { circuit_counter++; - bool is_kernel = (circuit_counter % 2 == 0); - if (is_kernel) { - // return mock kernel circuit - return create_mock_circuit(ivc); + + 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_function_circuit_new(circuit, use_large_circuit); } - // return mock app circuit - return create_mock_circuit(ivc); + return circuit; } }; @@ -142,7 +144,7 @@ BENCHMARK_DEFINE_F(AztecIVCBench, FullStructured)(benchmark::State& state) #define ARGS Arg(AztecIVCBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) -BENCHMARK_REGISTER_F(AztecIVCBench, FullStructured)->Unit(benchmark::kMillisecond)->ARGS; +BENCHMARK_REGISTER_F(AztecIVCBench, FullStructured)->Unit(benchmark::kMillisecond)->Repetitions(1)->ARGS; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 9e696ae3580..0809aa41df7 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -41,6 +41,38 @@ class GoblinMockCircuits { std::shared_ptr verification_key; }; + /** + * @brief Populate a builder with some arbitrary but nontrivial constraints + * @details Although the details of the circuit constructed here are arbitrary, the intent is to mock something a + * bit more realistic than a circuit comprised entirely of arithmetic gates. E.g. the circuit should respond + * realistically to efforts to parallelize circuit construction. + * + * @param builder + * @param large If true, construct a "large" circuit (2^19), else a medium circuit (2^17) + */ + static void construct_mock_function_circuit_new(MegaBuilder& builder, bool large = false) + { + // Determine number of times to execute the below operations that constitute the mock circuit logic. Note that + // the circuit size does not scale linearly with number of iterations due to e.g. amortization of lookup costs + const size_t NUM_ITERATIONS_LARGE = 12; // results in circuit size 2^19 (502238 gates) + + if (large) { + stdlib::generate_sha256_test_circuit(builder, NUM_ITERATIONS_LARGE); + stdlib::generate_ecdsa_verification_test_circuit(builder, 11); + stdlib::generate_merkle_membership_test_circuit(builder, NUM_ITERATIONS_LARGE); + } else { // Results in circuit size 2^17 when accumulated via ClientIvc + stdlib::generate_sha256_test_circuit(builder, 10); + stdlib::generate_ecdsa_verification_test_circuit(builder, 2); + stdlib::generate_merkle_membership_test_circuit(builder, 10); + } + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): We require goblin ops to be added to the + // function circuit because we cannot support zero commtiments. While the builder handles this at + // ProverInstance creation stage via the add_gates_to_ensure_all_polys_are_non_zero function for other MegaHonk + // circuits (where we don't explicitly need to add goblin ops), in ClientIVC merge proving happens prior to + // folding where the absense of goblin ecc ops will result in zero commitments. + MockCircuits::construct_goblin_ecc_op_circuit(builder); + } /** * @brief Populate a builder with some arbitrary but nontrivial constraints * @details Although the details of the circuit constructed here are arbitrary, the intent is to mock something a diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp index 1ecb1875e54..e304e90a441 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp @@ -83,14 +83,24 @@ template class MegaArith { { this->ecc_op = 1 << 10; this->pub_inputs = 1 << 7; - this->arithmetic = 1 << 17; - this->delta_range = 1 << 15; - this->elliptic = 1 << 7; - this->aux = 1 << 15; - this->lookup = 1 << 7; + this->arithmetic = 187000; + this->delta_range = 90000; + this->elliptic = 9000; + this->aux = 137000; + this->lookup = 72000; this->busread = 1 << 7; - this->poseidon_external = 1 << 13; - this->poseidon_internal = 1 << 15; + this->poseidon_external = 3000; + this->poseidon_internal = 1 << 14; + // this->ecc_op = 1 << 10; + // this->pub_inputs = 1 << 7; + // this->arithmetic = 1 << 18; + // this->delta_range = 1 << 17; + // this->elliptic = 1 << 14; + // this->aux = 1 << 18; + // this->lookup = 1 << 17; + // this->busread = 1 << 7; + // this->poseidon_external = 1 << 13; + // this->poseidon_internal = 1 << 15; } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index 7e39ebc7df8..04aba4c5228 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -35,8 +35,8 @@ template class LogDerivLookupRelationImpl { // TODO(https://github.com/AztecProtocol/barretenberg/issues/1036): Scrutinize these adjustment factors. Counting // degrees suggests the first subrelation should require an adjustment of 2. static constexpr std::array TOTAL_LENGTH_ADJUSTMENTS{ - 1, // inverse construction sub-relation - 1 // log derivative lookup argument sub-relation + 2, // inverse construction sub-relation + 2 // log derivative lookup argument sub-relation }; static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; From 71862ba4ed154a2145a5ba2a97414c69c1ef3406 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 8 Aug 2024 23:19:42 +0000 Subject: [PATCH 4/9] full bench functioning and verifying --- .../aztec_ivc_bench/aztec_ivc.bench.cpp | 57 ++++++++++--------- .../arithmetization/mega_arithmetization.hpp | 10 ---- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index c39049c275c..f20e08f788d 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -32,20 +32,10 @@ class AztecIVCBench : public benchmark::Fixture { bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); } - static Builder create_mock_circuit(AztecIVC& ivc, size_t log2_num_gates = 16) - { - Builder circuit{ ivc.goblin.op_queue }; - MockCircuits::construct_arithmetic_circuit(circuit, log2_num_gates); - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): We require goblin ops to be added to the - // function circuit because we cannot support zero commtiments. While the builder handles this at - // finalisation stage via the add_gates_to_ensure_all_polys_are_non_zero function for other MegaHonk - // circuits (where we don't explicitly need to add goblin ops), in AztecIVC merge proving happens prior to - // folding where the absense of goblin ecc ops will result in zero commitments. - MockCircuits::construct_goblin_ecc_op_circuit(circuit); - return circuit; - } - + /** + * @brief Verify an IVC proof + * + */ static bool verify_ivc(Proof& proof, AztecIVC& ivc) { auto verifier_inst = std::make_shared(ivc.verification_queue[0].instance_vk); @@ -56,34 +46,43 @@ class AztecIVCBench : public benchmark::Fixture { } else { info("IVC failed to verify."); } - return verified; } - static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_function_circuits) + /** + * @brief Precompute the verification keys for the bench given a number of + * + * @param ivc + * @param num_function_circuits + * @return auto + */ + static auto precompute_verification_keys(AztecIVC& ivc, const size_t num_circuits) { MockCircuitMaker mock_circuit_maker; - size_t total_num_circuits = num_function_circuits; - // size_t total_num_circuits = num_function_circuits * 2; - std::vector circuits; - for (size_t circuit_idx = 0; circuit_idx < total_num_circuits; ++circuit_idx) { + 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 verfication keys corresponding to this set of circuits + // Compute and return th 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. + */ class MockCircuitMaker { - public: size_t circuit_counter = 0; + public: Builder create_next_circuit(AztecIVC& ivc) { circuit_counter++; - bool is_kernel = (circuit_counter % 2 == 0); + + 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 @@ -129,22 +128,24 @@ BENCHMARK_DEFINE_F(AztecIVCBench, FullStructured)(benchmark::State& state) AztecIVC ivc; ivc.trace_structure = TraceStructure::AZTEC_IVC_BENCH; - auto num_circuits = static_cast(state.range(0)); - auto precomputed_vkeys = precompute_verification_keys(ivc, num_circuits); + auto total_num_circuits = 2 * static_cast(state.range(0)); // 2x accounts for kernel circuits - Proof proof; + // Precompute the verification keys for the benchmark circuits + auto precomputed_vkeys = precompute_verification_keys(ivc, total_num_circuits); + Proof proof; for (auto _ : state) { - perform_ivc_accumulation_rounds(num_circuits, ivc, precomputed_vkeys); + 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)->Repetitions(1)->ARGS; +BENCHMARK_REGISTER_F(AztecIVCBench, FullStructured)->Unit(benchmark::kMillisecond)->ARGS; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp index e304e90a441..b4fed017d5b 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp @@ -91,16 +91,6 @@ template class MegaArith { this->busread = 1 << 7; this->poseidon_external = 3000; this->poseidon_internal = 1 << 14; - // this->ecc_op = 1 << 10; - // this->pub_inputs = 1 << 7; - // this->arithmetic = 1 << 18; - // this->delta_range = 1 << 17; - // this->elliptic = 1 << 14; - // this->aux = 1 << 18; - // this->lookup = 1 << 17; - // this->busread = 1 << 7; - // this->poseidon_external = 1 << 13; - // this->poseidon_internal = 1 << 15; } }; From 53cd1557c1696d1b12bc0a4c5040d4750f29a578 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 9 Aug 2024 18:37:33 +0000 Subject: [PATCH 5/9] updates to bench and analysis scripts to handle aztec ivc --- .../cpp/scripts/analyze_client_ivc_bench.py | 54 +++++++++++++++---- .../cpp/scripts/benchmark_client_ivc.sh | 29 ++++++---- .../src/barretenberg/aztec_ivc/aztec_ivc.cpp | 11 ++-- .../aztec_ivc_bench/aztec_ivc.bench.cpp | 1 + 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py index 94c66435f46..5cbc9cceb66 100644 --- a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py +++ b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py @@ -1,9 +1,20 @@ import json +import argparse from pathlib import Path -PREFIX = Path("build-op-count-time") -IVC_BENCH_JSON = Path("client_ivc_bench.json") -BENCHMARK = "ClientIVCBench/Full/6" +# Define command-line arguments with defaults +parser = argparse.ArgumentParser(description="Analyze benchmark JSON data.") +parser.add_argument("--json", type=Path, default=Path("client_ivc_bench.json"), help="Benchmark JSON file name.") +parser.add_argument("--benchmark", type=str, default="ClientIVCBench/Full/6", help="Benchmark name to analyze.") +parser.add_argument("--prefix", type=Path, default=Path("build-op-count-time"), help="Prefix path for benchmark files.") +args = parser.parse_args() + +# # Print the received arguments to debug +# print(f"Received arguments:\n JSON file: {args.json}\n Benchmark: {args.benchmark}\n Prefix: {args.prefix}") + +IVC_BENCH_JSON = args.json +BENCHMARK = args.benchmark +PREFIX = args.prefix # Single out an independent set of functions accounting for most of BENCHMARK's real_time to_keep = [ @@ -16,27 +27,52 @@ "TranslatorProver::construct_proof(t)", "Goblin::merge(t)" ] -with open(PREFIX/IVC_BENCH_JSON, "r") as read_file: + +with open(PREFIX / IVC_BENCH_JSON, "r") as read_file: read_result = json.load(read_file) for _bench in read_result["benchmarks"]: if _bench["name"] == BENCHMARK: bench = _bench + +# # Debugging: Check if the BENCHMARK was found +# if 'bench' not in locals(): +# print(f"Error: BENCHMARK '{BENCHMARK}' not found in the JSON file.") +# exit(1) + +# # Debugging: Print all keys in the bench dictionary +# print("Keys in bench:", bench.items()) + bench_components = dict(filter(lambda x: x[0] in to_keep, bench.items())) +# # Debugging: Print bench_components to see what functions were kept +# print("bench_components:", bench_components) + # For each kept time, get the proportion over all kept times. -sum_of_kept_times_ms = sum(float(time) - for _, time in bench_components.items())/1e6 +sum_of_kept_times_ms = sum(float(time) for _, time in bench_components.items()) / 1e6 + +# # Debugging: Check the value of sum_of_kept_times_ms +# print(f"sum_of_kept_times_ms: {sum_of_kept_times_ms} ms") + +# # Check if sum_of_kept_times_ms is zero +# if sum_of_kept_times_ms == 0: +# print("Warning: sum_of_kept_times_ms is zero, leading to division by zero error.") +# exit(1) + max_label_length = max(len(label) for label in to_keep) column = {"function": "function", "ms": "ms", "%": "% sum"} -print( - f"{column['function']:<{max_label_length}}{column['ms']:>8} {column['%']:>8}") +print(f"{column['function']:<{max_label_length}}{column['ms']:>8} {column['%']:>8}") + for key in to_keep: if key not in bench: time_ms = 0 else: - time_ms = bench[key]/1e6 + time_ms = bench[key] / 1e6 + # # Debugging: Check time_ms before division + # print(f"{key}: time_ms = {time_ms} ms") + # print(f"Percentage of sum: {time_ms/sum_of_kept_times_ms:>8.2%}") print(f"{key:<{max_label_length}}{time_ms:>8.0f} {time_ms/sum_of_kept_times_ms:>8.2%}") + # Validate that kept times account for most of the total measured time. total_time_ms = bench["real_time"] totals = '\nTotal time accounted for: {:.0f}ms/{:.0f}ms = {:.2%}' diff --git a/barretenberg/cpp/scripts/benchmark_client_ivc.sh b/barretenberg/cpp/scripts/benchmark_client_ivc.sh index 7991ef87940..0841f4429ba 100755 --- a/barretenberg/cpp/scripts/benchmark_client_ivc.sh +++ b/barretenberg/cpp/scripts/benchmark_client_ivc.sh @@ -1,21 +1,30 @@ #!/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 @@ -23,4 +32,4 @@ 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" diff --git a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp index 66d03fbcbd9..28a8c086b3d 100644 --- a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp @@ -41,10 +41,10 @@ void AztecIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr(circuit, trace_structure); - info("Circuit count = ", circuit_count); - info("Num gates = ", circuit.get_num_gates()); - info("Circuit size = ", prover_instance->proving_key.circuit_size); - circuit.blocks.summarize(); + // info("Circuit count = ", circuit_count); + // info("Num gates = ", circuit.get_num_gates()); + // info("Circuit size = ", prover_instance->proving_key.circuit_size); + // circuit.blocks.summarize(); // Set the instance verification key from precomputed if available, else compute it if (precomputed_vk) { @@ -95,16 +95,13 @@ bool AztecIVC::verify(const Proof& proof, { // Goblin verification (merge, eccvm, translator) GoblinVerifier goblin_verifier{ eccvm_vk, translator_vk }; - info("Verify goblin."); bool goblin_verified = goblin_verifier.verify(proof.goblin_proof); // Decider verification AztecIVC::FoldingVerifier folding_verifier({ accumulator, final_verifier_instance }); - info("Verify fold."); auto verifier_accumulator = folding_verifier.verify_folding_proof(proof.folding_proof); AztecIVC::DeciderVerifier decider_verifier(verifier_accumulator); - info("Verify decider."); bool decision = decider_verifier.verify_proof(proof.decider_proof); return goblin_verified && decision; } diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index f20e08f788d..ba8e88397a2 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -135,6 +135,7 @@ BENCHMARK_DEFINE_F(AztecIVCBench, FullStructured)(benchmark::State& state) 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(); } From 90d0a3c79947839fe1e7f7a6f1c67373ef2f80b5 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 9 Aug 2024 19:37:41 +0000 Subject: [PATCH 6/9] cleanup --- .../cpp/scripts/analyze_client_ivc_bench.py | 25 ------------------- .../src/barretenberg/aztec_ivc/aztec_ivc.cpp | 5 ---- .../max_block_size_tracker.hpp | 1 - 3 files changed, 31 deletions(-) diff --git a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py index 5cbc9cceb66..d949765fca7 100644 --- a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py +++ b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py @@ -9,9 +9,6 @@ parser.add_argument("--prefix", type=Path, default=Path("build-op-count-time"), help="Prefix path for benchmark files.") args = parser.parse_args() -# # Print the received arguments to debug -# print(f"Received arguments:\n JSON file: {args.json}\n Benchmark: {args.benchmark}\n Prefix: {args.prefix}") - IVC_BENCH_JSON = args.json BENCHMARK = args.benchmark PREFIX = args.prefix @@ -34,30 +31,11 @@ if _bench["name"] == BENCHMARK: bench = _bench -# # Debugging: Check if the BENCHMARK was found -# if 'bench' not in locals(): -# print(f"Error: BENCHMARK '{BENCHMARK}' not found in the JSON file.") -# exit(1) - -# # Debugging: Print all keys in the bench dictionary -# print("Keys in bench:", bench.items()) - bench_components = dict(filter(lambda x: x[0] in to_keep, bench.items())) -# # Debugging: Print bench_components to see what functions were kept -# print("bench_components:", bench_components) - # For each kept time, get the proportion over all kept times. sum_of_kept_times_ms = sum(float(time) for _, time in bench_components.items()) / 1e6 -# # Debugging: Check the value of sum_of_kept_times_ms -# print(f"sum_of_kept_times_ms: {sum_of_kept_times_ms} ms") - -# # Check if sum_of_kept_times_ms is zero -# if sum_of_kept_times_ms == 0: -# print("Warning: sum_of_kept_times_ms is zero, leading to division by zero error.") -# exit(1) - max_label_length = max(len(label) for label in to_keep) column = {"function": "function", "ms": "ms", "%": "% sum"} print(f"{column['function']:<{max_label_length}}{column['ms']:>8} {column['%']:>8}") @@ -67,9 +45,6 @@ time_ms = 0 else: time_ms = bench[key] / 1e6 - # # Debugging: Check time_ms before division - # print(f"{key}: time_ms = {time_ms} ms") - # print(f"Percentage of sum: {time_ms/sum_of_kept_times_ms:>8.2%}") print(f"{key:<{max_label_length}}{time_ms:>8.0f} {time_ms/sum_of_kept_times_ms:>8.2%}") diff --git a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp index 28a8c086b3d..eda78fe0b3e 100644 --- a/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/aztec_ivc/aztec_ivc.cpp @@ -41,11 +41,6 @@ void AztecIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr(circuit, trace_structure); - // info("Circuit count = ", circuit_count); - // info("Num gates = ", circuit.get_num_gates()); - // info("Circuit size = ", prover_instance->proving_key.circuit_size); - // circuit.blocks.summarize(); - // Set the instance verification key from precomputed if available, else compute it if (precomputed_vk) { instance_vk = precomputed_vk; diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp index 20664322391..b9d1f64f721 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/max_block_size_tracker.hpp @@ -37,7 +37,6 @@ struct MaxBlockSizeTracker { { info("Minimum required block sizes for structured trace: "); for (auto [label, max_size] : zip_view(block_labels, max_sizes.get())) { - info(label + ": ", max_size); std::cout << std::left << std::setw(20) << (label + ":") << max_size << std::endl; } info(""); From 0d455290e6a51278db12c472c52db02022ea00a2 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 9 Aug 2024 19:48:21 +0000 Subject: [PATCH 7/9] cleanup, add pinning test --- .../cpp/scripts/analyze_client_ivc_bench.py | 2 -- .../aztec_ivc_bench/aztec_ivc.bench.cpp | 2 +- .../src/barretenberg/goblin/mock_circuits.hpp | 19 ++++++++----------- .../goblin/mock_circuits_pinning.test.cpp | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py index d949765fca7..532079f847e 100644 --- a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py +++ b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py @@ -47,7 +47,6 @@ time_ms = bench[key] / 1e6 print(f"{key:<{max_label_length}}{time_ms:>8.0f} {time_ms/sum_of_kept_times_ms:>8.2%}") - # Validate that kept times account for most of the total measured time. total_time_ms = bench["real_time"] totals = '\nTotal time accounted for: {:.0f}ms/{:.0f}ms = {:.2%}' @@ -81,7 +80,6 @@ total_time_ms = bench["ProtogalaxyProver::fold_instances(t)"]/1e6 print(f"{key:<{max_label_length}}{time_ms:>8.0f} {time_ms/total_time_ms:>8.2%}") - # Extract a set of components from the benchmark data and display timings and relative percentages def print_contributions(prefix, ivc_bench_json, bench_name, components): diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index ba8e88397a2..5bf49a1a927 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -89,7 +89,7 @@ class AztecIVCBench : public benchmark::Fixture { GoblinMockCircuits::construct_mock_folding_kernel(circuit); } else { // construct mock app bool use_large_circuit = (circuit_counter == 1); - GoblinMockCircuits::construct_mock_function_circuit_new(circuit, use_large_circuit); + GoblinMockCircuits::construct_mock_app_circuit(circuit, use_large_circuit); } return circuit; } diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 0809aa41df7..e4cd7435e5a 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -50,17 +50,13 @@ class GoblinMockCircuits { * @param builder * @param large If true, construct a "large" circuit (2^19), else a medium circuit (2^17) */ - static void construct_mock_function_circuit_new(MegaBuilder& builder, bool large = false) + static void construct_mock_app_circuit(MegaBuilder& builder, bool large = false) { - // Determine number of times to execute the below operations that constitute the mock circuit logic. Note that - // the circuit size does not scale linearly with number of iterations due to e.g. amortization of lookup costs - const size_t NUM_ITERATIONS_LARGE = 12; // results in circuit size 2^19 (502238 gates) - - if (large) { - stdlib::generate_sha256_test_circuit(builder, NUM_ITERATIONS_LARGE); + if (large) { // Results in circuit size 2^19 + stdlib::generate_sha256_test_circuit(builder, 12); stdlib::generate_ecdsa_verification_test_circuit(builder, 11); - stdlib::generate_merkle_membership_test_circuit(builder, NUM_ITERATIONS_LARGE); - } else { // Results in circuit size 2^17 when accumulated via ClientIvc + stdlib::generate_merkle_membership_test_circuit(builder, 12); + } else { // Results in circuit size 2^17 stdlib::generate_sha256_test_circuit(builder, 10); stdlib::generate_ecdsa_verification_test_circuit(builder, 2); stdlib::generate_merkle_membership_test_circuit(builder, 10); @@ -69,10 +65,11 @@ class GoblinMockCircuits { // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): We require goblin ops to be added to the // function circuit because we cannot support zero commtiments. While the builder handles this at // ProverInstance creation stage via the add_gates_to_ensure_all_polys_are_non_zero function for other MegaHonk - // circuits (where we don't explicitly need to add goblin ops), in ClientIVC merge proving happens prior to - // folding where the absense of goblin ecc ops will result in zero commitments. + // circuits (where we don't explicitly need to add goblin ops), in IVC merge proving happens prior to folding + // where the absense of goblin ecc ops will result in zero commitments. MockCircuits::construct_goblin_ecc_op_circuit(builder); } + /** * @brief Populate a builder with some arbitrary but nontrivial constraints * @details Although the details of the circuit constructed here are arbitrary, the intent is to mock something a diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp index b37cdd16206..38c14d4b5cb 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp @@ -32,4 +32,21 @@ TEST_F(MegaMockCircuitsPinning, FunctionSizes) }; run_test(true); run_test(false); +} + +TEST_F(MegaMockCircuitsPinning, AppCircuitSizes) +{ + const auto run_test = [](bool large) { + GoblinProver goblin; + MegaCircuitBuilder app_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_app_circuit(app_circuit, large); + auto instance = std::make_shared(app_circuit); + if (large) { + EXPECT_EQ(instance->proving_key.log_circuit_size, 19); + } else { + EXPECT_EQ(instance->proving_key.log_circuit_size, 17); + }; + }; + run_test(true); + run_test(false); } \ No newline at end of file From c96e6c66ef0cc93ccaae8f4aaa1fdfe4defca5eb Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 9 Aug 2024 20:01:21 +0000 Subject: [PATCH 8/9] cleannn --- .../benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp index 5bf49a1a927..a24535ea22b 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/aztec_ivc_bench/aztec_ivc.bench.cpp @@ -41,6 +41,7 @@ class AztecIVCBench : public benchmark::Fixture { auto verifier_inst = std::make_shared(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 { @@ -50,7 +51,7 @@ class AztecIVCBench : public benchmark::Fixture { } /** - * @brief Precompute the verification keys for the bench given a number of + * @brief Precompute the verification keys for the bench given the number of circuits in the IVC * * @param ivc * @param num_function_circuits @@ -58,21 +59,21 @@ class AztecIVCBench : public benchmark::Fixture { */ 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 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 th corresponding set of verfication keys + // 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 are size 2^17. Circuits produced are alternatingly app and kernel. */ class MockCircuitMaker { size_t circuit_counter = 0; @@ -96,10 +97,9 @@ class AztecIVCBench : public benchmark::Fixture { }; /** - * @brief Perform a specified number of function circuit accumulation rounds - * @details + * @brief Perform a specified number of circuit accumulation rounds * - * @param NUM_CIRCUITS Number of function circuits to accumulate + * @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) { From 275837ec95ef974555f5e5b84d93942e437850a3 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 9 Aug 2024 21:11:57 +0000 Subject: [PATCH 9/9] update small app circuit --- barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp | 2 +- .../plonk_honk_shared/arithmetization/mega_arithmetization.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index e4cd7435e5a..e64847a7a0e 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -57,7 +57,7 @@ class GoblinMockCircuits { stdlib::generate_ecdsa_verification_test_circuit(builder, 11); stdlib::generate_merkle_membership_test_circuit(builder, 12); } else { // Results in circuit size 2^17 - stdlib::generate_sha256_test_circuit(builder, 10); + stdlib::generate_sha256_test_circuit(builder, 9); stdlib::generate_ecdsa_verification_test_circuit(builder, 2); stdlib::generate_merkle_membership_test_circuit(builder, 10); } diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp index 0be99734156..8f0e9e35721 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/mega_arithmetization.hpp @@ -90,7 +90,7 @@ template class MegaArith { this->lookup = 72000; this->busread = 1 << 7; this->poseidon_external = 3000; - this->poseidon_internal = 1 << 14; + this->poseidon_internal = 17000; } };