Skip to content
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: New script to output table of benchmarks for README pasting. #2780

Merged
merged 27 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ebf3411
Passing around crs is painful and buggy, leverage the global crs.
charlielye Oct 10, 2023
d3551c8
Stop whinging about this ownership stuff.
charlielye Oct 10, 2023
e67f080
Build circuit to determine size of crs to load.
charlielye Oct 10, 2023
5737a73
Remove redundency in format. Remove composer as member in acir_composer.
charlielye Oct 10, 2023
c42ddf2
Benchmarking acir tests.
charlielye Oct 10, 2023
66ea7af
Builds.
charlielye Oct 10, 2023
9f0987d
Formatting.
charlielye Oct 10, 2023
91ed471
Fix oopsie.
charlielye Oct 10, 2023
982641b
Merge branch 'cl/use_global_crs' into cl/clangd_owning
charlielye Oct 10, 2023
3040789
Merge branch 'cl/clangd_owning' into cl/bb_faster_init
charlielye Oct 10, 2023
ff25df2
use init
charlielye Oct 10, 2023
6842689
Fix.
charlielye Oct 10, 2023
286cc52
Merge branch 'cl/bb_faster_init' into cl/acir_format_cleanup
charlielye Oct 10, 2023
64e811b
Merge branch 'cl/acir_format_cleanup' into cl/bb_bench2
charlielye Oct 10, 2023
99a13b4
Benchmarks.
charlielye Oct 10, 2023
4f3db63
Use throw_or_abort.
charlielye Oct 10, 2023
e2f08f7
Fix.
charlielye Oct 11, 2023
7e5dc9f
Build wasms independently or failures are confusing.
charlielye Oct 11, 2023
2046529
Fix.
charlielye Oct 11, 2023
547d27c
Nice formatting.
charlielye Oct 11, 2023
1b7420e
Units.
charlielye Oct 11, 2023
e2fd5bc
Merge remote-tracking branch 'origin/master' into cl/acir_format_cleanup
charlielye Oct 11, 2023
cbf0631
Merge branch 'cl/acir_format_cleanup' into cl/bb_bench2
charlielye Oct 11, 2023
60db150
Merge branch 'master' into cl/bb_bench2
charlielye Oct 16, 2023
cc62b98
Merge remote-tracking branch 'origin/master' into cl/bb_bench2
charlielye Oct 19, 2023
aa0ace2
Add wasm benchmarks.
charlielye Oct 19, 2023
f7ff882
Merge branch 'cl/bb_bench2' of github.com:aztecprotocol/aztec-package…
charlielye Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions barretenberg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,39 @@ As the spec solidifies, this should be less of an issue. Aztec and Barretenberg

**This code is highly experimental, use at your own risk!**

### Benchmarks!

Table represents time in ms to build circuit and proof for each test on n threads.
Ignores proving key construction.

#### x86_64

```
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
| Test | Gate Count | Subgroup Size | 1 | 4 | 16 | 32 | 64 |
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
| sha256 | 38799 | 65536 | 5947 | 1653 | 729 | 476 | 388 |
| ecdsa_secp256k1 | 41049 | 65536 | 6005 | 2060 | 963 | 693 | 583 |
| ecdsa_secp256r1 | 67331 | 131072 | 12186 | 3807 | 1612 | 1351 | 1137 |
| schnorr | 33740 | 65536 | 5817 | 1696 | 688 | 532 | 432 |
| double_verify_proof | 505513 | 524288 | 47841 | 15824 | 7970 | 6784 | 6082 |
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
```

#### WASM

```
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
| Test | Gate Count | Subgroup Size | 1 | 4 | 16 | 32 | 64 |
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
| sha256 | 38799 | 65536 | 18764 | 5116 | 1854 | 1524 | 1635 |
| ecdsa_secp256k1 | 41049 | 65536 | 19129 | 5595 | 2255 | 2097 | 2166 |
| ecdsa_secp256r1 | 67331 | 131072 | 38815 | 11257 | 4744 | 3633 | 3702 |
| schnorr | 33740 | 65536 | 18649 | 5244 | 2019 | 1498 | 1702 |
| double_verify_proof | 505513 | 524288 | 149652 | 45702 | 20811 | 16979 | 15679 |
+--------------------------+------------+---------------+-----------+-----------+-----------+-----------+-----------+
```

