Skip to content

Commit

Permalink
Merge pull request #216 from filecoin-project/perf-lc
Browse files Browse the repository at this point in the history
perf: Optimize LinearCombination
  • Loading branch information
dignifiedquire committed Sep 27, 2021
2 parents 5b736e5 + 61af305 commit f46302e
Show file tree
Hide file tree
Showing 9 changed files with 482 additions and 256 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ rand = "0.8"
rayon = "1.5.0"
memmap = "0.7.0"
thiserror = "1.0.10"
rustc-hash = "1.1.0"
num_cpus = "1"
crossbeam-channel = "0.5.0"
digest = "0.9.0"
Expand Down
6 changes: 3 additions & 3 deletions src/gadgets/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ impl<E: Engine> From<AllocatedNum<E>> for Num<E> {
fn from(num: AllocatedNum<E>) -> Num<E> {
Num {
value: num.value,
lc: LinearCombination::<E>::zero() + num.variable,
lc: LinearCombination::<E>::from_variable(num.variable),
}
}
}
Expand Down Expand Up @@ -435,7 +435,7 @@ impl<E: Engine> Num<E> {
}

pub fn scale(mut self, scalar: E::Fr) -> Self {
for (_variable, fr) in self.lc.0.iter_mut() {
for (_variable, fr) in self.lc.iter_mut() {
fr.mul_assign(&scalar);
}

Expand Down Expand Up @@ -661,7 +661,7 @@ mod test {
assert_eq!(scaled_value, scaled_num.value.unwrap());

// Each variable has the expected coefficient, the sume of those added by its Index.
scaled_num.lc.0.iter().for_each(|(var, coeff)| match var.0 {
scaled_num.lc.iter().for_each(|(var, coeff)| match var.0 {
Index::Aux(i) => {
let mut tmp = expected_sums[i];
tmp.mul_assign(&scalar);
Expand Down
4 changes: 2 additions & 2 deletions src/gadgets/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Ord for OrderedVariable {

fn proc_lc<E: Engine>(terms: &LinearCombination<E>) -> BTreeMap<OrderedVariable, E::Fr> {
let mut map = BTreeMap::new();
for (&var, &coeff) in terms.0.iter() {
for (var, &coeff) in terms.iter() {
map.entry(OrderedVariable(var))
.or_insert_with(E::Fr::zero)
.add_assign(&coeff);
Expand Down Expand Up @@ -124,7 +124,7 @@ fn eval_lc<E: Engine>(
) -> E::Fr {
let mut acc = E::Fr::zero();

for (&var, coeff) in terms.0.iter() {
for (var, coeff) in terms.iter() {
let mut tmp = match var.get_unchecked() {
Index::Input(index) => inputs[index].0,
Index::Aux(index) => aux[index].0,
Expand Down
6 changes: 3 additions & 3 deletions src/groth16/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ impl<E: Engine> ConstraintSystem<E> for KeypairAssembly<E> {
aux: &mut [Vec<(E::Fr, usize)>],
this_constraint: usize,
) {
for (index, coeff) in l.0 {
for (index, coeff) in l.iter() {
match index {
Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)),
Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)),
Variable(Index::Input(id)) => inputs[id].push((*coeff, this_constraint)),
Variable(Index::Aux(id)) => aux[id].push((*coeff, this_constraint)),
}
}
}
Expand Down
86 changes: 30 additions & 56 deletions src/groth16/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,6 @@ use log::{debug, info};
#[cfg(any(feature = "cuda", feature = "opencl"))]
use crate::gpu::PriorityLock;

fn eval<E: Engine>(
lc: &LinearCombination<E>,
mut input_density: Option<&mut DensityTracker>,
mut aux_density: Option<&mut DensityTracker>,
input_assignment: &[E::Fr],
aux_assignment: &[E::Fr],
) -> E::Fr {
let mut acc = E::Fr::zero();

for (&index, &coeff) in lc.0.iter() {
let mut tmp;

match index {
Variable(Index::Input(i)) => {
tmp = input_assignment[i];
if let Some(ref mut v) = input_density {
v.inc(i);
}
}
Variable(Index::Aux(i)) => {
tmp = aux_assignment[i];
if let Some(ref mut v) = aux_density {
v.inc(i);
}
}
}

if coeff == E::Fr::one() {
acc.add_assign(&tmp);
} else {
tmp.mul_assign(&coeff);
acc.add_assign(&tmp);
}
}

acc
}

struct ProvingAssignment<E: Engine> {
// Density of queries
a_aux_density: DensityTracker,
Expand Down Expand Up @@ -180,34 +142,43 @@ impl<E: Engine> ConstraintSystem<E> for ProvingAssignment<E> {
let b = b(LinearCombination::zero());
let c = c(LinearCombination::zero());

self.a.push(eval(
&a,
let input_assignment = &self.input_assignment;
let aux_assignment = &self.aux_assignment;
let a_aux_density = &mut self.a_aux_density;
let b_input_density = &mut self.b_input_density;
let b_aux_density = &mut self.b_aux_density;

let a_res = a.eval(
// Inputs have full density in the A query
// because there are constraints of the
// form x * 0 = 0 for each input.
None,
Some(&mut self.a_aux_density),
&self.input_assignment,
&self.aux_assignment,
));
self.b.push(eval(
&b,
Some(&mut self.b_input_density),
Some(&mut self.b_aux_density),
&self.input_assignment,
&self.aux_assignment,
));
self.c.push(eval(
&c,
Some(a_aux_density),
input_assignment,
aux_assignment,
);

let b_res = b.eval(
Some(b_input_density),
Some(b_aux_density),
input_assignment,
aux_assignment,
);

let c_res = c.eval(
// There is no C polynomial query,
// though there is an (beta)A + (alpha)B + C
// query for all aux variables.
// However, that query has full density.
None,
None,
&self.input_assignment,
&self.aux_assignment,
));
input_assignment,
aux_assignment,
);

self.a.push(a_res);
self.b.push(b_res);
self.c.push(c_res);
}

fn push_namespace<NR, N>(&mut self, _: N)
Expand Down Expand Up @@ -611,6 +582,7 @@ where
E: Engine,
C: Circuit<E> + Send,
{
let start = Instant::now();
let mut provers = circuits
.into_par_iter()
.map(|circuit| -> Result<_, SynthesisError> {
Expand All @@ -628,6 +600,8 @@ where
})
.collect::<Result<Vec<_>, _>>()?;

info!("synthesis time: {:?}", start.elapsed());

// Start fft/multiexp prover timer
let start = Instant::now();
info!("starting proof timer");
Expand Down
Loading

0 comments on commit f46302e

Please sign in to comment.