mirror of
https://github.com/logos-storage/proof-aggregation.git
synced 2026-01-02 13:53:13 +00:00
Add benchmark scripts and refactor.
This commit is contained in:
parent
30b7a6ae03
commit
0a5bb1b52e
@ -6,7 +6,7 @@ resolver = "2"
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = { version = "1.0.89"}
|
anyhow = { version = "1.0.89"}
|
||||||
unroll = { version = "0.1.5"}
|
unroll = { version = "0.1.5"}
|
||||||
plonky2 = { version = "1.0.0" }
|
plonky2 = { version = "1.0.0" , default-features = false}
|
||||||
plonky2_field = { version = "1.0.0" }
|
plonky2_field = { version = "1.0.0" }
|
||||||
plonky2_maybe_rayon = { version = "1.0.0"}
|
plonky2_maybe_rayon = { version = "1.0.0"}
|
||||||
itertools = { version = "0.12.1"}
|
itertools = { version = "0.12.1"}
|
||||||
|
|||||||
@ -4,63 +4,30 @@ In here we show the preliminary benchmarks of codex storage proofs circuits.
|
|||||||
|
|
||||||
## Running Benchmarks
|
## Running Benchmarks
|
||||||
|
|
||||||
To run the benchmarks for safe merkle tree circuit, you can use the following command:
|
**Runtime Benchmarks**
|
||||||
|
|
||||||
|
To run the benchmarks for sampling circuit and aggregation, you can use the following commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo bench --bench safe_circuit
|
cd bench_scripts
|
||||||
|
bash ./bench_runtime
|
||||||
```
|
```
|
||||||
|
|
||||||
To run the benchmarks for sampling circuit, you can use the following command:
|
The following operations were benchmarked for sampling and recursion circuits (both single-thread and multi-thread):
|
||||||
Note: make sure to adjust the parameters as need in ....
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo bench --bench sample_cells
|
|
||||||
```
|
|
||||||
|
|
||||||
The following operations were benchmarked:
|
|
||||||
|
|
||||||
- **Build Circuit**: Time taken to construct the circuit for the specified params.
|
- **Build Circuit**: Time taken to construct the circuit for the specified params.
|
||||||
- **Prove Circuit**: Time taken to generate a proof for the constructed circuit.
|
- **Prove Circuit**: Time taken to generate a proof for the constructed circuit.
|
||||||
- **Verify Circuit**: Time taken to verify the generated proof.
|
- **Verify Circuit**: Time taken to verify the generated proof.
|
||||||
|
|
||||||
## Bench Results
|
**Memory Benchmarks**
|
||||||
The following is the result of running the codex storage proof circuit (sample_cells).
|
To run the memory benchmarks for sampling circuit and aggregation, you can use the following commands:
|
||||||
The bench uses the Goldilocks field and Poseidon2 Hash. All results were run on Mac Mini with M2 Pro and 16GB RAM.
|
|
||||||
|
|
||||||
### Bench params
|
|
||||||
The benchmark runs with the default params which are the following:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export MAXDEPTH=32 # Maximum depth of the slot tree
|
cd bench_scripts
|
||||||
export MAXSLOTS=256 # Maximum number of slots
|
bash ./bench_memory
|
||||||
export CELLSIZE=2048 # Cell size in bytes
|
|
||||||
export BLOCKSIZE=65536 # Block size in bytes
|
|
||||||
export NSAMPLES=5 # Number of samples to prove
|
|
||||||
|
|
||||||
export ENTROPY=1234567 # External randomness
|
|
||||||
export SEED=12345 # Seed for creating fake data
|
|
||||||
|
|
||||||
export NSLOTS=11 # Number of slots in the dataset
|
|
||||||
export SLOTINDEX=3 # Which slot to prove (0..NSLOTS-1)
|
|
||||||
export NCELLS=512 # Number of cells in this slot
|
|
||||||
```
|
```
|
||||||
|
Note: The memory usage is quite difficult to replicate as it depends on the operating system,
|
||||||
|
but on macOS look for the "maximum resident set size" to get the peak memory usage.
|
||||||
|
|
||||||
### Build Time
|
## Bench Results
|
||||||
Build time for plonky2 circuits is 39.644 ms.
|
See this [document](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/Bk-SopNj1g) for full benchmark results.
|
||||||
Baseline Groth16 with same params: 61 seconds for the circuit specific setup.
|
|
||||||
|
|
||||||
### Prove Time
|
|
||||||
Prove time for plonky2 circuits is 53.940 ms.
|
|
||||||
Baseline Groth16 with same params: 4.56 seconds using snarkjs
|
|
||||||
|
|
||||||
improvement: approx 80x
|
|
||||||
|
|
||||||
### Verify Time
|
|
||||||
To be done once recursion is added to the codebase.
|
|
||||||
|
|
||||||
### Proof Size
|
|
||||||
Plonky Proof size: 116008 bytes
|
|
||||||
This is without recursion or Groth16 wrapper.
|
|
||||||
|
|
||||||
### Peak Memory Usage
|
|
||||||
To be done.
|
|
||||||
|
|||||||
@ -22,6 +22,10 @@ proof-input = { path = "../proof-input" }
|
|||||||
criterion = { version = "0.5.1", default-features = false }
|
criterion = { version = "0.5.1", default-features = false }
|
||||||
tynm = { version = "0.1.6", default-features = false }
|
tynm = { version = "0.1.6", default-features = false }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
parallel = ["plonky2/parallel"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "prove_and_verify"
|
name = "prove_and_verify"
|
||||||
path = "src/bin/prove_and_verify.rs"
|
path = "src/bin/prove_and_verify.rs"
|
||||||
@ -38,6 +42,10 @@ path = "src/bin/build_circ.rs"
|
|||||||
name = "prove"
|
name = "prove"
|
||||||
path = "src/bin/prove.rs"
|
path = "src/bin/prove.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "aggregate"
|
||||||
|
path = "src/bin/aggregate.rs"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "merkle_circuit"
|
name = "merkle_circuit"
|
||||||
harness = false
|
harness = false
|
||||||
@ -48,4 +56,8 @@ harness = false
|
|||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "uniform_recursion"
|
name = "uniform_recursion"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "compression"
|
||||||
harness = false
|
harness = false
|
||||||
@ -22,6 +22,7 @@ This crate can be used to:
|
|||||||
|
|
||||||
- [`prove_and_verify`](./src/bin/prove_and_verify.rs) contains the main function to generated input with the given params as environment variables.
|
- [`prove_and_verify`](./src/bin/prove_and_verify.rs) contains the main function to generated input with the given params as environment variables.
|
||||||
|
|
||||||
|
- [`aggregate`](./src/bin/aggregate.rs) contains the main function to generate the sampling proofs and aggregate `k` of them.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ rustup override set nightly
|
|||||||
The steps to generate circuit input with **fake data** are the following:
|
The steps to generate circuit input with **fake data** are the following:
|
||||||
|
|
||||||
#### Step 1: Setting Up Parameters
|
#### Step 1: Setting Up Parameters
|
||||||
Parameters for generating the circuit input can be defined in [`params.sh`](./params.sh).
|
Parameters for generating the circuit input can be defined in [`params.sh`](scripts/params.sh).
|
||||||
You can customize the test parameters by setting the following environment variables:
|
You can customize the test parameters by setting the following environment variables:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -75,13 +76,13 @@ fn main() {
|
|||||||
Once the params are set, you can run the script to generate the [`JSON file`](./input.json).
|
Once the params are set, you can run the script to generate the [`JSON file`](./input.json).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo bash ./gen_input.sh
|
sudo bash ./scripts/gen_input.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build the Circuit
|
### Build the Circuit
|
||||||
To build the circuit and measure the time to build, you can simply run the script:
|
To build the circuit and measure the time to build, you can simply run the script:
|
||||||
```bash
|
```bash
|
||||||
sudo bash ./build_circuit.sh
|
sudo bash ./scripts/build_circuit.sh
|
||||||
```
|
```
|
||||||
To see the source code of how to build the circuit, see [`build_circ`](./src/bin/build_circ.rs).
|
To see the source code of how to build the circuit, see [`build_circ`](./src/bin/build_circ.rs).
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ you can run the circuits to generate the proofs.
|
|||||||
First make sure you have the [`JSON file`](./input.json), then follow the steps:
|
First make sure you have the [`JSON file`](./input.json), then follow the steps:
|
||||||
|
|
||||||
#### Step 1: Setting Up Circuit Parameters
|
#### Step 1: Setting Up Circuit Parameters
|
||||||
Parameters for the circuit can be defined in [`circ_params.sh`](./circ_params.sh).
|
Parameters for the circuit can be defined in [`circ_params.sh`](scripts/circ_params.sh).
|
||||||
You can customize the test parameters by setting the following environment variables:
|
You can customize the test parameters by setting the following environment variables:
|
||||||
```bash
|
```bash
|
||||||
export MAX_DEPTH=32 # maximum depth of the slot tree
|
export MAX_DEPTH=32 # maximum depth of the slot tree
|
||||||
@ -106,16 +107,31 @@ Once the params are set, you can run the script to generate the proof.
|
|||||||
You can also see the time taken to generate the proof.
|
You can also see the time taken to generate the proof.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo bash ./prove.sh
|
sudo bash ./scripts/prove.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build, Prove, and Verify
|
### Build, Prove, and Verify
|
||||||
To automate the whole process, you can run the following script
|
To automate the whole process, you can run the following script
|
||||||
the script builds the circuit, loads the JSON circuit input, generates the proof, and verifies it.
|
the script builds the circuit, loads the JSON circuit input, generates the proof, and verifies it.
|
||||||
It also shows the time taken for each step.
|
It also shows the time taken for each step.
|
||||||
Make sure that you generate the circuit input prior to this so that you have the [`JSON input file`](./input.json) and set the [`circ_params.sh`](./circ_params.sh).
|
Make sure that you generate the circuit input prior to this so that you have the [`JSON input file`](./input.json) and set the [`circ_params.sh`](scripts/circ_params.sh).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo bash ./prove_and_verify.sh
|
sudo bash ./scripts/prove_and_verify.sh
|
||||||
```
|
```
|
||||||
To inspect the source code, see [`prove_and_verify`](./src/bin/prove_and_verify.rs).
|
To inspect the source code, see [`prove_and_verify`](./src/bin/prove_and_verify.rs).
|
||||||
|
|
||||||
|
### Generate K Proofs and aggregate them
|
||||||
|
To do this, you can run the following script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo bash ./scripts/aggregate.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
or the following if you want to specify the number of proofs to be aggregated
|
||||||
|
```bash
|
||||||
|
sudo bash ./scripts/aggregate.sh -- "$K_VALUE"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,77 +0,0 @@
|
|||||||
## Benchmarks
|
|
||||||
|
|
||||||
In here we show the benchmarks results when using Plonky2 recursion for the codex storage proofs.
|
|
||||||
|
|
||||||
## Running Benchmarks
|
|
||||||
|
|
||||||
To run the benchmarks, you can use the following command with `x` replaced with the benchmark name (for the list of all benchmarks, see [benches](./benches)):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo bench --bench x
|
|
||||||
```
|
|
||||||
|
|
||||||
## Benchmark Results:
|
|
||||||
We implemented and experimented with various recursion approaches:
|
|
||||||
- Simple Recursion
|
|
||||||
- Simple Tree Recursion
|
|
||||||
- Cyclic Recursion
|
|
||||||
- Tree Recursion (Approach1)
|
|
||||||
- Tree Recursion (Approach2)
|
|
||||||
- Hybrid Recursion (Simple + Tree)
|
|
||||||
|
|
||||||
For more details on each of these approaches see this [writeup](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/rk85D2HX1e)
|
|
||||||
|
|
||||||
Here we show the benchmark results of running Hybrid recursion approaches and compare it to simple recursion.
|
|
||||||
Based on our experimentation, the hybrid approach gives the best results, compared to others.
|
|
||||||
The Params for the hybrid approach must be adjusted based on the number of proofs to be aggregated to give optimal results.
|
|
||||||
|
|
||||||
There are various parameters to consider before benchmarking.
|
|
||||||
First the circuit and test parameters we used are the following:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export MAXDEPTH=32 # Maximum depth of the slot tree
|
|
||||||
export MAXSLOTS=256 # Maximum number of slots
|
|
||||||
export CELLSIZE=2048 # Cell size in bytes
|
|
||||||
export BLOCKSIZE=65536 # Block size in bytes
|
|
||||||
export NSAMPLES=100 # Number of samples to prove
|
|
||||||
|
|
||||||
export ENTROPY=1234567 # External randomness
|
|
||||||
export SEED=12345 # Seed for creating fake data
|
|
||||||
|
|
||||||
export NSLOTS=11 # Number of slots in the dataset
|
|
||||||
export SLOTINDEX=3 # Which slot to prove (0..NSLOTS-1)
|
|
||||||
export NCELLS=512 # Number of cells in this slot
|
|
||||||
```
|
|
||||||
|
|
||||||
As can be seen above we set the number of samples (`NSAMPLES=100`) which should be sufficient.
|
|
||||||
|
|
||||||
Additionally, we vary the number of proofs to be aggregated (`P = {4,8,16,32,64,128}`).
|
|
||||||
There are also the `N` and `M` parameters for the tree-structure recursion.
|
|
||||||
These params mean different things for each approach (refer to [writeup](https://hackmd.io/@NQdG6IOmQE6astjwhJ6ACw/rk85D2HX1e))
|
|
||||||
In the Hybrid approach, these values are
|
|
||||||
- `M`: Number of proof aggregated in the leaf
|
|
||||||
- `N`: Number of proofs aggregated in the nodes of the tree
|
|
||||||
|
|
||||||
**Build Circuit**
|
|
||||||
|
|
||||||
| **P** | ** Recursion Build time (s)** |
|
|
||||||
|---------|-------------------------------|
|
|
||||||
| **4** | 0.967 |
|
|
||||||
| **8** | 1.613 |
|
|
||||||
| **16** | 2.977 |
|
|
||||||
| **32** | 5.847 |
|
|
||||||
| **64** | 12.533 |
|
|
||||||
| **128** | 26.930 |
|
|
||||||
|
|
||||||
|
|
||||||
**Prove Circuit**
|
|
||||||
|
|
||||||
| **P** | **Simple Recursion (s)** | **Hybrid Recursion (s)** |
|
|
||||||
|-------|--------------------------|--------------------------|
|
|
||||||
| **4** | 0.769 | 0.612 |
|
|
||||||
| **8** | 1.549 | 1.227 |
|
|
||||||
| **16** | 3.212 | 2.691 |
|
|
||||||
| **32** | 6.574 | 6.225 |
|
|
||||||
| **64** | 15.107 | 14.654 |
|
|
||||||
| **128** | 34.617 | 29.189 |
|
|
||||||
|
|
||||||
25
workflow/bench_scripts/bench_memory.sh
Normal file
25
workflow/bench_scripts/bench_memory.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source parameters
|
||||||
|
source "params.sh"
|
||||||
|
|
||||||
|
# Move to the project root
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
|
# Build silently
|
||||||
|
cargo build --release > /dev/null 2>&1 || { echo "cargo build failed"; exit 101; }
|
||||||
|
|
||||||
|
# 1) sampling circuit - build
|
||||||
|
echo "Running sampling circuit - build..."
|
||||||
|
/usr/bin/time -l bash -c 'cargo run --bin build_circ --features "parallel" >/dev/null 2>/dev/null'
|
||||||
|
|
||||||
|
# 2) sampling circuit - prove
|
||||||
|
echo "Running sampling circuit - prove..."
|
||||||
|
cargo run --bin gen_input >/dev/null 2>/dev/null || { echo "gen_input.sh: cargo run failed"; exit 102; }
|
||||||
|
/usr/bin/time -l bash -c 'cargo run --bin prove --features "parallel" >/dev/null 2>/dev/null'
|
||||||
|
|
||||||
|
# 3) sampling circuit - aggregate
|
||||||
|
K_VALUE=${1:-128}
|
||||||
|
echo "Running sampling circuit - aggregate (${K_VALUE} proofs)..."
|
||||||
|
/usr/bin/time -l bash -c "cargo run --bin aggregate --features 'parallel' -- '${K_VALUE}' >/dev/null 2>/dev/null"
|
||||||
|
|
||||||
16
workflow/bench_scripts/bench_runtime.sh
Normal file
16
workflow/bench_scripts/bench_runtime.sh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
|
echo "Running bench for the sampling circuit with multithreading..."
|
||||||
|
cargo bench --bench sample_cells --features "parallel" || { echo "Benchmark 'sample_cells' with multithreading failed"; exit 101; }
|
||||||
|
|
||||||
|
echo "Running bench for the sampling circuit with single-thread..."
|
||||||
|
cargo bench --bench sample_cells || { echo "Benchmark 'sample_cells' with single-thread failed"; exit 102; }
|
||||||
|
|
||||||
|
echo "Running bench for the tree recursion circuit with multithreading..."
|
||||||
|
cargo bench --bench uniform_recursion --features "parallel" || { echo "Benchmark 'uniform_recursion' with multithreading failed"; exit 103; }
|
||||||
|
|
||||||
|
echo "Running bench for the tree recursion circuit with single-thread..."
|
||||||
|
cargo bench --bench uniform_recursion || { echo "Benchmark 'uniform_recursion' with single-thread failed"; exit 104; }
|
||||||
7
workflow/bench_scripts/circ_params.sh
Executable file
7
workflow/bench_scripts/circ_params.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export MAX_DEPTH=32 # maximum depth of the slot tree
|
||||||
|
export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots)
|
||||||
|
export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree)
|
||||||
|
export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell
|
||||||
|
export N_SAMPLES=100 # number of samples to prove
|
||||||
@ -4,7 +4,7 @@ export MAXDEPTH=32 # maximum depth of the slot tree
|
|||||||
export MAXSLOTS=256 # maximum number of slots
|
export MAXSLOTS=256 # maximum number of slots
|
||||||
export CELLSIZE=2048 # cell size in bytes
|
export CELLSIZE=2048 # cell size in bytes
|
||||||
export BLOCKSIZE=65536 # block size in bytes
|
export BLOCKSIZE=65536 # block size in bytes
|
||||||
export NSAMPLES=5 # number of samples to prove
|
export NSAMPLES=100 # number of samples to prove
|
||||||
|
|
||||||
export ENTROPY=1234567 # external randomness
|
export ENTROPY=1234567 # external randomness
|
||||||
export SEED=12345 # seed for creating fake data
|
export SEED=12345 # seed for creating fake data
|
||||||
@ -2,7 +2,6 @@ use criterion::{criterion_group, criterion_main, Criterion};
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use proof_input::merkle_tree::merkle_safe::{MerkleTree};
|
use proof_input::merkle_tree::merkle_safe::{MerkleTree};
|
||||||
// use codex_plonky2_circuits::{circuits::merkle_circuit::MerkleTreeCircuit};
|
|
||||||
use plonky2::field::types::Field;
|
use plonky2::field::types::Field;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData};
|
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData};
|
||||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig};
|
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig};
|
||||||
@ -13,8 +12,6 @@ use plonky2::field::extension::Extendable;
|
|||||||
use plonky2::hash::hash_types::RichField;
|
use plonky2::hash::hash_types::RichField;
|
||||||
use plonky2_poseidon2::poseidon2_hash::poseidon2::{Poseidon2, Poseidon2Hash};
|
use plonky2_poseidon2::poseidon2_hash::poseidon2::{Poseidon2, Poseidon2Hash};
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
// use codex_plonky2_circuits::merkle_tree::merkle_safe::MerkleProof;
|
|
||||||
// use plonky2_field::goldilocks_field::GoldilocksField;
|
|
||||||
use proof_input::merkle_tree::merkle_circuit;
|
use proof_input::merkle_tree::merkle_circuit;
|
||||||
use proof_input::merkle_tree::merkle_circuit::{assign_witness, MerkleTreeCircuitInput};
|
use proof_input::merkle_tree::merkle_circuit::{assign_witness, MerkleTreeCircuitInput};
|
||||||
use proof_input::utils::usize_to_bits_le;
|
use proof_input::utils::usize_to_bits_le;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use criterion::{criterion_group, criterion_main, Criterion};
|
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||||
use plonky2::iop::witness::PartialWitness;
|
use plonky2::iop::witness::PartialWitness;
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||||
@ -10,9 +10,9 @@ use proof_input::gen_input::gen_testing_circuit_input;
|
|||||||
use proof_input::params::{D, C, F, HF, Params};
|
use proof_input::params::{D, C, F, HF, Params};
|
||||||
|
|
||||||
/// Benchmark for building, proving, and verifying the Plonky2 circuit.
|
/// Benchmark for building, proving, and verifying the Plonky2 circuit.
|
||||||
fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
fn bench_prove_verify<const N: usize>(c: &mut Criterion) -> Result<()>{
|
||||||
|
|
||||||
let n_samples = 100;
|
let n_samples = N;
|
||||||
// get default parameters
|
// get default parameters
|
||||||
let params = Params::default();
|
let params = Params::default();
|
||||||
let mut test_params = params.input_params;
|
let mut test_params = params.input_params;
|
||||||
@ -21,6 +21,9 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
|||||||
let mut circuit_params = params.circuit_params;
|
let mut circuit_params = params.circuit_params;
|
||||||
circuit_params.n_samples = n_samples;
|
circuit_params.n_samples = n_samples;
|
||||||
|
|
||||||
|
#[cfg(feature = "parallel")]
|
||||||
|
println!("Parallel feature is ENABLED");
|
||||||
|
|
||||||
// gen the circuit input
|
// gen the circuit input
|
||||||
let circ_input = gen_testing_circuit_input::<F,D>(&test_params);
|
let circ_input = gen_testing_circuit_input::<F,D>(&test_params);
|
||||||
|
|
||||||
@ -37,7 +40,7 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
|||||||
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input.clone());
|
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input.clone());
|
||||||
|
|
||||||
// Benchmark Group: Separate benchmarks for building, proving, and verifying
|
// Benchmark Group: Separate benchmarks for building, proving, and verifying
|
||||||
let mut group = c.benchmark_group("Sampling Circuit Benchmark");
|
let mut group = c.benchmark_group(format!("Sampling Circuit Benchmark for N= {}", N));
|
||||||
|
|
||||||
// Benchmark the Circuit Building Phase
|
// Benchmark the Circuit Building Phase
|
||||||
group.bench_function("Build Circuit", |b| {
|
group.bench_function("Build Circuit", |b| {
|
||||||
@ -45,9 +48,6 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
|||||||
let config = CircuitConfig::standard_recursion_config();
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
let mut local_builder = CircuitBuilder::<F, D>::new(config);
|
let mut local_builder = CircuitBuilder::<F, D>::new(config);
|
||||||
let _targets = circ.sample_slot_circuit_with_public_input(&mut local_builder);
|
let _targets = circ.sample_slot_circuit_with_public_input(&mut local_builder);
|
||||||
// let local_targets = targets.clone();
|
|
||||||
// let mut local_pw = pw.clone();
|
|
||||||
// circ.sample_slot_assign_witness(&mut local_pw, &local_targets, &circ_input.clone());
|
|
||||||
let _data = local_builder.build::<C>();
|
let _data = local_builder.build::<C>();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -68,12 +68,12 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
|||||||
// println!("Number of constraints: {}", num_constr);
|
// println!("Number of constraints: {}", num_constr);
|
||||||
// println!("Number of gates used: {}", data.common.gates.len());
|
// println!("Number of gates used: {}", data.common.gates.len());
|
||||||
|
|
||||||
// Benchmark the Proving Phase
|
|
||||||
group.bench_function("Prove Circuit", |b| {
|
group.bench_function("Prove Circuit", |b| {
|
||||||
b.iter(|| {
|
b.iter_batched(
|
||||||
let local_pw = pw.clone();
|
|| pw.clone(),
|
||||||
data.prove(local_pw).expect("Failed to prove circuit")
|
|local_pw| data.prove(local_pw).expect("Failed to prove circuit"),
|
||||||
})
|
BatchSize::SmallInput,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate the proof once for verification benchmarking
|
// Generate the proof once for verification benchmarking
|
||||||
@ -96,10 +96,17 @@ fn bench_prove_verify(c: &mut Criterion) -> Result<()>{
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bench_sampling(c: &mut Criterion) -> Result<()>{
|
||||||
|
bench_prove_verify::<10>(c)?;
|
||||||
|
bench_prove_verify::<50>(c)?;
|
||||||
|
bench_prove_verify::<100>(c)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Criterion benchmark group
|
/// Criterion benchmark group
|
||||||
criterion_group!{
|
criterion_group!{
|
||||||
name = prove_verify_benches;
|
name = benches;
|
||||||
config = Criterion::default().sample_size(10);
|
config = Criterion::default().sample_size(10);
|
||||||
targets = bench_prove_verify
|
targets = bench_sampling
|
||||||
}
|
}
|
||||||
criterion_main!(prove_verify_benches);
|
criterion_main!(benches);
|
||||||
|
|||||||
@ -31,7 +31,7 @@ fn bench_uniform_recursion<const K: usize,const N: usize,const M: usize,>(c: &mu
|
|||||||
let inner_data = sampling_builder.build::<C>();
|
let inner_data = sampling_builder.build::<C>();
|
||||||
let inner_proof = inner_data.prove(pw.clone())?;
|
let inner_proof = inner_data.prove(pw.clone())?;
|
||||||
|
|
||||||
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..N).map(|i| inner_proof.clone()).collect();
|
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..K).map(|i| inner_proof.clone()).collect();
|
||||||
|
|
||||||
// ------------------- tree --------------------
|
// ------------------- tree --------------------
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Source the parameters from params.sh
|
|
||||||
source ./params.sh
|
|
||||||
|
|
||||||
# Build
|
|
||||||
cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; }
|
|
||||||
|
|
||||||
# Run the Rust executable
|
|
||||||
cargo run --bin build_circ || { echo "build_circuit.sh: cargo run failed"; exit 102; }
|
|
||||||
14
workflow/scripts/aggregate.sh
Normal file
14
workflow/scripts/aggregate.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source the parameters from the scripts directory
|
||||||
|
source "params.sh"
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
||||||
|
|
||||||
|
# Run the Rust executable
|
||||||
|
K_VALUE=${1:-4}
|
||||||
|
cargo run --bin aggregate --features "parallel" -- "$K_VALUE" || { echo "prove.sh: cargo run failed"; exit 102; }
|
||||||
14
workflow/scripts/build_circuit.sh
Executable file
14
workflow/scripts/build_circuit.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source the parameters from the scripts directory
|
||||||
|
source "params.sh"
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; }
|
||||||
|
|
||||||
|
# Run the Rust executable
|
||||||
|
cargo run --bin build_circ || { echo "build_circuit.sh: cargo run failed"; exit 102; }
|
||||||
|
|
||||||
@ -3,6 +3,9 @@
|
|||||||
# Source the parameters from params.sh
|
# Source the parameters from params.sh
|
||||||
source ./params.sh
|
source ./params.sh
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
cargo build --release || { echo "gen_input.sh: cargo build failed"; exit 101; }
|
cargo build --release || { echo "gen_input.sh: cargo build failed"; exit 101; }
|
||||||
|
|
||||||
14
workflow/scripts/params.sh
Executable file
14
workflow/scripts/params.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export MAXDEPTH=32 # maximum depth of the slot tree
|
||||||
|
export MAXSLOTS=256 # maximum number of slots
|
||||||
|
export CELLSIZE=2048 # cell size in bytes
|
||||||
|
export BLOCKSIZE=65536 # block size in bytes
|
||||||
|
export NSAMPLES=100 # number of samples to prove
|
||||||
|
|
||||||
|
export ENTROPY=1234567 # external randomness
|
||||||
|
export SEED=12345 # seed for creating fake data
|
||||||
|
|
||||||
|
export NSLOTS=11 # number of slots in the dataset
|
||||||
|
export SLOTINDEX=3 # which slot we prove (0..NSLOTS-1)
|
||||||
|
export NCELLS=512 # number of cells in this slot
|
||||||
@ -3,6 +3,9 @@
|
|||||||
# Source the parameters from params.sh
|
# Source the parameters from params.sh
|
||||||
source ./circ_params.sh
|
source ./circ_params.sh
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
||||||
|
|
||||||
@ -3,6 +3,9 @@
|
|||||||
# Source the parameters from params.sh
|
# Source the parameters from params.sh
|
||||||
source ./circ_params.sh
|
source ./circ_params.sh
|
||||||
|
|
||||||
|
# Change to the parent directory of the script
|
||||||
|
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
cargo build --release || { echo "prove_and_verify.sh: cargo build failed"; exit 101; }
|
cargo build --release || { echo "prove_and_verify.sh: cargo build failed"; exit 101; }
|
||||||
|
|
||||||
60
workflow/src/bin/aggregate.rs
Normal file
60
workflow/src/bin/aggregate.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use std::env;
|
||||||
|
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||||
|
use plonky2::plonk::config::GenericConfig;
|
||||||
|
use plonky2::iop::witness::PartialWitness;
|
||||||
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use anyhow::Result;
|
||||||
|
use plonky2::plonk::proof::ProofWithPublicInputs;
|
||||||
|
use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit;
|
||||||
|
use codex_plonky2_circuits::recursion::uniform::tree::TreeRecursion;
|
||||||
|
use proof_input::gen_input::gen_testing_circuit_input;
|
||||||
|
use proof_input::params::{D, C, F, HF, Params};
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
// load the parameters from environment variables
|
||||||
|
let params = Params::from_env()?;
|
||||||
|
const N: usize = 1;
|
||||||
|
const M: usize = 2;
|
||||||
|
|
||||||
|
// take k = "number of proofs" from env arguments; default to 4 if not there
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let k: usize = if args.len() > 1 {
|
||||||
|
args[1]
|
||||||
|
.parse()
|
||||||
|
.expect("k not valid")
|
||||||
|
} else {
|
||||||
|
4
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate circuit input with given parameters
|
||||||
|
let circ_input = gen_testing_circuit_input::<F,D>(¶ms.input_params);
|
||||||
|
|
||||||
|
// create the circuit
|
||||||
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
|
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||||
|
let circ = SampleCircuit::<F,D,HF>::new(params.circuit_params);
|
||||||
|
let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?;
|
||||||
|
|
||||||
|
// create a PartialWitness and assign
|
||||||
|
let mut pw = PartialWitness::new();
|
||||||
|
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?;
|
||||||
|
|
||||||
|
// Build the circuit
|
||||||
|
let data = builder.build::<C>();
|
||||||
|
|
||||||
|
// Prove the inner-circuit with the assigned witness
|
||||||
|
let inner_proof = data.prove(pw)?;
|
||||||
|
|
||||||
|
// dummy proofs
|
||||||
|
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..k).map(|i| inner_proof.clone()).collect();
|
||||||
|
|
||||||
|
let mut tree = TreeRecursion::<F,D,C,HF, N, M>::build(data.common.clone()).unwrap();
|
||||||
|
|
||||||
|
let tree_proof = tree.prove_tree(&proofs, &data.verifier_only).unwrap();
|
||||||
|
|
||||||
|
let inner_pi: Vec<Vec<F>> = proofs.iter().map(|p| p.public_inputs.clone()).collect();
|
||||||
|
|
||||||
|
assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),&data.verifier_data(), false).is_ok());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
// Create a PartialWitness and assign
|
// Create a PartialWitness and assign
|
||||||
let mut pw = PartialWitness::new();
|
let mut pw = PartialWitness::new();
|
||||||
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input);
|
circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?;
|
||||||
|
|
||||||
// Build the circuit
|
// Build the circuit
|
||||||
let build_time = Instant::now();
|
let build_time = Instant::now();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user