Skip to content

Commit

Permalink
feat: simple NIVC benchmark with the Trie coprocessors (#1220)
Browse files Browse the repository at this point in the history
Add a straightforward NIVC benchmark that uses the Trie coprocessors to create
proofs with the `SuperNovaProver`.

This should be enough for a first implementation to drive design/optimization
decisions for our NIVC pipeline.

Closes #1219
  • Loading branch information
arthurpaulino authored Mar 19, 2024
1 parent 54e9292 commit 4266b15
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,7 @@ harness = false
[[bench]]
name = "public_params"
harness = false

[[bench]]
name = "trie_nivc"
harness = false
114 changes: 114 additions & 0 deletions benches/trie_nivc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use criterion::{
black_box, criterion_group, criterion_main, measurement, BenchmarkGroup, BenchmarkId,
Criterion, SamplingMode,
};
use halo2curves::bn256::Fr;
use std::{sync::Arc, time::Duration};

use lurk::{
coprocessor::trie::{install, TrieCoproc},
dual_channel::dummy_terminal,
lang::Lang,
lem::{
eval::{evaluate, make_cprocs_funcs_from_lang, make_eval_step_from_config, EvalConfig},
interpreter::Frame,
store::Store,
},
proof::supernova::{public_params, SuperNovaProver},
state::State,
};

const CODE: &str = "
(let ((fib (letrec ((next (lambda (a b n target)
(if (eq n target)
a
(next b
(+ a b)
(+ 1 n)
target))))
(fib (next 0 1 0)))
fib))
(fib-trie (.lurk.trie.new))
(fib-trie (.lurk.trie.insert fib-trie 40 (fib 40)))
(fib-trie (.lurk.trie.insert fib-trie 50 (fib 50))))
(+ (num (.lurk.trie.lookup fib-trie 40)) (num (.lurk.trie.lookup fib-trie 50))))";

fn prove<M: measurement::Measurement>(
name: &str,
reduction_count: usize,
lang: &Arc<Lang<Fr, TrieCoproc<Fr>>>,
store: &Store<Fr>,
frames: &[Frame],
c: &mut BenchmarkGroup<'_, M>,
) {
c.bench_with_input(
BenchmarkId::new(name.to_string(), reduction_count),
&reduction_count,
|b, reduction_count| {
let rc = *reduction_count;
let prover = SuperNovaProver::new(rc, lang.clone());
let pp = public_params(rc, lang.clone());
b.iter(|| {
let (proof, ..) = prover.prove_from_frames(&pp, frames, store, None).unwrap();
let _ = black_box(proof);
})
},
);
}

fn trie_nivc(c: &mut Criterion) {
let batch_sizes = [5, 10, 100, 200];
let mut group: BenchmarkGroup<'_, _> = c.benchmark_group("trie-nivc");
group.sampling_mode(SamplingMode::Flat); // This can take a *while*
group.sample_size(10);

let state = State::init_lurk_state().rccell();
let mut lang = Lang::new();
install(&state, &mut lang);
let lang = Arc::new(lang);

let store = Store::<Fr>::default();
let expr = store.read(state, CODE).unwrap();

let lurk_step = make_eval_step_from_config(&EvalConfig::new_nivc(&lang));
let cprocs = make_cprocs_funcs_from_lang(&lang);
let frames = evaluate(
Some((&lurk_step, &cprocs, &lang)),
expr,
&store,
1_000_000,
&dummy_terminal(),
)
.unwrap();

assert_eq!(frames.last().unwrap().output[0], store.num_u64(12688603180));

for size in batch_sizes {
prove("rc", size, &lang, &store, &frames, &mut group);
}
}

cfg_if::cfg_if! {
if #[cfg(feature = "flamegraph")] {
criterion_group! {
name = benches;
config = Criterion::default()
.measurement_time(Duration::from_secs(120))
.sample_size(10)
.with_profiler(pprof::criterion::PProfProfiler::new(100, pprof::criterion::Output::Flamegraph(None)));
targets =
trie_nivc,
}
} else {
criterion_group! {
name = benches;
config = Criterion::default()
.measurement_time(Duration::from_secs(120))
.sample_size(10);
targets =
trie_nivc,
}
}
}

criterion_main!(benches);
2 changes: 1 addition & 1 deletion src/lem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
pub mod circuit;
pub mod coroutine;
pub mod eval;
pub(crate) mod interpreter;
pub mod interpreter;
mod macros;
pub mod multiframe;
pub mod pointers;
Expand Down

1 comment on commit 4266b15

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Table of Contents

Overview

This benchmark report shows the Fibonacci GPU benchmark.
NVIDIA L4
Intel(R) Xeon(R) CPU @ 2.20GHz
32 vCPUs
125 GB RAM
Workflow run: https://github.com/lurk-lab/lurk-rs/actions/runs/8342861241

Benchmark Results

LEM Fibonacci Prove - rc = 100

ref=54e92922b8de887c547e48320fd5c6b8bc622652 ref=4266b151841e4f10e4245856fc465ae08494bda6
num-100 1.46 s (✅ 1.00x) 1.47 s (✅ 1.00x slower)
num-200 2.78 s (✅ 1.00x) 2.80 s (✅ 1.01x slower)

LEM Fibonacci Prove - rc = 600

ref=54e92922b8de887c547e48320fd5c6b8bc622652 ref=4266b151841e4f10e4245856fc465ae08494bda6
num-100 1.84 s (✅ 1.00x) 1.84 s (✅ 1.00x slower)
num-200 3.01 s (✅ 1.00x) 3.04 s (✅ 1.01x slower)

Made with criterion-table

Please sign in to comment.