Skip to content

Commit e50297d

Browse files
committed
Parallelise division function
1 parent 5bef51c commit e50297d

File tree

1 file changed

+59
-14
lines changed

1 file changed

+59
-14
lines changed

saffron/src/vid.rs

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ pub struct VIDProof {
3030
}
3131

3232
/// Divide `self` by the vanishing polynomial for the sub-domain, `X^{domain_size} - coeff`.
33+
///
34+
/// coeff_powers are w^i starting with i = 0
3335
pub fn divide_by_sub_vanishing_poly(
3436
poly: &DensePolynomial<ScalarField>,
3537
domain_size: usize,
36-
coeff: ScalarField,
38+
coeff_powers: &[ScalarField],
3739
) -> DensePolynomial<ScalarField> {
3840
if poly.coeffs.len() < domain_size {
3941
// If degree(poly) < len(Domain), then the quotient is zero, and the entire polynomial is the remainder
@@ -48,16 +50,48 @@ pub fn divide_by_sub_vanishing_poly(
4850
// which can be computed using the following algorithm.
4951
//
5052

51-
// TODO parallelise
52-
let mut quotient_vec = poly.coeffs[domain_size..].to_vec();
53-
//println!("poly.len(): {:?}", poly.len());
54-
//assert!(poly.len() / domain_size <= 2);
55-
for i in 1..(poly.len() / domain_size) {
56-
quotient_vec
57-
.iter_mut()
58-
.zip(&poly.coeffs[domain_size * (i + 1)..])
59-
.for_each(|(s, c)| *s += c * &(coeff.pow([i as u64])));
60-
}
53+
let quotient_vec = (0..(poly.len() / domain_size))
54+
.into_par_iter()
55+
.map(|i| poly.coeffs[domain_size * (i + 1)..].to_vec())
56+
.zip(coeff_powers)
57+
.map(|(poly, pow)| poly.into_iter().map(|v| v * pow).collect::<Vec<_>>())
58+
.reduce_with(|mut l, r| {
59+
for i in 0..std::cmp::min(l.len(), r.len()) {
60+
l[i] += r[i]
61+
}
62+
l
63+
})
64+
.unwrap();
65+
66+
// // TODO parallelise
67+
// let mut quotient_vec = poly.coeffs[domain_size..].to_vec();
68+
//
69+
// //println!("poly.len(): {:?}", poly.len());
70+
// //assert!(poly.len() / domain_size <= 2);
71+
//
72+
// if poly.len() / domain_size > 1 {
73+
// let mut addons: Vec<_> = (1..(poly.len() / domain_size))
74+
// .into_par_iter()
75+
// .map(|i| poly.coeffs[domain_size * (i + 1)..].to_vec())
76+
// .zip(coeff_powers)
77+
// .map(|(poly, pow)| poly.into_iter().map(|v| v * pow).collect::<Vec<_>>())
78+
// .reduce_with(|mut l, r| {
79+
// for i in 0..std::cmp::min(l.len(), r.len()) {
80+
// l[i] += r[i]
81+
// }
82+
// l
83+
// })
84+
// .unwrap();
85+
//
86+
// for i in 1..(poly.len() / domain_size) {
87+
// quotient_vec
88+
// .iter_mut()
89+
// .zip(&poly.coeffs[domain_size * (i + 1)..])
90+
// .for_each(|(s, c)| *s += c * &(coeff_powers[i]));
91+
// }
92+
// }
93+
// .reduce_with(|mut l, r| &l * &r)
94+
// .unwrap()
6195

6296
let quotient = DensePolynomial::from_coefficients_vec(quotient_vec);
6397
quotient
@@ -222,6 +256,10 @@ where
222256

223257
let coset_omega = all_omegas[node_ix * per_node_size].clone();
224258

259+
let coeff_powers: Vec<_> = (0..proofs_number)
260+
.map(|i| coset_omega.pow([i as u64]))
261+
.collect();
262+
225263
for j in indices.iter() {
226264
assert!(all_divisors[node_ix].evaluate(&all_omegas[*j]) == ScalarField::zero());
227265
}
@@ -248,7 +286,7 @@ where
248286
let quotient = divide_by_sub_vanishing_poly(
249287
&numerator_eval_interpolated,
250288
per_node_size,
251-
coset_omega,
289+
&coeff_powers,
252290
);
253291
// let (quotient, res) = DenseOrSparsePolynomial::divide_with_q_and_r(
254292
// &From::from(numerator_eval_interpolated),
@@ -687,9 +725,16 @@ mod tests {
687725
}
688726
}
689727

728+
let coeff_powers: Vec<_> = (0..proofs_number)
729+
.map(|i| coset_omega.pow([i as u64]))
730+
.collect();
731+
690732
println!("Division");
691-
let quot =
692-
divide_by_sub_vanishing_poly(&numerator_eval_interpolated, per_node_size, coset_omega);
733+
let quot = divide_by_sub_vanishing_poly(
734+
&numerator_eval_interpolated,
735+
per_node_size,
736+
&coeff_powers,
737+
);
693738

694739
println!(
695740
"Degree of numerator_eval_interpolated: {:?}",

0 commit comments

Comments
 (0)