Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast Coset Extrapolate #212

Merged
merged 18 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
bench: Update benchmark
 - Apples-to-apples: extract preprocessing out of intt-then-eval.
 - Include dispatcher.
 - Dop barycentric.
  • Loading branch information
aszepieniec committed May 22, 2024
commit 6abebca97c4d27f3b8a1c44781fb4d683b2fe4eb
37 changes: 28 additions & 9 deletions twenty-first/benches/extrapolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,21 @@ criterion_group!(
fn intt_then_evaluate(
codeword: &[BFieldElement],
offset: BFieldElement,
points: &[BFieldElement],
zerofier_tree: &ZerofierTree<BFieldElement>,
shift_coefficients: &[BFieldElement],
tail_length: usize,
) -> Vec<BFieldElement> {
let omega = BFieldElement::primitive_root_of_unity(codeword.len() as u64).unwrap();
let log_domain_length = codeword.len().ilog2();
let mut coefficients = codeword.to_vec();
intt(&mut coefficients, omega, log_domain_length);
let polynomial: Polynomial<BFieldElement> =
Polynomial::new(coefficients).scale(offset.inverse());
polynomial.batch_evaluate(points)
let polynomial: Polynomial<BFieldElement> = Polynomial::new(coefficients)
.scale(offset.inverse())
.reduce_by_ntt_friendly_modulus(shift_coefficients, tail_length);
polynomial.divide_and_conquer_batch_evaluate(zerofier_tree)
}

#[allow(dead_code)]
aszepieniec marked this conversation as resolved.
Show resolved Hide resolved
fn iterative_barycentric(
codeword: &[BFieldElement],
points: &[BFieldElement],
Expand Down Expand Up @@ -164,20 +168,30 @@ fn extrapolation<const SIZE: usize, const NUM_POINTS: usize>(c: &mut Criterion)
let codeword = random_elements(SIZE);
let offset = BFieldElement::new(7);
let eval_points: Vec<BFieldElement> = random_elements(NUM_POINTS);

let zerofier_tree = ZerofierTree::new_from_domain(&eval_points);
let modulus = zerofier_tree.zerofier();
let (even_zerofiers, odd_zerofiers, shift_coefficients, tail_length) =
even_and_odd_zerofiers_and_shift_coefficients_with_tail_length(SIZE, offset, &modulus);

let id = BenchmarkId::new("INTT-then-Evaluate", log2_of_size);
group.bench_function(id, |b| {
b.iter(|| intt_then_evaluate(&codeword, offset, &eval_points))
b.iter(|| {
intt_then_evaluate(
&codeword,
offset,
&zerofier_tree,
&shift_coefficients,
tail_length,
)
})
});

let id = BenchmarkId::new("Iterative Barycentric", log2_of_size);
group.bench_function(id, |b| {
b.iter(|| iterative_barycentric(&codeword, &eval_points))
});
// Iterative barycentric is never close to faster.
// let id = BenchmarkId::new("Iterative Barycentric", log2_of_size);
// group.bench_function(id, |b| {
// b.iter(|| iterative_barycentric(&codeword, &eval_points))
// });
aszepieniec marked this conversation as resolved.
Show resolved Hide resolved

let id = BenchmarkId::new("Fast Codeword Extrapolation", log2_of_size);
group.bench_function(id, |b| {
Expand All @@ -194,5 +208,10 @@ fn extrapolation<const SIZE: usize, const NUM_POINTS: usize>(c: &mut Criterion)
})
});

let id = BenchmarkId::new("Dispatcher (includes preprocessing)", log2_of_size);
group.bench_function(id, |b| {
b.iter(|| Polynomial::coset_extrapolate(offset, &codeword, &eval_points))
});

group.finish();
}
9 changes: 8 additions & 1 deletion twenty-first/src/math/polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,11 @@ where
///
/// This method uses NTT-based multiplication, meaning that the unstructured
/// part of the structured multiple must be given in NTT-domain.
fn reduce_by_ntt_friendly_modulus(&self, shift_ntt: &[FF], tail_length: usize) -> Self {
///
/// This function is marked `pub` for benchmarking. Not considered part of
/// the public API
#[doc(hidden)]
pub fn reduce_by_ntt_friendly_modulus(&self, shift_ntt: &[FF], tail_length: usize) -> Self {
// m = tail_length
let domain_length = shift_ntt.len();
assert!(domain_length.is_power_of_two());
Expand Down Expand Up @@ -1580,6 +1584,9 @@ where
}
}

/// Marked `pub` for benchmarking purposes. Not considered part of the
/// public API.
#[doc(hidden)]
fn naive_coset_extrapolate_preprocessing(points: &[FF]) -> (ZerofierTree<FF>, Vec<FF>, usize) {
let zerofier_tree = ZerofierTree::new_from_domain(points);
let (shift_coefficients, tail_length) =
Expand Down