From 7b00a3afc18c905ee4a667e06bd0d604349e82f2 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 2 May 2023 13:59:12 +0100 Subject: [PATCH 1/4] Add external benchmarks --- .../Dockerfile.x86_64-linux-clang-benchmarks | 23 ++ .../barretenberg/stdlib/hash/CMakeLists.txt | 3 +- .../stdlib/hash/benchmarks/CMakeLists.txt | 2 + .../hash/benchmarks/external/CMakeLists.txt | 1 + .../benchmarks/external/external.bench.cpp | 203 ++++++++++++++++++ .../hash/benchmarks/sha256/CMakeLists.txt | 1 + .../{ => benchmarks}/sha256/sha256.bench.cpp | 2 +- 7 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 cpp/dockerfiles/Dockerfile.x86_64-linux-clang-benchmarks create mode 100644 cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt create mode 100644 cpp/src/barretenberg/stdlib/hash/benchmarks/external/CMakeLists.txt create mode 100644 cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp create mode 100644 cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt rename cpp/src/barretenberg/stdlib/hash/{ => benchmarks}/sha256/sha256.bench.cpp (98%) diff --git a/cpp/dockerfiles/Dockerfile.x86_64-linux-clang-benchmarks b/cpp/dockerfiles/Dockerfile.x86_64-linux-clang-benchmarks new file mode 100644 index 0000000000..af2bec48a9 --- /dev/null +++ b/cpp/dockerfiles/Dockerfile.x86_64-linux-clang-benchmarks @@ -0,0 +1,23 @@ +FROM alpine:3.17 AS builder +RUN apk update \ + && apk upgrade \ + && apk add --no-cache \ + build-base \ + clang15 \ + openmp-dev \ + cmake \ + ninja \ + git \ + curl \ + perl + +WORKDIR /usr/src/barretenberg/cpp + +COPY . . +# Build everything to ensure everything builds. All tests will be run from the result of this build. +RUN cmake --preset default && cmake --build --preset default --target external_bench + +FROM alpine:3.17 +RUN apk update && apk add curl openmp +COPY --from=builder /usr/src/barretenberg/cpp/srs_db /usr/src/barretenberg/cpp/srs_db +COPY --from=builder /usr/src/barretenberg/cpp/build/bin/*_bench /usr/src/barretenberg/cpp/build/bin/ \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/CMakeLists.txt b/cpp/src/barretenberg/stdlib/hash/CMakeLists.txt index c8aaf1e4b4..2ce247a010 100644 --- a/cpp/src/barretenberg/stdlib/hash/CMakeLists.txt +++ b/cpp/src/barretenberg/stdlib/hash/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(blake2s) add_subdirectory(blake3s) add_subdirectory(pedersen) add_subdirectory(sha256) -add_subdirectory(keccak) \ No newline at end of file +add_subdirectory(keccak) +add_subdirectory(benchmarks) \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt b/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt new file mode 100644 index 0000000000..e758f7c8b0 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(sha256) +add_subdirectory(external) \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/CMakeLists.txt b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/CMakeLists.txt new file mode 100644 index 0000000000..2ef6b1656c --- /dev/null +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(external stdlib_primitives crypto_sha256 stdlib_sha256 stdlib_blake3s) \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp new file mode 100644 index 0000000000..583736b516 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp @@ -0,0 +1,203 @@ +/** + * @file external.bench.cpp + * @author Kesha (Rumata888) + * @brief Benchmarks for external benchmarking projects (e.g. delendum-xyz) + * + */ +#include "../../sha256/sha256.hpp" +#include "../../blake3s/blake3s.hpp" +#include +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/plonk/composer/ultra_composer.hpp" +#include "barretenberg/plonk/proof_system/prover/prover.hpp" +#include "barretenberg/stdlib/primitives/packed_byte_array/packed_byte_array.hpp" + +using namespace benchmark; + +using Composer = proof_system::plonk::UltraComposer; +using Prover = proof_system::plonk::UltraProver; +using Verifier = proof_system::plonk::UltraVerifier; + +constexpr size_t PROOF_COUNT_LOG = 10; +constexpr size_t NUM_PROOFS = 3; + +/** + * @brief Main function generating a circuit with num_iterations sequential sha256 hashes, where the output of a + * previous iteration is fed into the next one + * + * @param composer + * @param num_iterations + */ +void generate_test_sha256_plonk_circuit(Composer& composer, size_t num_iterations) +{ + std::string in; + in.resize(32); + for (size_t i = 0; i < 32; ++i) { + in[i] = 0; + } + proof_system::plonk::stdlib::packed_byte_array input(&composer, in); + for (size_t i = 0; i < num_iterations; i++) { + input = proof_system::plonk::stdlib::sha256(input); + } +} +// /** +// * @brief If CPU scaling is disabled, we need to warm up to get an accurate reading on the first benchmark +// * +// * @param state +// */ +// void warm_up(State& state) +// { +// for (auto _ : state) { + +// size_t num_iterations = static_cast(state.range(0)); +// auto composer = Composer(); +// generate_test_sha256_plonk_circuit(composer, num_iterations); +// info("Gate number: ", composer.get_num_gates()); +// auto prover = composer.create_prover(); +// auto proof = prover.construct_proof(); +// info("Proof Size for SHA256 hash count ", num_iterations, ": ", proof.proof_data.size()); +// } +// } + +// BENCHMARK(warm_up)->DenseRange(1, 3); +Composer external_composers[NUM_PROOFS]; +Prover external_provers[NUM_PROOFS]; +Verifier external_verifiers[NUM_PROOFS]; +plonk::proof external_proofs[NUM_PROOFS]; + +/** + * @brief Construct the circuit for sequential sha256 proofs and compute the proof for each case + * + * @param state + */ +void generate_sha256_proof_bench(State& state) noexcept +{ + for (auto _ : state) { + + size_t idx = static_cast(state.range(0)); + size_t num_iterations = 1; + for (size_t i = 0; i < idx; i++) { + num_iterations *= PROOF_COUNT_LOG; + } + external_composers[idx] = Composer(); + generate_test_sha256_plonk_circuit(external_composers[idx], num_iterations); + // info("Gate number: ", external_composers[idx].get_num_gates()); + external_provers[idx] = external_composers[idx].create_prover(); + external_proofs[idx] = external_provers[idx].construct_proof(); + // info("Proof Size for SHA256 hash count ", num_iterations, ": ", external_proofs[idx].proof_data.size()); + } +} + +/** + * @brief We have to warm up the benchmarking function first, otherwise we spend 50% more time than expected + * + */ +BENCHMARK(generate_sha256_proof_bench)->DenseRange(0, 2)->MinWarmUpTime(10)->MinTime(2)->Unit(benchmark::kMillisecond); +/** + * @brief Create sha256 verifier + * + * @details We don't want to benchmark this + * + * @param state + */ +static void generate_sha256_verifier(const State& state) +{ + + size_t idx = static_cast(state.range(0)); + external_verifiers[idx] = external_composers[idx].create_verifier(); +} +/** + * @brief Benchmark sha256 verification + * + * @param state + */ +void verify_sha256_proof_bench(State& state) noexcept +{ + for (auto _ : state) { + + size_t idx = static_cast(state.range(0)); + external_verifiers[idx].verify_proof(external_proofs[idx]); + } +} + +BENCHMARK(verify_sha256_proof_bench)->DenseRange(0, 2)->Setup(generate_sha256_verifier)->Unit(benchmark::kMillisecond); + +/** + * @brief Main function for generating Blake 3 circuits + * + * @param composer + * @param num_iterations + */ +void generate_test_blake3s_plonk_circuit(Composer& composer, size_t num_iterations) +{ + std::string in; + in.resize(32); + for (size_t i = 0; i < 32; ++i) { + in[i] = 0; + } + proof_system::plonk::stdlib::packed_byte_array input(&composer, in); + for (size_t i = 0; i < num_iterations; i++) { + input = proof_system::plonk::stdlib::blake3s(input); + } +} + +/** + * @brief Blake3 circuit construction and proof creation benchmark function + * + * @param state + */ +void generate_blake3s_proof_bench(State& state) noexcept +{ + for (auto _ : state) { + + size_t idx = static_cast(state.range(0)); + size_t num_iterations = 1; + for (size_t i = 0; i < idx; i++) { + num_iterations *= PROOF_COUNT_LOG; + } + external_composers[idx] = Composer(); + generate_test_blake3s_plonk_circuit(external_composers[idx], num_iterations); + // info("Gate number: ", external_composers[idx].get_num_gates()); + external_provers[idx] = external_composers[idx].create_prover(); + external_proofs[idx] = external_provers[idx].construct_proof(); + // Proof size with no public inputs is always 2144 + // info("Proof Size for Blake3s hash count ", num_iterations, ": ", external_proofs[idx].proof_data.size()); + } +} + +BENCHMARK(generate_blake3s_proof_bench)->DenseRange(0, 2)->MinWarmUpTime(10)->MinTime(2)->Unit(benchmark::kMillisecond); + +/** + * @brief Create blake 3 verifier + * + * @details We don't benchmark verifier creation + * + * @param state + */ +static void generate_blake3s_verifier(const State& state) +{ + + size_t idx = static_cast(state.range(0)); + external_verifiers[idx] = external_composers[idx].create_verifier(); +} + +/** + * @brief Benchmark blake3 proof verification + * + * @param state + */ +void verify_blake3s_proof_bench(State& state) noexcept +{ + for (auto _ : state) { + + size_t idx = static_cast(state.range(0)); + external_verifiers[idx].verify_proof(external_proofs[idx]); + } +} + +BENCHMARK(verify_blake3s_proof_bench) + ->DenseRange(0, 2) + ->Setup(generate_blake3s_verifier) + ->Unit(benchmark::kMillisecond); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt new file mode 100644 index 0000000000..e049536e74 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(stdlib_sha256 stdlib_primitives crypto_sha256) \ No newline at end of file diff --git a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/sha256.bench.cpp similarity index 98% rename from cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp rename to cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/sha256.bench.cpp index d912505c44..d33645a8d8 100644 --- a/cpp/src/barretenberg/stdlib/hash/sha256/sha256.bench.cpp +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/sha256.bench.cpp @@ -1,4 +1,4 @@ -#include "sha256.hpp" +#include "../../sha256/sha256.hpp" #include #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/plonk/composer/ultra_composer.hpp" From 88225aa8ac8ee33400bdf267e6188913348e67f1 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 2 May 2023 14:40:41 +0000 Subject: [PATCH 2/4] Fixed forgotten sha256 benchmarks --- .../barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt index e049536e74..f3f408e1fe 100644 --- a/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/sha256/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(stdlib_sha256 stdlib_primitives crypto_sha256) \ No newline at end of file +barretenberg_module(stdlib_sha256_just stdlib_sha256) \ No newline at end of file From 97585c12b98ea8e0560275867a9f6fc78a200383 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 2 May 2023 16:43:24 +0100 Subject: [PATCH 3/4] Deleted some commented-out code --- .../benchmarks/external/external.bench.cpp | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp index 583736b516..2b6d82c7a5 100644 --- a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp @@ -40,26 +40,7 @@ void generate_test_sha256_plonk_circuit(Composer& composer, size_t num_iteration input = proof_system::plonk::stdlib::sha256(input); } } -// /** -// * @brief If CPU scaling is disabled, we need to warm up to get an accurate reading on the first benchmark -// * -// * @param state -// */ -// void warm_up(State& state) -// { -// for (auto _ : state) { - -// size_t num_iterations = static_cast(state.range(0)); -// auto composer = Composer(); -// generate_test_sha256_plonk_circuit(composer, num_iterations); -// info("Gate number: ", composer.get_num_gates()); -// auto prover = composer.create_prover(); -// auto proof = prover.construct_proof(); -// info("Proof Size for SHA256 hash count ", num_iterations, ": ", proof.proof_data.size()); -// } -// } - -// BENCHMARK(warm_up)->DenseRange(1, 3); + Composer external_composers[NUM_PROOFS]; Prover external_provers[NUM_PROOFS]; Verifier external_verifiers[NUM_PROOFS]; From 7b723cc58a5c4938fe8dd1d13d29f679babd69d8 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Fri, 5 May 2023 13:11:12 +0000 Subject: [PATCH 4/4] Remove unneeded info --- .../stdlib/hash/benchmarks/external/external.bench.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp index 2b6d82c7a5..357318bd3d 100644 --- a/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp +++ b/cpp/src/barretenberg/stdlib/hash/benchmarks/external/external.bench.cpp @@ -62,7 +62,6 @@ void generate_sha256_proof_bench(State& state) noexcept } external_composers[idx] = Composer(); generate_test_sha256_plonk_circuit(external_composers[idx], num_iterations); - // info("Gate number: ", external_composers[idx].get_num_gates()); external_provers[idx] = external_composers[idx].create_prover(); external_proofs[idx] = external_provers[idx].construct_proof(); // info("Proof Size for SHA256 hash count ", num_iterations, ": ", external_proofs[idx].proof_data.size()); @@ -138,7 +137,6 @@ void generate_blake3s_proof_bench(State& state) noexcept } external_composers[idx] = Composer(); generate_test_blake3s_plonk_circuit(external_composers[idx], num_iterations); - // info("Gate number: ", external_composers[idx].get_num_gates()); external_provers[idx] = external_composers[idx].create_prover(); external_proofs[idx] = external_provers[idx].construct_proof(); // Proof size with no public inputs is always 2144