Skip to content

Commit

Permalink
Revert "merge fib benchmarks (#784)"
Browse files Browse the repository at this point in the history
This reverts commit 1ad6470.
  • Loading branch information
huitseeker committed Oct 27, 2023
1 parent 1e42515 commit f00544e
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 316 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ harness = false
name = "fibonacci"
harness = false

[[bench]]
name = "fibonacci_lem"
harness = false

[[bench]]
name = "synthesis"
harness = false
Expand Down
317 changes: 95 additions & 222 deletions benches/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,263 +5,136 @@ use criterion::{
BenchmarkId, Criterion, SamplingMode,
};

use pasta_curves::pallas;

use lurk::{
eval::lang::{Coproc, Lang},
field::LurkField,
proof::{
nova::{NovaProver, Proof},
Prover,
circuit::circuit_frame::MultiFrame,
eval::{
empty_sym_env,
lang::{Coproc, Lang},
},
field::LurkField,
proof::nova::NovaProver,
proof::Prover,
ptr::Ptr,
public_parameters::{
instance::{Instance, Kind},
public_params,
},
state::State,
store::Store,
};
use pasta_curves::pallas;

mod common;
use common::set_bench_config;

#[allow(clippy::upper_case_acronyms)]
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
enum Version {
ALPHA,
LEM,
fn fib<F: LurkField>(store: &Store<F>, state: Rc<RefCell<State>>, _a: u64) -> Ptr<F> {
let program = r#"
(letrec ((next (lambda (a b) (next b (+ a b))))
(fib (next 0 1)))
(fib))
"#;

store.read_with_state(state, program).unwrap()
}

// The env output in the `fib_frame`th frame of the above, infinite Fibonacci computation will contain a binding of the
// nth Fibonacci number to `a`.
// means of computing it.]
fn fib_frame(n: usize) -> usize {
11 + 16 * n
}

// Set the limit so the last step will be filled exactly, since Lurk currently only pads terminal/error continuations.
fn fib_limit(n: usize, rc: usize) -> usize {
let frame = fib_frame(n);
rc * (frame / rc + usize::from(frame % rc != 0))
}

#[derive(Clone, Debug, Copy)]
pub struct ProveParams {
folding_steps: usize,
struct ProveParams {
fib_n: usize,
reduction_count: usize,
version: Version,
}

impl ProveParams {
fn name(&self) -> String {
format!("{:?},rc={}", self.version, self.reduction_count)
}
}

mod alpha {
use lurk::{circuit::circuit_frame::MultiFrame, eval::empty_sym_env, ptr::Ptr, store::Store};

use super::*;

fn fib<F: LurkField>(store: &Store<F>, state: Rc<RefCell<State>>) -> Ptr<F> {
let program = r#"
(letrec ((next (lambda (a b) (next b (+ a b))))
(fib (next 0 1)))
(fib))
"#;

store.read_with_state(state, program).unwrap()
}

pub fn prove<M: measurement::Measurement>(
prove_params: ProveParams,
c: &mut BenchmarkGroup<'_, M>,
state: &Rc<RefCell<State>>,
) {
let ProveParams {
folding_steps,
reduction_count,
version,
} = prove_params;

assert_eq!(version, Version::ALPHA);
let limit = reduction_count * (folding_steps + 1);

// Track the number of `folded iterations / sec`
c.throughput(criterion::Throughput::Elements(
(reduction_count * folding_steps) as u64,
));

let lang_pallas = Lang::<pallas::Scalar, Coproc<pallas::Scalar>>::new();
let lang_rc = Arc::new(lang_pallas.clone());

// use cached public params
let instance = Instance::new(
reduction_count,
lang_rc.clone(),
true,
Kind::NovaPublicParams,
);
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(&instance).unwrap();

let date = env!("VERGEN_GIT_COMMIT_DATE");
let sha = env!("VERGEN_GIT_SHA");
let parameter = format!("{},{},steps={}", date, sha, folding_steps);

c.bench_with_input(
BenchmarkId::new(prove_params.name(), parameter),
&prove_params,
|b, prove_params| {
let store = Store::default();

let env = empty_sym_env(&store);
let ptr = fib::<pasta_curves::Fq>(&store, state.clone());
let prover = NovaProver::new(prove_params.reduction_count, lang_pallas.clone());

let frames = &prover
.get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone())
.unwrap();

// Here we split the proving step by first generating the recursive snark,
// then have `criterion` only bench the rest of the folding steps
let (recursive_snark, circuits, z0, _zi, _num_steps) = prover
.recursive_snark(&pp, frames, &store, &lang_rc)
.unwrap();

b.iter_batched(
|| (recursive_snark.clone(), z0.clone(), lang_rc.clone()),
|(recursive_snark, z0, lang_rc)| {
let result = Proof::prove_recursively(
&pp,
&store,
Some(recursive_snark),
&circuits,
reduction_count,
z0,
lang_rc,
);
let _ = black_box(result);
},
BatchSize::LargeInput,
)
},
);
format!("{date}:{sha}:Fibonacci-rc={}", self.reduction_count)
}
}

mod lem {
use lurk::lem::{eval::evaluate, multiframe::MultiFrame, pointers::Ptr, store::Store};

use super::*;

fn fib<F: LurkField>(store: &Store<F>, state: Rc<RefCell<State>>) -> Ptr<F> {
let program = r#"
(letrec ((next (lambda (a b) (next b (+ a b))))
(fib (next 0 1)))
(fib))
"#;

store.read(state, program).unwrap()
}

pub fn prove<M: measurement::Measurement>(
prove_params: ProveParams,
c: &mut BenchmarkGroup<'_, M>,
state: &Rc<RefCell<State>>,
) {
let ProveParams {
folding_steps,
reduction_count,
version,
} = prove_params;

assert_eq!(version, Version::LEM);
let limit = reduction_count * (folding_steps + 1);

// Track the number of `folded iterations / sec`
c.throughput(criterion::Throughput::Elements(
(reduction_count * folding_steps) as u64,
));

let lang_pallas = Lang::<pallas::Scalar, Coproc<pallas::Scalar>>::new();
let lang_rc = Arc::new(lang_pallas.clone());

// use cached public params
let instance: Instance<
'_,
pasta_curves::Fq,
Coproc<pasta_curves::Fq>,
MultiFrame<'_, pasta_curves::Fq, Coproc<pasta_curves::Fq>>,
> = Instance::new(
reduction_count,
lang_rc.clone(),
true,
Kind::NovaPublicParams,
);
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(&instance).unwrap();

let date = env!("VERGEN_GIT_COMMIT_DATE");
let sha = env!("VERGEN_GIT_SHA");
let parameter = format!("{},{},steps={}", date, sha, folding_steps);

c.bench_with_input(
BenchmarkId::new(prove_params.name(), parameter),
&prove_params,
|b, prove_params| {
let store = Store::default();

let ptr = fib::<pasta_curves::Fq>(&store, state.clone());
let prover = NovaProver::new(prove_params.reduction_count, lang_pallas.clone());

let frames = &evaluate::<pasta_curves::Fq, Coproc<pasta_curves::Fq>>(
None, ptr, &store, limit,
)
.unwrap()
.0;

// Here we split the proving step by first generating the recursive snark,
// then have `criterion` only bench the rest of the folding steps
let (recursive_snark, circuits, z0, _zi, _num_steps) = prover
.recursive_snark(&pp, frames, &store, &lang_rc)
.unwrap();

b.iter_batched(
|| (recursive_snark.clone(), z0.clone(), lang_rc.clone()),
|(recursive_snark, z0, lang_rc)| {
let result = Proof::prove_recursively(
&pp,
&store,
Some(recursive_snark),
&circuits,
reduction_count,
z0,
lang_rc,
);
let _ = black_box(result);
},
BatchSize::LargeInput,
)
},
);
}
fn fibo_prove<M: measurement::Measurement>(
prove_params: ProveParams,
c: &mut BenchmarkGroup<'_, M>,
state: &Rc<RefCell<State>>,
) {
let ProveParams {
fib_n,
reduction_count,
} = prove_params;

let limit = fib_limit(fib_n, reduction_count);
let lang_pallas = Lang::<pallas::Scalar, Coproc<pallas::Scalar>>::new();
let lang_rc = Arc::new(lang_pallas.clone());

// use cached public params
let instance = Instance::new(
reduction_count,
lang_rc.clone(),
true,
Kind::NovaPublicParams,
);
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(&instance).unwrap();

c.bench_with_input(
BenchmarkId::new(prove_params.name(), fib_n),
&prove_params,
|b, prove_params| {
let store = Store::default();

let env = empty_sym_env(&store);
let ptr = fib::<pasta_curves::Fq>(
&store,
state.clone(),
black_box(prove_params.fib_n as u64),
);
let prover = NovaProver::new(prove_params.reduction_count, lang_pallas.clone());

let frames = &prover
.get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone())
.unwrap();

b.iter_batched(
|| (frames, lang_rc.clone()),
|(frames, lang_rc)| {
let result = prover.prove(&pp, frames, &store, &lang_rc);
let _ = black_box(result);
},
BatchSize::LargeInput,
)
},
);
}

fn fib_bench(c: &mut Criterion) {
fn fibonacci_prove(c: &mut Criterion) {
set_bench_config();
tracing::debug!("{:?}", lurk::config::LURK_CONFIG);
let reduction_counts = [100, 600, 700, 800, 900];
let folding_step_sizes = [2, 4, 8];

let mut group: BenchmarkGroup<'_, _> = c.benchmark_group("Fibonacci");
let batch_sizes = [100, 200];
let mut group: BenchmarkGroup<'_, _> = c.benchmark_group("Prove");
group.sampling_mode(SamplingMode::Flat); // This can take a *while*
group.sample_size(10);

let state = State::init_lurk_state().rccell();

for folding_steps in folding_step_sizes.iter() {
for reduction_count in reduction_counts.iter() {
let alpha_params = ProveParams {
folding_steps: *folding_steps,
reduction_count: *reduction_count,
version: Version::ALPHA,
};
alpha::prove(alpha_params, &mut group, &state);
}
}

for folding_steps in folding_step_sizes.iter() {
for fib_n in batch_sizes.iter() {
for reduction_count in reduction_counts.iter() {
let lem_params = ProveParams {
folding_steps: *folding_steps,
let prove_params = ProveParams {
fib_n: *fib_n,
reduction_count: *reduction_count,
version: Version::LEM,
};
lem::prove(lem_params, &mut group, &state);
fibo_prove(prove_params, &mut group, &state);
}
}
}
Expand All @@ -275,7 +148,7 @@ cfg_if::cfg_if! {
.sample_size(10)
.with_profiler(pprof::criterion::PProfProfiler::new(100, pprof::criterion::Output::Flamegraph(None)));
targets =
fib_bench,
fibonacci_prove,
}
} else {
criterion_group! {
Expand All @@ -284,7 +157,7 @@ cfg_if::cfg_if! {
.measurement_time(Duration::from_secs(120))
.sample_size(10);
targets =
fib_bench,
fibonacci_prove,
}
}
}
Expand Down
Loading

0 comments on commit f00544e

Please sign in to comment.