### Dependencies

- cmake >= 3.24
Expand Down
67 changes: 67 additions & 0 deletions barretenberg/acir_tests/bench_acir_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash

TEST_NAMES=("$@")
THREADS=(1 4 16 32 64)
BENCHMARKS=$(mktemp)

if [ "${#TEST_NAMES[@]}" -eq 0 ]; then
TEST_NAMES=(sha256 ecdsa_secp256k1 ecdsa_secp256r1 schnorr double_verify_proof)
fi

for TEST in ${TEST_NAMES[@]}; do
for HC in ${THREADS[@]}; do
HARDWARE_CONCURRENCY=$HC BENCHMARK_FD=3 ./run_acir_tests.sh $TEST 3>>$BENCHMARKS
done
done

# Build results into string with \n delimited rows and space delimited values.
TABLE_DATA=""
for TEST in ${TEST_NAMES[@]}; do
GATE_COUNT=$(jq -r --arg test "$TEST" 'select(.name == "gate_count" and .acir_test == $test) | .value' $BENCHMARKS | uniq)
SUBGROUP_SIZE=$(jq -r --arg test "$TEST" 'select(.name == "subgroup_size" and .acir_test == $test) | .value' $BENCHMARKS | uniq)
# Name in col 1, gate count in col 2, subgroup size in col 3.
TABLE_DATA+="$TEST $GATE_COUNT $SUBGROUP_SIZE"
# Each thread timing in subsequent cols.
for HC in "${THREADS[@]}"; do
RESULT=$(cat $BENCHMARKS | jq -r --arg test "$TEST" --argjson hc $HC 'select(.name == "proof_construction_time" and .acir_test == $test and .threads == $hc) | .value')
TABLE_DATA+=" $RESULT"
done
TABLE_DATA+=$'\n'
done

# Trim the trailing newline.
TABLE_DATA="${TABLE_DATA%$'\n'}"

echo
echo Table represents time in ms to build circuit and proof for each test on n threads.
echo Ignores proving key construction.
echo
# Use awk to print the table
echo -e "$TABLE_DATA" | awk -v threads="${THREADS[*]}" 'BEGIN {
split(threads, t, " ");
len_threads = length(t);
print "+--------------------------+------------+---------------+" genseparator(len_threads);
print "| Test | Gate Count | Subgroup Size |" genthreadheaders(t, len_threads);
print "+--------------------------+------------+---------------+" genseparator(len_threads);
}
{
printf("| %-24s | %-10s | %-13s |", $1, $2, $3);
for (i = 4; i <= len_threads+3; i++) {
printf " %9s |", $(i);
}
print "";
}
END {
print "+--------------------------+------------+---------------+" genseparator(len_threads);
}
function genseparator(len, res) {
for (i = 1; i <= len; i++) res = res "-----------+";
return res;
}
function genthreadheaders(t, len, res) {
for (i = 1; i <= len; i++) res = res sprintf(" %9s |", t[i]);
return res;
}
'

rm $BENCHMARKS
2 changes: 1 addition & 1 deletion barretenberg/acir_tests/flows/prove_and_verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ set -eu
if [ -n "$VERBOSE" ]; then
$BIN prove_and_verify -v -c $CRS_PATH -b ./target/acir.gz
else
$BIN prove_and_verify -c $CRS_PATH -b ./target/acir.gz > /dev/null 2>&1
$BIN prove_and_verify -c $CRS_PATH -b ./target/acir.gz
fi
15 changes: 10 additions & 5 deletions barretenberg/acir_tests/run_acir_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ FLOW=${FLOW:-prove_and_verify}
CRS_PATH=~/.bb-crs
BRANCH="master"
VERBOSE=${VERBOSE:-}
NAMED_TEST=${1:-}
TEST_NAMES=("$@")

FLOW_SCRIPT=$(realpath ./flows/${FLOW}.sh)

