Skip to content

Commit

Permalink
add benchmark case back
Browse files Browse the repository at this point in the history
  • Loading branch information
KimiWu123 committed Jul 11, 2024
1 parent 461eaab commit 26554f2
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 56 deletions.
161 changes: 161 additions & 0 deletions singer/benches/rv_add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#![allow(clippy::manual_memcpy)]
#![allow(clippy::needless_range_loop)]

use std::time::{Duration, Instant};

use ark_std::test_rng;
use const_env::from_env;
use criterion::*;

use ff_ext::{ff::Field, ExtensionField};
use gkr::structs::LayerWitness;
use goldilocks::GoldilocksExt2;
use itertools::Itertools;

cfg_if::cfg_if! {
if #[cfg(feature = "flamegraph")] {
criterion_group! {
name = op_rv_add;
config = Criterion::default().warm_up_time(Duration::from_millis(3000)).with_profiler(pprof::criterion::PProfProfiler::new(100, pprof::criterion::Output::Flamegraph(None)));
targets = bench_rv_add
}
} else {
criterion_group! {
name = op_rv_add;
config = Criterion::default().warm_up_time(Duration::from_millis(3000));
targets = bench_rv_add
}
}
}

criterion_main!(op_rv_add);

const NUM_SAMPLES: usize = 10;
#[from_env]
const RAYON_NUM_THREADS: usize = 8;

use singer::{
instructions::{
riscv_add::RVAddInstruction, Instruction, InstructionGraph, SingerCircuitBuilder,
},
scheme::GKRGraphProverState,
CircuitWiresIn, SingerGraphBuilder, SingerParams,
};
use singer_utils::structs::ChipChallenges;
use transcript::Transcript;

pub fn is_power_of_2(x: usize) -> bool {
(x != 0) && ((x & (x - 1)) == 0)
}

fn bench_rv_add(c: &mut Criterion) {
let max_thread_id = {
if !is_power_of_2(RAYON_NUM_THREADS) {
#[cfg(not(feature = "non_pow2_rayon_thread"))]
{
panic!("add --features non_pow2_rayon_thread to enable unsafe feature which support non pow of 2 rayon thread pool");
}

#[cfg(feature = "non_pow2_rayon_thread")]
{
use sumcheck::{local_thread_pool::create_local_pool_once, util::ceil_log2};
let max_thread_id = 1 << ceil_log2(RAYON_NUM_THREADS);
create_local_pool_once(1 << ceil_log2(RAYON_NUM_THREADS), true);
max_thread_id
}
} else {
RAYON_NUM_THREADS
}
};
let chip_challenges = ChipChallenges::default();
let circuit_builder =
SingerCircuitBuilder::<E>::new(chip_challenges).expect("circuit builder failed");

for instance_num_vars in 11..12 {
// expand more input size once runtime is acceptable
let mut group = c.benchmark_group(format!("rv_add_op_{}", instance_num_vars));
group.sample_size(NUM_SAMPLES);

// Benchmark the proving time
group.bench_function(
BenchmarkId::new("prove_keccak256", format!("keccak256_log2_{}", instance_num_vars)),
|b| {
b.iter_with_setup(
|| {
let mut rng = test_rng();
let singer_builder = SingerGraphBuilder::<E>::new();

let real_challenges = vec![E::random(&mut rng), E::random(&mut rng)];
(rng, singer_builder, real_challenges)
},
| (mut rng,mut singer_builder, real_challenges)| {

let size = RVAddInstruction::phase0_size();

let phase0: CircuitWiresIn<
<GoldilocksExt2 as ff_ext::ExtensionField>::BaseField,
> = vec![LayerWitness {
instances: (0..(1 << instance_num_vars))
.map(|_| {
(0..size)
.map(|_| {
<GoldilocksExt2 as ExtensionField>::BaseField::random(
&mut rng,
)
})
.collect_vec()
})
.collect_vec(),
}];


let timer = Instant::now();

let _ = RVAddInstruction::construct_graph_and_witness(
&mut singer_builder.graph_builder,
&mut singer_builder.chip_builder,
&circuit_builder.insts_circuits
[<RVAddInstruction as Instruction<E>>::OPCODE as usize],
vec![phase0],
&real_challenges,
1 << instance_num_vars,
&SingerParams::default(),
)
.expect("gkr graph construction failed");

let (graph, wit) = singer_builder.graph_builder.finalize_graph_and_witness();

println!(
"AddInstruction::construct_graph_and_witness, instance_num_vars = {}, time = {}",
instance_num_vars,
timer.elapsed().as_secs_f64()
);

let point = vec![E::random(&mut rng), E::random(&mut rng)];
let target_evals = graph.target_evals(&wit, &point);

let mut prover_transcript = &mut Transcript::new(b"Singer");

let timer = Instant::now();
let _ = GKRGraphProverState::prove(
&graph,
&wit,
&target_evals,
&mut prover_transcript,
(1 << instance_num_vars).min(max_thread_id),
)
.expect("prove failed");
println!(
"AddInstruction::prove, instance_num_vars = {}, time = {}",
instance_num_vars,
timer.elapsed().as_secs_f64()
);
});
},
);

group.finish();
}

type E = GoldilocksExt2;
}
3 changes: 3 additions & 0 deletions singer/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ pub(crate) fn construct_instruction_circuits<E: ExtensionField>(
0x91 => SwapInstruction::<2>::construct_circuits(challenges),
0x93 => SwapInstruction::<4>::construct_circuits(challenges),
0xF3 => ReturnInstruction::construct_circuits(challenges),

// RISC-V iSA
0x33 => RVAddInstruction::construct_circuits(challenges),
_ => Ok(vec![]), // TODO: Add more instructions.
}
}
Expand Down
117 changes: 61 additions & 56 deletions singer/src/instructions/riscv_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,60 +336,65 @@ mod test {
);
}

