Skip to content

Commit 398e18f

Browse files
diegokingstongabrielbosio
authored andcommitted
perf(fri): parallelize fold_evaluations_in_place with Rayon
Under the `parallel` feature, fold each conjugate pair concurrently using `par_chunks(2).zip(inv_twiddles.par_iter())`, collecting into a new Vec of half length. The sequential path (no `parallel` feature) is unchanged. This avoids the index aliasing issue from an in-place interleaved write.
1 parent ada4503 commit 398e18f

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

crypto/stark/src/fri/fri_functions.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,37 @@ pub fn fold_evaluations_in_place<F: IsSubFieldOf<E>, E: IsField>(
1818
inv_twiddles: &[FieldElement<F>],
1919
) {
2020
let half = evals.len() / 2;
21-
for j in 0..half {
22-
let lo = &evals[2 * j];
23-
let hi = &evals[2 * j + 1];
24-
let sum = lo + hi;
25-
let diff = lo - hi;
26-
evals[j] = &sum + &(&inv_twiddles[j] * &(zeta * &diff));
21+
22+
#[cfg(feature = "parallel")]
23+
{
24+
use rayon::prelude::*;
25+
// Evaluations are stored interleaved: pairs (evals[2j], evals[2j+1]).
26+
// Fold each pair in parallel, collecting into a new Vec of half length.
27+
let folded: Vec<FieldElement<E>> = evals
28+
.par_chunks(2)
29+
.zip(inv_twiddles.par_iter())
30+
.map(|(pair, tw)| {
31+
let lo = &pair[0];
32+
let hi = &pair[1];
33+
let sum = lo + hi;
34+
let diff = lo - hi;
35+
&sum + &(tw * &(zeta * &diff))
36+
})
37+
.collect();
38+
*evals = folded;
39+
}
40+
41+
#[cfg(not(feature = "parallel"))]
42+
{
43+
for j in 0..half {
44+
let lo = &evals[2 * j];
45+
let hi = &evals[2 * j + 1];
46+
let sum = lo + hi;
47+
let diff = lo - hi;
48+
evals[j] = &sum + &(&inv_twiddles[j] * &(zeta * &diff));
49+
}
50+
evals.truncate(half);
2751
}
28-
evals.truncate(half);
2952
}
3053

3154
/// Compute inverse twiddle factors for evaluation-form FRI folding.

0 commit comments

Comments
 (0)