Expand Down Expand Up @@ -47,12 +47,15 @@ function test() {
cd $1

set +e
start=$(date +%s%3N)
$FLOW_SCRIPT
result=$?
end=$(date +%s%3N)
duration=$((end - start))
set -eu

if [ $result -eq 0 ]; then
echo -e "\033[32mPASSED\033[0m"
echo -e "\033[32mPASSED\033[0m ($duration ms)"
else
echo -e "\033[31mFAILED\033[0m"
exit 1
Expand All @@ -61,9 +64,11 @@ function test() {
cd ..
}

if [ -n "$NAMED_TEST" ]; then
echo -n "Testing $NAMED_TEST... "
test $NAMED_TEST
if [ "${#TEST_NAMES[@]}" -ne 0 ]; then
for NAMED_TEST in "${TEST_NAMES[@]}"; do
echo -n "Testing $NAMED_TEST... "
test $NAMED_TEST
done
else
for TEST_NAME in $(find -maxdepth 1 -type d -not -path '.' | sed 's|^\./||'); do
echo -n "Testing $TEST_NAME... "
Expand Down
7 changes: 2 additions & 5 deletions barretenberg/cpp/dockerfiles/Dockerfile.wasm-linux-clang
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ WORKDIR /usr/src/barretenberg/cpp
COPY ./scripts/install-wasi-sdk.sh ./scripts/install-wasi-sdk.sh
RUN ./scripts/install-wasi-sdk.sh
COPY . .
# Building both wasm's in parallel reduces build from 120s to 80s.
RUN (cmake --preset wasm && cmake --build --preset wasm) & \
(cmake --preset wasm-threads && cmake --build --preset wasm-threads) & \
wait

RUN cmake --preset wasm && cmake --build --preset wasm
RUN cmake --preset wasm-threads && cmake --build --preset wasm-threads

FROM scratch
WORKDIR /usr/src/barretenberg/cpp
Expand Down
20 changes: 20 additions & 0 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include "barretenberg/dsl/acir_format/acir_format.hpp"
#include "barretenberg/dsl/types.hpp"
#include "config.hpp"
#include "get_bytecode.hpp"
#include "get_crs.hpp"
#include "get_witness.hpp"
#include "log.hpp"
#include <barretenberg/common/benchmark.hpp>
#include <barretenberg/common/container.hpp>
#include <barretenberg/common/timer.hpp>
#include <barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp>
#include <barretenberg/dsl/acir_proofs/acir_composer.hpp>
#include <barretenberg/srs/global_crs.hpp>
Expand All @@ -16,6 +20,9 @@ using namespace barretenberg;
std::string CRS_PATH = "./crs";
bool verbose = false;

const std::filesystem::path current_path = std::filesystem::current_path();
const auto current_dir = current_path.filename().string();

acir_proofs::AcirComposer init(acir_format::acir_format& constraint_system)
{
acir_proofs::AcirComposer acir_composer(0, verbose);
Expand Down Expand Up @@ -69,7 +76,20 @@ bool proveAndVerify(const std::string& bytecodePath, const std::string& witnessP
auto witness = get_witness(witnessPath);
auto acir_composer = init(constraint_system);

Timer pk_timer;
acir_composer.init_proving_key(constraint_system);
write_benchmark("pk_construction_time", pk_timer.milliseconds(), "acir_test", current_dir);
write_benchmark("gate_count", acir_composer.get_total_circuit_size(), "acir_test", current_dir);
write_benchmark("subgroup_size", acir_composer.get_circuit_subgroup_size(), "acir_test", current_dir);

Timer proof_timer;
auto proof = acir_composer.create_proof(constraint_system, witness, recursive);
write_benchmark("proof_construction_time", proof_timer.milliseconds(), "acir_test", current_dir);

Timer vk_timer;
acir_composer.init_verification_key();
write_benchmark("vk_construction_time", vk_timer.milliseconds(), "acir_test", current_dir);

auto verified = acir_composer.verify_proof(proof, recursive);

vinfo("verified: ", verified);
Expand Down
105 changes: 105 additions & 0 deletions barretenberg/cpp/src/barretenberg/common/benchmark.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "barretenberg/common/throw_or_abort.hpp"
#include "barretenberg/env/hardware_concurrency.hpp"
#include <cstdlib>
#include <ctime>
#include <fcntl.h>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>

namespace {
/**
* If user provides the env var BENCHMARK_FD write benchmarks to this fd, otherwise default to -1 (disable).
* e.g:
* BENCHMARK_FD=3 bb 3> benchmarks.jsonl
*/
auto bfd = []() {
try {
static auto bfd_str = std::getenv("BENCHMARK_FD");
int bfd = bfd_str ? (int)std::stoul(bfd_str) : -1;
if (bfd >= 0 && (fcntl(bfd, F_GETFD) == -1 || errno == EBADF)) {
throw_or_abort("fd is not open. Did you redirect in your shell?");
}
return bfd;
} catch (std::exception const& e) {
std::string inner_msg = e.what();
throw_or_abort("Invalid BENCHMARK_FD: " + inner_msg);
}
}();
} // namespace

template <typename T, typename Enable = void> struct TypeTraits;

template <typename T> struct TypeTraits<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> {
static const char* type;
};

template <typename T>
const char* TypeTraits<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>::type = "number";

template <> struct TypeTraits<std::string> {
static const char* type;
};

const char* TypeTraits<std::string>::type = "string";

template <> struct TypeTraits<double> {
static const char* type;
};

const char* TypeTraits<double>::type = "number";

template <> struct TypeTraits<bool> {
static const char* type;
};

const char* TypeTraits<bool>::type = "bool";

// Helper function to get the current timestamp in the desired format
std::string getCurrentTimestamp()
{
std::time_t now = std::time(nullptr);
std::tm* now_tm = std::gmtime(&now);
char buf[21] = { 0 };
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", now_tm);
return std::string(buf);
}

template <typename T> std::string toString(const T& value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}

void appendToStream(std::ostringstream&)
{
// base case: do nothing
}

template <typename K, typename V, typename... Args>
void appendToStream(std::ostringstream& oss, const K& key, const V& value, Args... args)
{
oss << ", \"" << key << "\": \"" << toString(value) << "\"";
appendToStream(oss, args...); // recursively process the remaining arguments
}

template <typename T, typename... Args> void write_benchmark(const std::string& name, const T& value, Args... args)
{
if (bfd == -1) {
return;
}
std::ostringstream oss;
oss << "{\"timestamp\": \"" << getCurrentTimestamp() << "\", "
<< "\"name\": \"" << name << "\", "
<< "\"type\": \"" << TypeTraits<T>::type << "\", "
<< "\"value\": " << value << ", "
<< "\"threads\": " << env_hardware_concurrency();

appendToStream(oss, args...); // unpack and append the key-value pairs

oss << "}" << std::endl;
const std::string& tmp = oss.str();
write((int)bfd, tmp.c_str(), tmp.size());
}
9 changes: 9 additions & 0 deletions barretenberg/cpp/src/barretenberg/common/timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ class Timer {
return nanos;
}

/**
* @brief Return the number of nanoseconds elapsed since the start of the timer.
*/
[[nodiscard]] int64_t milliseconds() const
{
int64_t nanos = nanoseconds();
return nanos / 1000000;
}

/**
* @brief Return the number of seconds elapsed since the start of the timer.
*/
Expand Down
16 changes: 15 additions & 1 deletion barretenberg/cpp/src/barretenberg/env/hardware_concurrency.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
#include "hardware_concurrency.hpp"
#include <barretenberg/common/throw_or_abort.hpp>
#include <cstdlib>
#include <stdexcept>
#include <string>
#include <thread>

extern "C" {

uint32_t env_hardware_concurrency()
{
return std::thread::hardware_concurrency();
#ifndef __wasm__
try {
#endif
static auto val = std::getenv("HARDWARE_CONCURRENCY");
static const uint32_t cores = val ? (uint32_t)std::stoul(val) : std::thread::hardware_concurrency();
return cores;
#ifndef __wasm__
} catch (std::exception const&) {
throw std::runtime_error("HARDWARE_CONCURRENCY invalid.");
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ class UltraComposer {
std::shared_ptr<plonk::proving_key> circuit_proving_key;
std::shared_ptr<plonk::verification_key> circuit_verification_key;

// The crs_factory holds the path to the srs and exposes methods to extract the srs elements

bool computed_witness = false;

// This variable controls the amount with which the lookup table and witness values need to be shifted
Expand Down
Loading