// fn bench_add_instruction_helper<E: ExtensionField>(instance_num_vars: usize) {
// let chip_challenges = ChipChallenges::default();
// let circuit_builder =
// SingerCircuitBuilder::<E>::new(chip_challenges).expect("circuit builder failed");
// let mut singer_builder = SingerGraphBuilder::<E>::new();

// let mut rng = test_rng();
// let size = RVAddInstruction::phase0_size();
// let phase0: CircuitWiresIn<E::BaseField> = vec![LayerWitness {
// instances: (0..(1 << instance_num_vars))
// .map(|_| {
// (0..size)
// .map(|_| E::BaseField::random(&mut rng))
// .collect_vec()
// })
// .collect_vec(),
// }];

// let real_challenges = vec![E::random(&mut rng), E::random(&mut rng)];

// let timer = Instant::now();

// let _ = RVAddInstruction::construct_graph_and_witness(
// &mut singer_builder.graph_builder,
// &mut singer_builder.chip_builder,
// &circuit_builder.insts_circuits[<RVAddInstruction as InstructionRV<E>>::OPCODE as
// usize], vec![phase0],
// &real_challenges,
// 1 << instance_num_vars,
// &SingerParams::default(),
// )
// .expect("gkr graph construction failed");

// let (graph, wit) = singer_builder.graph_builder.finalize_graph_and_witness();

// println!(
// "RVAddInstruction::construct_graph_and_witness, instance_num_vars = {}, time = {}",
// instance_num_vars,
// timer.elapsed().as_secs_f64()
// );

// let point = vec![E::random(&mut rng), E::random(&mut rng)];
// let target_evals = graph.target_evals(&wit, &point);

// let mut prover_transcript = &mut Transcript::new(b"Singer");

// let timer = Instant::now();
// let _ = GKRGraphProverState::prove(&graph, &wit, &target_evals, &mut prover_transcript,
// 1) .expect("prove failed"); println!( "RVAddInstruction::prove, instance_num_vars = {}, time
// = {}", instance_num_vars, timer.elapsed().as_secs_f64() );
// }

// #[test]
// fn bench_add_instruction() {
// bench_add_instruction_helper::<GoldilocksExt2>(10);
// }
fn bench_add_instruction_helper<E: ExtensionField>(instance_num_vars: usize) {
let chip_challenges = ChipChallenges::default();
let circuit_builder =
SingerCircuitBuilder::<E>::new(chip_challenges).expect("circuit builder failed");
let mut singer_builder = SingerGraphBuilder::<E>::new();

let mut rng = test_rng();
let size = RVAddInstruction::phase0_size();
let phase0: CircuitWiresIn<E::BaseField> = vec![LayerWitness {
instances: (0..(1 << instance_num_vars))
.map(|_| {
(0..size)
.map(|_| E::BaseField::random(&mut rng))
.collect_vec()
})
.collect_vec(),
}];

let real_challenges = vec![E::random(&mut rng), E::random(&mut rng)];

let timer = Instant::now();

let _ = RVAddInstruction::construct_graph_and_witness(
&mut singer_builder.graph_builder,
&mut singer_builder.chip_builder,
&circuit_builder.insts_circuits[<RVAddInstruction as Instruction<E>>::OPCODE as usize],
vec![phase0],
&real_challenges,
1 << instance_num_vars,
&SingerParams::default(),
)
.expect("gkr graph construction failed");

let (graph, wit) = singer_builder.graph_builder.finalize_graph_and_witness();

println!(
"RVAddInstruction::construct_graph_and_witness, instance_num_vars = {}, time = {}",
instance_num_vars,
timer.elapsed().as_secs_f64()
);

let point = vec![E::random(&mut rng), E::random(&mut rng)];
let target_evals = graph.target_evals(&wit, &point);

let mut prover_transcript = &mut Transcript::new(b"Singer");

let timer = Instant::now();
let _ = GKRGraphProverState::prove(&graph, &wit, &target_evals, &mut prover_transcript, 1)
.expect("prove failed");
println!(
"RVAddInstruction::prove, instance_num_vars = {}, time
= {}",
instance_num_vars,
timer.elapsed().as_secs_f64()
);
}

#[test]
fn bench_add_instruction() {
bench_add_instruction_helper::<GoldilocksExt2>(10);
}
}

0 comments on commit 26554f2

Please sign in to comment.