Skip to content

Commit 66a61ba

Browse files
ludamadCopilotThunkarmaramihaliledwards2225
authored
feat: no longer recompute vk's in CIVC proofs (#13590)
Apologies for the big PR. Lots of the stuff in here ended up being chicken and egg with wanting to do refactoring to make this process smoother/help debug tricky issues, and wanting to see that those refactorings actually make sense by the end. We no longer compute VKs on the fly in CIVC. This saves ~25% of computation. This is done throughout by consolidating IVC inputs into a single ivc-inputs.msgpack structure which supports passing bytecode, witness & vk information to the bb backend. Now attaches a name for each function, as well. Major features: - IVC inputs passed thru native and wasm are always passed a single file/buffer. This is encoded using msgpack and capture bytecode, witness, vk, and function name (which is now printed, but only properly passed by native) For native, the bincode and witnesses are gzipped, for WASM they are uncompressed. For actions such as gates or write_vk, the IVC inputs are used with same structure but witness and vk data can be blank. This has a bunch of implications, such as having to break away from the rigid API base class in bb cli (which overall doesn't feel worthwhile anyway as CIVC is fundamentally different than UH), having to string vk info along, etc. Other features: Debuggability: - Correct README.md instructions on WASM stack traces (give up on getting line numbers working :/) - clangd now properly shows all errors in a C++ file you're browsing, instead of only showing you the first error. Cleanup - small cleanup to acir tests, but still not testing new ivc flow there. Lightest weight test is ivc-integration in yarn-project - Get rid of --input_type in bb cli for CIVC. now implied always to be what was previously runtime_stack. Simplifies usages, other modes were unused. - more ignored linting in the clangd file. Maybe one day we can enforce the remaining as errors. - Clean up msgpack usage. Msgpack headers were leaking everywhere and it is a chunky library. - Consolidate with using msgpackr as our only typescript messagepack library Benches - use wasmtime helper in bb bootstrap. deduplicate code in bench. bench now honours NATIVE_PRESET, and if you do ``` export NATIVE_PRESET=op-count-time ./bootstrap.sh ./bootstrap.sh bench ``` you will get op count timings for our native ivc benches. --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: thunkar <[email protected]> Co-authored-by: maramihali <[email protected]> Co-authored-by: ledwards2225 <[email protected]>
1 parent 2154d5e commit 66a61ba

File tree

108 files changed

+1261
-1594
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+1261
-1594
lines changed

barretenberg/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ To do a single benchmark you can do e.g.
477477
`IVC_BENCH=amm-add-liquidity ./bootstrap.sh bench_ivc origin/master~3`
478478

479479
If one doesn't provide the commit, it generates these IVC inputs on the fly (depends on yarn-project having been bootstrapped).
480-
To use these inputs manually, just abort after input download and run ClientIVC proving with --input runtime_stack on those inputs (stored in `yarn-project/end-to-end/example-app-ivc-inputs-out`).
480+
To use these inputs manually, just abort after input download and run ClientIVC proving on those inputs (stored in `yarn-project/end-to-end/example-app-ivc-inputs-out`).
481481

482482
#### Using Tracy to Profile Memory/CPU/Gate Counts
483483

@@ -532,7 +532,7 @@ By default, the barretenberg.wasm.gz that is used by bb.js (aka barretenberg/ts)
532532
One can get stack traces working from WASM by running root level ./bootstrap.sh (or otherwise building what you need) and then doing:
533533
```
534534
cmake --build --preset wasm-threads --target barretenberg-debug.wasm.gz
535-
mv build-wasm-threads/barretenberg-debug.wasm.gz build-wasm-threads/barretenberg.wasm.gz
535+
cp build-wasm-threads/bin/barretenberg-debug.wasm.gz ../ts/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz
536536
```
537537

538538
This will mean that any yarn-project or barretenberg/ts tests that run will get stack traces with function names.
@@ -541,5 +541,5 @@ To get more detailed information use the following (NOTE: takes >10 minutes!):
541541
```
542542
cmake --preset wasm-threads-dbg
543543
cmake --build --preset wasm-threads-dbg --target barretenberg-debug.wasm.gz
544-
mv build-wasm-threads-dbg/barretenberg-debug.wasm.gz build-wasm-threads/barretenberg.wasm.gz
544+
cp build-wasm-threads-dbg/bin/barretenberg-debug.wasm.gz ../ts/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz
545545
```

barretenberg/acir_tests/bootstrap.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,6 @@ function run_benchmark {
215215

216216
# TODO(https://github.com/AztecProtocol/barretenberg/issues/1254): More complete testing, including failure tests
217217
function bench {
218-
# TODO(https://github.com/AztecProtocol/barretenberg/issues/1265) fix acir benchmarking
219-
# LOG_FILE=bench-acir.jsonl ./bench_acir_tests.sh
220-
221218
export HARDWARE_CONCURRENCY=16
222219

223220
rm -rf bench-out && mkdir -p bench-out

barretenberg/acir_tests/flows/prove_then_verify.sh

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,6 @@ BFLAG="-b ./target/program.json"
66
FLAGS="-c $CRS_PATH ${VERBOSE:+-v}"
77
[ "${RECURSIVE}" = "true" ] && FLAGS+=" --recursive"
88

9-
# TODO: Use this when client ivc support write_vk. Currently it keeps its own flow.
10-
# case ${SYS:-} in
11-
# "")
12-
# prove_cmd=prove
13-
# verify_cmd=verify
14-
# ;;
15-
# "client_ivc")
16-
# prove_cmd=prove
17-
# verify_cmd=verify
18-
# flags+=" --scheme client_ivc --input_type ${INPUT_TYPE:-single_circuit}"
19-
# ;;
20-
# *)
21-
# prove_cmd=prove_$SYS
22-
# verify_cmd=verify_$SYS
23-
# ;;
24-
# esac
25-
269
# Test we can perform the proof/verify flow.
2710
# This ensures we test independent pk construction through real/garbage witness data paths.
2811
# We use process substitution pipes to avoid temporary files, which need cleanup, and can collide with parallelism.
Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
11
#!/usr/bin/env bash
22
# Create intermediate state in a directory. Uses a temp dir to ensure parallel safe and cleans up on exit.
3+
# TODO this is unused
34
set -eux
45

5-
INFLAG=${INPUT_TYPE:---input_type runtime_stack}
6-
7-
if [ "$INFLAG" = "--input_type runtime_stack" ]; then
8-
BFLAG=target/acir.msgpack
9-
WFLAG=target/witness.msgpack
10-
else
11-
BFLAG=target/program.json
12-
WFLAG=target/witness.gz
13-
fi
14-
156
CRS_PATH=${CRS_PATH:-$HOME/.bb-crs}
167
BIN=$(realpath ${BIN:-../cpp/build/bin/bb})
178

@@ -23,6 +14,6 @@ trap "rm -rf $outdir" EXIT
2314
flags="--scheme client_ivc -c $CRS_PATH ${VERBOSE:+-v}"
2415

2516
parallel ::: \
26-
"$BIN prove $flags -b $BFLAG -w $WFLAG $INFLAG --output_format proof -o $outdir" \
27-
"$BIN write_vk $flags -b $BFLAG $INFLAG --verifier_type ivc -o $outdir"
17+
"$BIN prove $flags -i target/ivc-inputs.msgpack $INFLAG --output_format proof -o $outdir" \
18+
"$BIN write_vk $flags -i target/ivc-inputs.msgpack $INFLAG --verifier_type ivc -o $outdir"
2819
$BIN verify $flags -p $outdir/proof -k $outdir/vk

barretenberg/acir_tests/flows/sol_honk.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -eu
44
VFLAG=${VERBOSE:+-v}
55
BFLAG="-b ./target/program.json"
66
FLAGS="-c $CRS_PATH $VFLAG --scheme ultra_honk"
7-
PROVE_FLAGS="$FLAGS $BFLAG --oracle_hash keccak --output_format bytes_and_fields --write_vk --input_type single_circuit"
7+
PROVE_FLAGS="$FLAGS $BFLAG --oracle_hash keccak --output_format bytes_and_fields --write_vk"
88
VERIFY_FLAGS="$FLAGS --oracle_hash keccak"
99

1010
outdir=$(mktemp -d)

barretenberg/cpp/.clangd

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
CompileFlags: # Tweak the parse settings
2-
Remove: -fconstexpr-ops-limit=* -Wfatal-errors
2+
Remove:
3+
- "-fconstexpr-ops-limit=*"
4+
- "-Wfatal-errors"
35
---
46
# Applies all barretenberg source files
57
If:
@@ -51,6 +53,8 @@ Diagnostics:
5153
- readability-container-data-pointer
5254
# Many hits; potential for false positives.
5355
- cppcoreguidelines-pro-type-member-init
56+
# We do use this, so no point banning it. The name is a warning enough.
57+
- cppcoreguidelines-pro-type-reinterpret-cast
5458
# As cryptographers, we often think of bools as 0/1 values; would bloat code in some places.
5559
- modernize-use-bool-literals
5660
# Triggers on every TYPED_TEST
@@ -71,6 +75,12 @@ Diagnostics:
7175
- modernize-use-auto
7276
# Not worth rewriting. Redundant types are often clearer.
7377
- modernize-return-braced-init-list
78+
# Not worth rewriting. Also some gotchas with mac not accepting emplaces of C++20 default constructors.
79+
- modernize-use-emplace
80+
# We only really use macros where a constexpr would NOT be able to replace its functionality.
81+
- cppcoreguidelines-macro-usage
82+
# Opinionated, we sometimes just want to use a default-derived constructor.
83+
- modernize-use-designated-initializers
7484

7585
--- # this divider is necessary
7686
# Disable some checks for Google Test/Bench

barretenberg/cpp/CMakePresets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@
471471
},
472472
{
473473
"name": "wasm-threads-assert",
474-
"displayName": "Build for WASM with multithreading and and asserts",
474+
"displayName": "Build for WASM with multithreading and asserts",
475475
"binaryDir": "build-wasm-threads-assert",
476476
"description": "Build with wasi-sdk with asserts",
477477
"inherits": "wasm-threads",

barretenberg/cpp/bootstrap.sh

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,9 @@ function bench {
220220
--benchmark_filter="construct_proof_ultrahonk_power_of_2/20$"
221221
}
222222
function ultra_honk_wasm {
223-
wasmtime run --env HARDWARE_CONCURRENCY --env IGNITION_CRS_PATH --env GRUMPKIN_CRS_PATH -Wthreads=y -Sthreads=y --dir=. \
224-
./build-wasm-threads/bin/ultra_honk_bench \
225-
--benchmark_out=./bench-out/ultra_honk_wasm.json \
226-
--benchmark_filter="construct_proof_ultrahonk_power_of_2/20$"
223+
scripts/wasmtime.sh ./build-wasm-threads/bin/ultra_honk_bench \
224+
--benchmark_out=./bench-out/ultra_honk_wasm.json \
225+
--benchmark_filter="construct_proof_ultrahonk_power_of_2/20$"
227226
}
228227

229228
# Client IVC
@@ -243,10 +242,9 @@ function bench {
243242
--benchmark_filter="ClientIVCBench/Full/6$"
244243
}
245244
function client_ivc_wasm {
246-
wasmtime run --env HARDWARE_CONCURRENCY --env IGNITION_CRS_PATH --env GRUMPKIN_CRS_PATH -Wthreads=y -Sthreads=y --dir=. \
247-
./build-wasm-threads/bin/client_ivc_bench \
248-
--benchmark_out=./bench-out/client_ivc_wasm.json \
249-
--benchmark_filter="ClientIVCBench/Full/6$"
245+
scripts/wasmtime.sh ./build-wasm-threads/bin/client_ivc_bench \
246+
--benchmark_out=./bench-out/client_ivc_wasm.json \
247+
--benchmark_filter="ClientIVCBench/Full/6$"
250248
}
251249

252250
function run_benchmark {
@@ -300,7 +298,7 @@ case "$cmd" in
300298
# Takes an optional master commit to download them from. Otherwise, downloads from latest master commit.
301299
git fetch origin master
302300

303-
build the benchmarked benches
301+
# build the benchmarked benches
304302
parallel --line-buffered --tag -v denoise ::: \
305303
"build_preset $native_preset --target bb_cli_bench" \
306304
"build_preset wasm-threads --target bb_cli_bench"

barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh

Lines changed: 63 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@
44
source $(git rev-parse --show-toplevel)/ci3/source
55

66
if [[ $# -ne 2 ]]; then
7-
echo "Usage: $0 <bench_input_folder> <output_folder>"
7+
echo "Usage: $0 <bench_input_folder> <benchmark_output>"
88
exit 1
99
fi
10-
export input_folder="$1"
11-
output_folder="$2"
12-
1310
cd ..
11+
export input_folder="$1"
12+
benchmark_output="$2"
1413

1514
echo_header "bb ivc flow bench"
1615

1716
export HARDWARE_CONCURRENCY=16
1817
export IGNITION_CRS_PATH=./srs_db/ignition
1918
export GRUMPKIN_CRS_PATH=./srs_db/grumpkin
19+
export native_preset=${NATIVE_PRESET:-clang16-assert}
20+
export native_build_dir=$(scripts/cmake/preset-build-dir $native_preset)
2021

21-
rm -rf bench-out/ivc && mkdir -p bench-out/ivc
22+
mkdir -p bench-out
23+
rm -rf bench-out/ivc-*
2224

2325
function verify_ivc_flow {
2426
local flow="$1"
@@ -28,10 +30,10 @@ function verify_ivc_flow {
2830
# TODO(AD): Checking which one would be good, but there isn't too much that can go wrong here.
2931
set +e
3032
echo_stderr "Private verify."
31-
./build/bin/bb verify --scheme client_ivc -p "$proof" -k ../../yarn-project/bb-prover/artifacts/private-civc-vk 1>&2
33+
"./$native_build_dir/bin/bb" verify --scheme client_ivc -p "$proof" -k ../../yarn-project/bb-prover/artifacts/private-civc-vk 1>&2
3234
local private_result=$?
3335
echo_stderr "Private verify: $private_result."
34-
./build/bin/bb verify --scheme client_ivc -p "$proof" -k ../../yarn-project/bb-prover/artifacts/public-civc-vk 1>&2
36+
"./$native_build_dir/bin/bb" verify --scheme client_ivc -p "$proof" -k ../../yarn-project/bb-prover/artifacts/public-civc-vk 1>&2
3537
local public_result=$?
3638
echo_stderr "Public verify: $public_result."
3739
if [[ $private_result -eq $public_result ]]; then
@@ -44,86 +46,71 @@ function verify_ivc_flow {
4446
fi
4547
}
4648

47-
function client_ivc_flow_native {
48-
set -eu
49-
local flow=$1
50-
local flow_folder="$input_folder/$flow"
51-
local start=$(date +%s%N)
52-
mkdir -p "bench-out/$flow-proof-files"
53-
export MEMUSAGE_OUT="bench-out/$flow-proof-files/peak-memory-native-mb.txt"
54-
55-
function bb_cli_bench_native {
56-
export MAIN_ARGS="$*"
57-
memusage ./build/bin/bb_cli_bench \
58-
--benchmark_out=bench-out/$flow-proof-files/op-counts.json \
59-
--benchmark_out_format=json || {
60-
echo "bb_cli_bench failed with args: $*"
49+
function run_bb_cli_bench {
50+
local runtime="$1"
51+
local output="$2"
52+
local args="$3"
53+
export MAIN_ARGS="$args"
54+
55+
if [[ "$runtime" == "native" ]]; then
56+
memusage "./$native_build_dir/bin/bb_cli_bench" \
57+
--benchmark_out=$output/op-counts.json \
58+
--benchmark_out_format=json || {
59+
echo "bb_cli_bench native failed with args: $args"
6160
exit 1
6261
}
63-
}
64-
65-
bb_cli_bench_native prove -o "bench-out/$flow-proof-files" -b "$flow_folder/acir.msgpack" -w "$flow_folder/witnesses.msgpack" --scheme client_ivc --input_type runtime_stack
66-
local end=$(date +%s%N)
67-
local elapsed_ns=$(( end - start ))
68-
local elapsed_ms=$(( elapsed_ns / 1000000 ))
69-
local memory_taken_mb=$(cat "$MEMUSAGE_OUT")
70-
echo "$flow (native) has proven in $((elapsed_ms / 1000))s and peak memory of ${memory_taken_mb}MB."
71-
dump_fail "verify_ivc_flow $flow bench-out/$flow-proof-files/proof"
72-
echo "$flow (native) has verified."
73-
cat > "./bench-out/ivc/$flow-ivc-native.json" <<EOF
74-
{
75-
"benchmarks": [
76-
{
77-
"name": "$flow-ivc-proof",
78-
"time_unit": "ms",
79-
"real_time": ${elapsed_ms}
80-
},
81-
{
82-
"name": "$flow-ivc-proof-memory",
83-
"time_unit": "MB",
84-
"real_time": ${elapsed_ms}
62+
else # wasm
63+
export WASMTIME_ALLOWED_DIRS="--dir=$flow_folder --dir=$output"
64+
# TODO support wasm op count time preset
65+
memusage scripts/wasmtime.sh $WASMTIME_ALLOWED_DIRS ./build-wasm-threads/bin/bb_cli_bench \
66+
--benchmark_out=$output/op-counts.json \
67+
--benchmark_out_format=json || {
68+
echo "bb_cli_bench wasm failed with args: $args"
69+
exit 1
8570
}
86-
]
87-
}
88-
EOF
71+
fi
8972
}
9073

91-
function client_ivc_flow_wasm {
74+
function client_ivc_flow {
9275
set -eu
93-
local flow=$1
76+
local runtime="$1"
77+
local flow="$2"
9478
local flow_folder="$input_folder/$flow"
9579
local start=$(date +%s%N)
96-
mkdir -p "bench-out/$flow-proof-files"
97-
export MEMUSAGE_OUT="bench-out/$flow-proof-files/peak-memory-wasm-mb.txt"
9880

99-
function bb_cli_bench_wasm {
100-
export MAIN_ARGS="$*"
101-
export WASMTIME_ALLOWED_DIRS="--dir=$HOME/.bb-crs --dir="$flow_folder" --dir=bench-out/$flow-proof-files"
102-
memusage scripts/wasmtime.sh $WASMTIME_ALLOWED_DIRS ./build-wasm-threads/bin/bb_cli_bench \
103-
--benchmark_out=bench-out/$flow-proof-files/op-counts.json \
104-
--benchmark_out_format=json || {
105-
echo "bb_cli_bench failed with args: $*"
106-
exit 1
107-
}
108-
}
109-
bb_cli_bench_wasm prove -o "bench-out/$flow-proof-files" -b "$flow_folder/acir.msgpack" -w "$flow_folder/witnesses.msgpack" --scheme client_ivc --input_type runtime_stack
81+
local output="bench-out/ivc-$flow-$runtime"
82+
rm -rf "$output"
83+
mkdir -p "$output"
84+
export MEMUSAGE_OUT="$output/peak-memory-$runtime-mb.txt"
85+
86+
run_bb_cli_bench "$runtime" "$output" "prove -o $output --ivc_inputs_path $flow_folder/ivc-inputs.msgpack --scheme client_ivc"
87+
88+
if [ -f "$output/op-counts.json" ]; then
89+
scripts/google-bench/summarize-op-counts "$output/op-counts.json"
90+
fi
91+
11092
local end=$(date +%s%N)
11193
local elapsed_ns=$(( end - start ))
11294
local elapsed_ms=$(( elapsed_ns / 1000000 ))
11395
local memory_taken_mb=$(cat "$MEMUSAGE_OUT")
114-
echo "$flow (WASM) has proven in ${elapsed_ms}ms and peak memory of ${memory_taken_mb}MB."
115-
dump_fail "verify_ivc_flow $flow bench-out/$flow-proof-files/proof"
116-
echo "$flow (WASM) has verified."
117-
cat > "./bench-out/ivc/$flow-ivc-wasm.json" <<EOF
96+
97+
echo "$flow ($runtime) has proven in $((elapsed_ms / 1000))s and peak memory of ${memory_taken_mb}MB."
98+
dump_fail "verify_ivc_flow $flow $output/proof"
99+
echo "$flow ($runtime) has verified."
100+
101+
local runtime_suffix=""
102+
[[ "$runtime" == "wasm" ]] && runtime_suffix="-wasm"
103+
104+
cat > "$output/benchmarks.json" <<EOF
118105
{
119106
"benchmarks": [
120107
{
121-
"name": "$flow-ivc-proof-wasm",
108+
"name": "$flow-ivc-proof$runtime_suffix",
122109
"time_unit": "ms",
123110
"real_time": ${elapsed_ms}
124111
},
125112
{
126-
"name": "$flow-ivc-proof-wasm-memory",
113+
"name": "$flow-ivc-proof$runtime_suffix-memory",
127114
"time_unit": "MB",
128115
"real_time": ${memory_taken_mb}
129116
}
@@ -140,7 +127,7 @@ function run_benchmark {
140127
taskset -c $start_core-$end_core bash -c "$2"
141128
}
142129

143-
export -f verify_ivc_flow client_ivc_flow_native client_ivc_flow_wasm run_benchmark
130+
export -f verify_ivc_flow client_ivc_flow run_bb_cli_bench run_benchmark
144131

145132
# TODO this does not work with smaller core counts - we will soon have a benchmark-wide mechanism for this.
146133
num_cpus=$(get_num_cpus)
@@ -149,15 +136,16 @@ jobs=$((num_cpus / HARDWARE_CONCURRENCY))
149136
# Split up the flows into chunks to run in parallel - otherwise we run out of CPUs to pin.
150137
if [ -n "${IVC_BENCH:-}" ]; then
151138
# If IVC_BENCH is set, run only that benchmark.
152-
run_benchmark 1 "client_ivc_flow_native $IVC_BENCH"
153-
run_benchmark 1 "client_ivc_flow_wasm $IVC_BENCH"
139+
run_benchmark 1 "client_ivc_flow native $IVC_BENCH"
140+
run_benchmark 1 "client_ivc_flow wasm $IVC_BENCH"
154141
else
155-
parallel -v --line-buffer --tag --jobs "$jobs" run_benchmark {#} '"client_ivc_flow_native {}"' ::: $(ls "$input_folder")
156-
parallel -v --line-buffer --tag --jobs "$jobs" run_benchmark {#} '"client_ivc_flow_wasm {}"' ::: $(ls "$input_folder")
142+
for runtime in native wasm; do
143+
parallel -v --line-buffer --tag --jobs "$jobs" run_benchmark {#} '"client_ivc_flow '$runtime' {}"' ::: $(ls "$input_folder")
144+
done
157145
fi
158146

159-
mkdir -p "$output_folder"
147+
mkdir -p "$benchmark_output"
160148

161149
../scripts/combine_benchmarks.py \
162-
./bench-out/ivc/*.json \
163-
> $output_folder/ivc-bench.json
150+
./bench-out/*/benchmarks.json \
151+
> $benchmark_output/ivc-bench.json

0 commit comments

Comments
 (0)