From ee0fc5fa1beb5bbd1d61fd938843203b6e1e313b Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 12:19:08 +0200 Subject: [PATCH 01/12] add a benchmark for poseidon --- .gitignore | 1 + Cargo.lock | 1 + poseidon/Cargo.toml | 5 +++++ poseidon/benches/poseidon_bench.rs | 32 ++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 poseidon/benches/poseidon_bench.rs diff --git a/.gitignore b/.gitignore index fb03a39692..43461ced65 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ idea *.sage.py params _build +build .merlin *.swp *.swo diff --git a/Cargo.lock b/Cargo.lock index 1a1ab03646..e4575f5447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1349,6 +1349,7 @@ dependencies = [ "ark-ff", "ark-poly", "ark-serialize", + "criterion", "hex", "mina-curves", "o1-utils", diff --git a/poseidon/Cargo.toml b/poseidon/Cargo.toml index 9256552934..78ff384f4e 100644 --- a/poseidon/Cargo.toml +++ b/poseidon/Cargo.toml @@ -34,7 +34,12 @@ ocaml-gen = { version = "0.1.5", optional = true } serde_json = "1.0" hex = "0.4" ark-serialize = "0.4.2" +criterion = "0.3" [features] default = [] ocaml_types = [ "ocaml", "ocaml-gen", ] + +[[bench]] +name = "poseidon_bench" +harness = false diff --git a/poseidon/benches/poseidon_bench.rs b/poseidon/benches/poseidon_bench.rs new file mode 100644 index 0000000000..852e560fd9 --- /dev/null +++ b/poseidon/benches/poseidon_bench.rs @@ -0,0 +1,32 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use mina_curves::pasta::Fp; +use mina_poseidon::constants::PlonkSpongeConstantsKimchi; +use mina_poseidon::pasta::fp_kimchi as SpongeParametersKimchi; +use mina_poseidon::poseidon::{ArithmeticSponge as Poseidon, Sponge}; + +pub fn bench_poseidon_kimchi(c: &mut Criterion) { + let mut group = c.benchmark_group("Poseidon"); + group.sample_size(100); + + let mut poseidon = + Poseidon::::new(SpongeParametersKimchi::static_params()); + + group.bench_function("poseidon_hash_kimchi", |b| { + b.iter(|| { + let input: Vec = vec![ + Fp::from(1), + Fp::from(2), + Fp::from(3), + Fp::from(4), + Fp::from(5), + ]; + poseidon.absorb(&input); + poseidon.squeeze(); + }) + }); + + group.finish(); +} + +criterion_group!(benches, bench_poseidon_kimchi); +criterion_main!(benches); From 04cfdc9f462fa16c7d6ab0b983a4eb70cfc8837b Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 12:54:56 +0200 Subject: [PATCH 02/12] silence warnings --- poseidon/Cargo.toml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/poseidon/Cargo.toml b/poseidon/Cargo.toml index 78ff384f4e..e76f0e5944 100644 --- a/poseidon/Cargo.toml +++ b/poseidon/Cargo.toml @@ -13,10 +13,10 @@ license = "Apache-2.0" path = "src/lib.rs" [dependencies] -ark-ff = { version = "0.4.2", features = [ "parallel", "asm" ] } -ark-ec = { version = "0.4.2", features = [ "parallel" ] } -ark-poly = { version = "0.4.2", features = [ "parallel" ] } -ark-serialize = { version = "0.4.2", features = ["derive"]} +ark-ff = { version = "0.4.2", features = ["parallel", "asm"] } +ark-ec = { version = "0.4.2", features = ["parallel"] } +ark-poly = { version = "0.4.2", features = ["parallel"] } +ark-serialize = { version = "0.4.2", features = ["derive"] } rand = "0.8.0" rayon = "1" serde = { version = "1.0", features = ["derive"] } @@ -34,11 +34,14 @@ ocaml-gen = { version = "0.1.5", optional = true } serde_json = "1.0" hex = "0.4" ark-serialize = "0.4.2" -criterion = "0.3" +criterion = { version = "0.3", default-features = false, features = [ + "cargo_bench_support", + "html_reports", +] } [features] default = [] -ocaml_types = [ "ocaml", "ocaml-gen", ] +ocaml_types = ["ocaml", "ocaml-gen"] [[bench]] name = "poseidon_bench" From 71abeef3a03c7f7d03bc6b44796de69b5f163210 Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 14:28:02 +0200 Subject: [PATCH 03/12] bench-wasm script --- bench-wasm.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 bench-wasm.sh diff --git a/bench-wasm.sh b/bench-wasm.sh new file mode 100755 index 0000000000..ae02086bd6 --- /dev/null +++ b/bench-wasm.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Default benchmark name +BENCH_NAME="" + +# Parse the optional --bench= argument +for i in "$@"; do + case $i in + --bench=*) + BENCH_NAME="${i#*=}" + shift # Remove --bench= from processing + ;; + *) + # unknown option + ;; + esac +done + +# Throw an error if --bench was not provided +if [ -z "$BENCH_NAME" ]; then + echo "Error: You must specify a benchmark using --bench=" + exit 1 +fi + +# Build the WASM benchmark with cargo-wasi +echo "Building benchmark '$BENCH_NAME' with cargo-wasi..." +cargo wasi build --bench="$BENCH_NAME" --release + +# Function to find the correct WASM file +find_wasm_file() { + # Search for the WASM file corresponding to the benchmark name + WASM_FILE=$(find target/wasm32-wasi/release/deps/ -type f -name "*$BENCH_NAME*.wasm" | head -n 1) + + if [ -z "$WASM_FILE" ]; then + echo "Error: No WASM file found for benchmark '$BENCH_NAME'." + exit 1 + fi +} + +# Call the function to find the correct WASM file +find_wasm_file + +echo "Running benchmark at $WASM_FILE with wasmer-js..." +# Run the WASM file with wasmer-js +wasmer-js run --dir=. "$WASM_FILE" -- --bench From d9c9ec375b477500ca0e20d1a5a0f26715e88706 Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 14:28:09 +0200 Subject: [PATCH 04/12] document wasm benchmark --- poseidon/README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/poseidon/README.md b/poseidon/README.md index cf0d24727e..2b3f6c4987 100644 --- a/poseidon/README.md +++ b/poseidon/README.md @@ -1,4 +1,4 @@ -# Oracle +# Poseidon ## Test vectors @@ -17,3 +17,31 @@ cargo run -p export_test_vectors -- B10 legacy - cargo run -p export_test_vectors -- b10 legacy legacy.json cargo run -p export_test_vectors -- hex kimchi kimchi.json ``` + +## Benchmark + +This folder contains a Poseidon benchmark `poseidon_bench`. + +To run the benchmark natively, do: + +```sh +cargo bench --bench=poseidon_bench +``` + +It can also be run in WebAssembly (executed by Node.js), with the following prerequisites: + +- Add the `wasm32-wasi` target +- Install `cargo-wasi` +- Install the wasmer JS CLI + +```sh +rustup target add wasm32-wasi +cargo install cargo-wasi +npm install -g @wasmer/cli +``` + +Now, you can run this and other benchmarks in Wasm, using the following from the repository root: + +```sh +./bench-wasm.sh --bench=poseidon_bench +``` From ece3335f4427b195e14dcff30e639c46731fc1da Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 14:35:14 +0200 Subject: [PATCH 05/12] don't accidentally use old files --- bench-wasm.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bench-wasm.sh b/bench-wasm.sh index ae02086bd6..43983ba05e 100755 --- a/bench-wasm.sh +++ b/bench-wasm.sh @@ -22,6 +22,21 @@ if [ -z "$BENCH_NAME" ]; then exit 1 fi +# Function to delete any old .wasm files related to the current benchmark +cleanup_old_wasm_files() { + WASM_FILES=$(find target/wasm32-wasi/release/deps/ -type f -name "*$BENCH_NAME*.wasm") + + if [ -n "$WASM_FILES" ]; then + echo "Cleaning up old WASM files for benchmark '$BENCH_NAME'..." + rm -f $WASM_FILES + else + echo "No old WASM files found for benchmark '$BENCH_NAME'." + fi +} + +# Call the cleanup function +cleanup_old_wasm_files + # Build the WASM benchmark with cargo-wasi echo "Building benchmark '$BENCH_NAME' with cargo-wasi..." cargo wasi build --bench="$BENCH_NAME" --release From cd535b3bfed9191c0bb2c8d516bac983f1744114 Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 14:51:36 +0200 Subject: [PATCH 06/12] make benchmark more random --- poseidon/benches/poseidon_bench.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/poseidon/benches/poseidon_bench.rs b/poseidon/benches/poseidon_bench.rs index 852e560fd9..b98b674d5f 100644 --- a/poseidon/benches/poseidon_bench.rs +++ b/poseidon/benches/poseidon_bench.rs @@ -11,17 +11,13 @@ pub fn bench_poseidon_kimchi(c: &mut Criterion) { let mut poseidon = Poseidon::::new(SpongeParametersKimchi::static_params()); + // Chain of hashes, starting from a random value group.bench_function("poseidon_hash_kimchi", |b| { + let mut hash: Fp = rand::random(); + b.iter(|| { - let input: Vec = vec![ - Fp::from(1), - Fp::from(2), - Fp::from(3), - Fp::from(4), - Fp::from(5), - ]; - poseidon.absorb(&input); - poseidon.squeeze(); + poseidon.absorb(&vec![hash]); + hash = poseidon.squeeze(); }) }); From 1778f634494e724ac8701e2c8948204a3c07f5af Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 15:16:48 +0200 Subject: [PATCH 07/12] add another note to readme --- poseidon/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/poseidon/README.md b/poseidon/README.md index 2b3f6c4987..60c36f8619 100644 --- a/poseidon/README.md +++ b/poseidon/README.md @@ -45,3 +45,5 @@ Now, you can run this and other benchmarks in Wasm, using the following from the ```sh ./bench-wasm.sh --bench=poseidon_bench ``` + +For this to work, the filename of your benchmark has to be the same as the benchmark name! From 846b4b744ad7f0c1d9c17f76994c5b5b65b7d08e Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 15:18:37 +0200 Subject: [PATCH 08/12] cargo fmt --- poseidon/benches/poseidon_bench.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/poseidon/benches/poseidon_bench.rs b/poseidon/benches/poseidon_bench.rs index b98b674d5f..013a47ff1e 100644 --- a/poseidon/benches/poseidon_bench.rs +++ b/poseidon/benches/poseidon_bench.rs @@ -1,8 +1,10 @@ use criterion::{criterion_group, criterion_main, Criterion}; use mina_curves::pasta::Fp; -use mina_poseidon::constants::PlonkSpongeConstantsKimchi; -use mina_poseidon::pasta::fp_kimchi as SpongeParametersKimchi; -use mina_poseidon::poseidon::{ArithmeticSponge as Poseidon, Sponge}; +use mina_poseidon::{ + constants::PlonkSpongeConstantsKimchi, + pasta::fp_kimchi as SpongeParametersKimchi, + poseidon::{ArithmeticSponge as Poseidon, Sponge}, +}; pub fn bench_poseidon_kimchi(c: &mut Criterion) { let mut group = c.benchmark_group("Poseidon"); From 693ff54a02b18930ba45118f641afd61823d527a Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 15:36:06 +0200 Subject: [PATCH 09/12] fix clippy error --- poseidon/benches/poseidon_bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poseidon/benches/poseidon_bench.rs b/poseidon/benches/poseidon_bench.rs index 013a47ff1e..6e2032466a 100644 --- a/poseidon/benches/poseidon_bench.rs +++ b/poseidon/benches/poseidon_bench.rs @@ -18,7 +18,7 @@ pub fn bench_poseidon_kimchi(c: &mut Criterion) { let mut hash: Fp = rand::random(); b.iter(|| { - poseidon.absorb(&vec![hash]); + poseidon.absorb(&[hash]); hash = poseidon.squeeze(); }) }); From 2060f9bcec1d2fa8a99b90ca1e2f88a2e0b1452b Mon Sep 17 00:00:00 2001 From: Gregor Date: Fri, 27 Sep 2024 15:48:16 +0200 Subject: [PATCH 10/12] makes more sense to start a new sponge in every call --- poseidon/benches/poseidon_bench.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poseidon/benches/poseidon_bench.rs b/poseidon/benches/poseidon_bench.rs index 6e2032466a..81a14d20fb 100644 --- a/poseidon/benches/poseidon_bench.rs +++ b/poseidon/benches/poseidon_bench.rs @@ -10,12 +10,12 @@ pub fn bench_poseidon_kimchi(c: &mut Criterion) { let mut group = c.benchmark_group("Poseidon"); group.sample_size(100); - let mut poseidon = - Poseidon::::new(SpongeParametersKimchi::static_params()); - // Chain of hashes, starting from a random value group.bench_function("poseidon_hash_kimchi", |b| { let mut hash: Fp = rand::random(); + let mut poseidon = Poseidon::::new( + SpongeParametersKimchi::static_params(), + ); b.iter(|| { poseidon.absorb(&[hash]); From 23de603e19e8c89bd0f785667abf8b6a3fc8f8ee Mon Sep 17 00:00:00 2001 From: Mikhail Volkhov Date: Fri, 11 Oct 2024 12:23:58 +0100 Subject: [PATCH 11/12] Move bench-wasm.sh into a sub-directory --- poseidon/README.md | 2 +- bench-wasm.sh => scripts/bench-wasm.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename bench-wasm.sh => scripts/bench-wasm.sh (100%) diff --git a/poseidon/README.md b/poseidon/README.md index 60c36f8619..067b665c66 100644 --- a/poseidon/README.md +++ b/poseidon/README.md @@ -43,7 +43,7 @@ npm install -g @wasmer/cli Now, you can run this and other benchmarks in Wasm, using the following from the repository root: ```sh -./bench-wasm.sh --bench=poseidon_bench +./scripts/bench-wasm.sh --bench=poseidon_bench ``` For this to work, the filename of your benchmark has to be the same as the benchmark name! diff --git a/bench-wasm.sh b/scripts/bench-wasm.sh similarity index 100% rename from bench-wasm.sh rename to scripts/bench-wasm.sh From 67c7d9a26d403ca93e22307395b680db7903c8de Mon Sep 17 00:00:00 2001 From: Mikhail Volkhov Date: Fri, 11 Oct 2024 13:01:52 +0100 Subject: [PATCH 12/12] Add dependency checks into bench-wasm, improve readme --- poseidon/README.md | 14 +---------- scripts/bench-wasm.sh | 54 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/poseidon/README.md b/poseidon/README.md index 067b665c66..bcf5401102 100644 --- a/poseidon/README.md +++ b/poseidon/README.md @@ -28,19 +28,7 @@ To run the benchmark natively, do: cargo bench --bench=poseidon_bench ``` -It can also be run in WebAssembly (executed by Node.js), with the following prerequisites: - -- Add the `wasm32-wasi` target -- Install `cargo-wasi` -- Install the wasmer JS CLI - -```sh -rustup target add wasm32-wasi -cargo install cargo-wasi -npm install -g @wasmer/cli -``` - -Now, you can run this and other benchmarks in Wasm, using the following from the repository root: +The benchmark can also be run in WebAssembly (executed by Node.js), launched from the repository root: ```sh ./scripts/bench-wasm.sh --bench=poseidon_bench diff --git a/scripts/bench-wasm.sh b/scripts/bench-wasm.sh index 43983ba05e..e47ad9c32c 100755 --- a/scripts/bench-wasm.sh +++ b/scripts/bench-wasm.sh @@ -1,8 +1,60 @@ #!/bin/bash + +USAGE=$(cat <<-END + +Dependencies installation: + + Add the \`wasm32-wasi\` target: + rustup target add wasm32-wasi + + Install \`cargo-wasi\`: + cargo install cargo-wasi + + Install the wasmer JS CLI: + npm install -g @wasmer/cli +END +) + +#read -r -d '' DEPENDENCIES_README << EOM +#rustup target add wasm32-wasi +# +#- Install `cargo-wasi` +#cargo install cargo-wasi +# +#- Install the wasmer JS CLI +#npm install -g @wasmer/cli +#EOM + + # Default benchmark name BENCH_NAME="" +GIT_ROOT=$(git rev-parse --show-toplevel); +if [ "$(pwd)" != "$GIT_ROOT" ]; then + echo "WARNING: it is recommended to launch this script from the git repo root" +fi + +# Checking dependencies + +if ! which wasmer-js > /dev/null; then + echo "ERROR: No wasmer-js found in PATH:" + echo "$USAGE" + exit 1 +fi + +if ! rustup target list --installed | grep wasm32-wasi > /dev/null; then + echo "ERROR: cargo wasm32-wasi target is not installed" + echo "$USAGE" + exit 1 +fi + +if ! cargo wasi > /dev/null; then + echo "ERROR: cargo-wasi is not installed" + echo "$USAGE" + exit 1 +fi + # Parse the optional --bench= argument for i in "$@"; do case $i in @@ -25,7 +77,7 @@ fi # Function to delete any old .wasm files related to the current benchmark cleanup_old_wasm_files() { WASM_FILES=$(find target/wasm32-wasi/release/deps/ -type f -name "*$BENCH_NAME*.wasm") - + if [ -n "$WASM_FILES" ]; then echo "Cleaning up old WASM files for benchmark '$BENCH_NAME'..." rm -f $WASM_FILES