diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 8d5f830a..060fc87d 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -19,7 +19,7 @@ jobs: toolchain: 1.51.0 override: true - name: Run benchmark - run: cargo bench | tee output.txt + run: cargo bench -- --output-format bencher | tee output.txt - name: Store benchmark result uses: benchmark-action/github-action-benchmark@v1 with: diff --git a/Cargo.toml b/Cargo.toml index 834b32ac..95ba643d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,9 @@ dev-graph = ["plotters", "tabbycat"] gadget-traces = ["backtrace"] sanity-checks = [] +[lib] +bench = false + [[example]] name = "circuit-layout" required-features = ["dev-graph"] diff --git a/benches/plonk.rs b/benches/plonk.rs index 6a20c555..fcd08609 100644 --- a/benches/plonk.rs +++ b/benches/plonk.rs @@ -11,16 +11,13 @@ use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255}; use std::marker::PhantomData; -use criterion::Criterion; +use criterion::{BenchmarkId, Criterion}; -fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { +fn criterion_benchmark(c: &mut Criterion) { /// This represents an advice column at a certain row in the ConstraintSystem #[derive(Copy, Clone, Debug)] pub struct Variable(Column, usize); - // Initialize the polynomial commitment parameters - let params: Params = Params::new(k); - #[derive(Clone)] struct PlonkConfig { a: Column, @@ -247,61 +244,74 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { } } - let empty_circuit: MyCircuit = MyCircuit { a: None, k }; + fn keygen(k: u32) -> (Params, ProvingKey) { + let params: Params = Params::new(k); + let empty_circuit: MyCircuit = MyCircuit { a: None, k }; + let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail"); + let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); + (params, pk) + } - // Initialize the proving key - let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); + fn prover(k: u32, params: &Params, pk: &ProvingKey) -> Vec { + let circuit: MyCircuit = MyCircuit { + a: Some(Fp::rand()), + k, + }; - let prover_name = name.to_string() + "-prover"; - let verifier_name = name.to_string() + "-verifier"; + let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); + create_proof(params, pk, &[circuit], &[&[]], &mut transcript) + .expect("proof generation should not fail"); + transcript.finalize() + } - c.bench_function(&prover_name, |b| { - b.iter(|| { - let circuit: MyCircuit = MyCircuit { - a: Some(Fp::rand()), - k, - }; + fn verifier(params: &Params, vk: &VerifyingKey, proof: &[u8]) { + let msm = params.empty_msm(); + let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(proof); + let guard = verify_proof(params, vk, msm, &[&[]], &mut transcript).unwrap(); + let msm = guard.clone().use_challenges(); + assert!(msm.eval()); + } - // Create a proof - let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); - create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript) - .expect("proof generation should not fail") + let k_range = 8..=16; + + let mut keygen_group = c.benchmark_group("plonk-keygen"); + keygen_group.sample_size(10); + for k in k_range.clone() { + keygen_group.bench_with_input(BenchmarkId::from_parameter(k), &k, |b, &k| { + b.iter(|| keygen(k)); }); - }); + } + keygen_group.finish(); - let circuit: MyCircuit = MyCircuit { - a: Some(Fp::rand()), - k, - }; + let mut prover_group = c.benchmark_group("plonk-prover"); + prover_group.sample_size(10); + for k in k_range.clone() { + let (params, pk) = keygen(k); - // Create a proof - let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); - create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript) - .expect("proof generation should not fail"); - let proof = transcript.finalize(); + prover_group.bench_with_input( + BenchmarkId::from_parameter(k), + &(k, ¶ms, &pk), + |b, &(k, params, pk)| { + b.iter(|| prover(k, params, pk)); + }, + ); + } + prover_group.finish(); - c.bench_function(&verifier_name, |b| { - b.iter(|| { - let msm = params.empty_msm(); - let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); - let guard = verify_proof(¶ms, pk.get_vk(), msm, &[&[]], &mut transcript).unwrap(); - let msm = guard.clone().use_challenges(); - assert!(msm.eval()); - }); - }); -} + let mut verifier_group = c.benchmark_group("plonk-verifier"); + for k in k_range { + let (params, pk) = keygen(k); + let proof = prover(k, ¶ms, &pk); -fn criterion_benchmark(c: &mut Criterion) { - bench_with_k("plonk-k=8", 8, c); - bench_with_k("plonk-k=9", 9, c); - bench_with_k("plonk-k=10", 10, c); - bench_with_k("plonk-k=11", 11, c); - bench_with_k("plonk-k=12", 12, c); - bench_with_k("plonk-k=13", 13, c); - bench_with_k("plonk-k=14", 14, c); - bench_with_k("plonk-k=15", 15, c); - bench_with_k("plonk-k=16", 16, c); + verifier_group.bench_with_input( + BenchmarkId::from_parameter(k), + &(¶ms, pk.get_vk(), &proof[..]), + |b, &(params, vk, proof)| { + b.iter(|| verifier(params, vk, proof)); + }, + ); + } + verifier_group.finish(); } criterion_group!(benches, criterion_benchmark);