From 3e132187918fedfdf5b26252468a8cbed731f8a5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Tue, 21 Jan 2025 11:06:37 +0100 Subject: [PATCH] added benchmarks for digit decomp --- math/benches/operations.rs | 180 +++++++++++++++++++++++++++++-------- math/tests/ring_switch.rs | 2 - 2 files changed, 144 insertions(+), 38 deletions(-) diff --git a/math/benches/operations.rs b/math/benches/operations.rs index 09b0010..a01ca50 100644 --- a/math/benches/operations.rs +++ b/math/benches/operations.rs @@ -1,25 +1,24 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use math::modulus::montgomery::Montgomery; -use math::modulus::VectorOperations; -use math::modulus::ONCE; +use math::modulus::{WordOps, ONCE}; +use math::poly::Poly; use math::ring::Ring; -use math::CHUNK; -fn va_add_vb_into_vb(c: &mut Criterion) { - fn runner(r: Ring) -> Box { - let mut p0: math::poly::Poly = r.new_poly(); - let mut p1: math::poly::Poly = r.new_poly(); - for i in 0..p0.n() { - p0.0[i] = i as u64; - p1.0[i] = i as u64; +fn a_add_b_into_b(c: &mut Criterion) { + fn runner(ring: Ring) -> Box { + let mut a: Poly = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = i as u64; + b.0[i] = i as u64; } Box::new(move || { - r.modulus.va_add_vb_into_vb::(&p0.0, &mut p1.0); + ring.a_add_b_into_b::(&a, &mut b); }) } let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = - c.benchmark_group("va_add_vb_into_vb"); + c.benchmark_group("a_add_b_into_b"); for log_n in 11..17 { let n: usize = 1 << log_n as usize; let q_base: u64 = 0x1fffffffffe00001u64; @@ -33,22 +32,21 @@ fn va_add_vb_into_vb(c: &mut Criterion) { } } -fn va_mont_mul_vb_into_vb(c: &mut Criterion) { - fn runner(r: Ring) -> Box { - let mut p0: math::poly::Poly> = r.new_poly(); - let mut p1: math::poly::Poly = r.new_poly(); - for i in 0..p0.n() { - p0.0[i] = r.modulus.montgomery.prepare::(i as u64); - p1.0[i] = i as u64; +fn a_mul_b_montgomery_into_a(c: &mut Criterion) { + fn runner(ring: Ring) -> Box { + let mut a: Poly> = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = ring.modulus.montgomery.prepare::(i as u64); + b.0[i] = i as u64; } Box::new(move || { - r.modulus - .va_mont_mul_vb_into_vb::(&p0.0, &mut p1.0); + ring.a_mul_b_montgomery_into_a::(&a, &mut b); }) } let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = - c.benchmark_group("va_mont_mul_vb_into_vb"); + c.benchmark_group("a_mul_b_montgomery_into_a"); for log_n in 11..17 { let n: usize = 1 << log_n as usize; let q_base: u64 = 0x1fffffffffe00001u64; @@ -62,23 +60,22 @@ fn va_mont_mul_vb_into_vb(c: &mut Criterion) { } } -fn va_mont_mul_vb_into_vc(c: &mut Criterion) { - fn runner(r: Ring) -> Box { - let mut p0: math::poly::Poly> = r.new_poly(); - let mut p1: math::poly::Poly = r.new_poly(); - let mut p2: math::poly::Poly = r.new_poly(); - for i in 0..p0.n() { - p0.0[i] = r.modulus.montgomery.prepare::(i as u64); - p1.0[i] = i as u64; +fn a_mul_b_montgomery_into_c(c: &mut Criterion) { + fn runner(ring: Ring) -> Box { + let mut a: Poly> = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + let mut c: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = ring.modulus.montgomery.prepare::(i as u64); + b.0[i] = i as u64; } Box::new(move || { - r.modulus - .va_mont_mul_vb_into_vc::(&p0.0, &p1.0, &mut p2.0); + ring.a_mul_b_montgomery_into_c::(&a, &b, &mut c); }) } let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = - c.benchmark_group("va_mont_mul_vb_into_vc"); + c.benchmark_group("a_mul_b_montgomery_into_c"); for log_n in 11..17 { let n: usize = 1 << log_n as usize; let q_base: u64 = 0x1fffffffffe00001u64; @@ -92,10 +89,121 @@ fn va_mont_mul_vb_into_vc(c: &mut Criterion) { } } +fn a_ith_digit_unsigned_base_scalar_b_into_c(c: &mut Criterion) { + fn runner(ring: Ring, base: usize, d: usize) -> Box { + let mut a: Poly> = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = i as u64; + } + Box::new(move || { + (0..d).for_each(|i| { + ring.a_ith_digit_unsigned_base_scalar_b_into_c(i, &a, &base, &mut b); + }) + }) + } + + let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = + c.benchmark_group("a_ith_digit_unsigned_base_scalar_b_into_c"); + for log_n in 11..12 { + let n: usize = 1 << log_n as usize; + let q_base: u64 = 0x1fffffffffe00001u64; + let q_power: usize = 1usize; + let ring: Ring = Ring::::new(n, q_base, q_power); + let base: usize = 7; + let logq: usize = ring.modulus.q.log2(); + let d: usize = (logq + base - 1) / base; + let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), { + runner(ring, base, d) + })]; + for (name, mut runner) in runners { + let id = BenchmarkId::new(name, n); + b.bench_with_input(id, &(), |b, _| b.iter(&mut runner)); + } + } +} + +fn a_ith_digit_signed_base_scalar_b_into_c_balanced_false(c: &mut Criterion) { + fn runner(ring: Ring, base: usize, d: usize) -> Box { + let mut a: Poly> = ring.new_poly(); + let mut carry: Poly = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = i as u64; + } + Box::new(move || { + (0..d).for_each(|i| { + ring.a_ith_digit_signed_base_scalar_b_into_c::( + i, &a, &base, &mut carry, &mut b, + ); + }) + }) + } + + let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = + c.benchmark_group("a_ith_digit_signed_base_scalar_b_into_c::"); + for log_n in 11..12 { + let n: usize = 1 << log_n as usize; + let q_base: u64 = 0x1fffffffffe00001u64; + let q_power: usize = 1usize; + let ring: Ring = Ring::::new(n, q_base, q_power); + let base: usize = 7; + let logq: usize = ring.modulus.q.log2(); + let d: usize = (logq + base - 1) / base; + let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), { + runner(ring, base, d) + })]; + for (name, mut runner) in runners { + let id = BenchmarkId::new(name, n); + b.bench_with_input(id, &(), |b, _| b.iter(&mut runner)); + } + } +} + +fn a_ith_digit_signed_base_scalar_b_into_c_balanced_true(c: &mut Criterion) { + fn runner(ring: Ring, base: usize, d: usize) -> Box { + let mut a: Poly> = ring.new_poly(); + let mut carry: Poly = ring.new_poly(); + let mut b: Poly = ring.new_poly(); + for i in 0..ring.n() { + a.0[i] = i as u64; + } + Box::new(move || { + (0..d).for_each(|i| { + ring.a_ith_digit_signed_base_scalar_b_into_c::( + i, &a, &base, &mut carry, &mut b, + ); + }) + }) + } + + let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = + c.benchmark_group("a_ith_digit_signed_base_scalar_b_into_c::"); + for log_n in 11..12 { + let n: usize = 1 << log_n as usize; + let q_base: u64 = 0x1fffffffffe00001u64; + let q_power: usize = 1usize; + let ring: Ring = Ring::::new(n, q_base, q_power); + let base: usize = 7; + let logq: usize = ring.modulus.q.log2(); + let d: usize = (logq + base - 1) / base; + let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), { + runner(ring, base, d) + })]; + for (name, mut runner) in runners { + let id = BenchmarkId::new(name, n); + b.bench_with_input(id, &(), |b, _| b.iter(&mut runner)); + } + } +} + criterion_group!( benches, - va_add_vb_into_vb, - va_mont_mul_vb_into_vb, - va_mont_mul_vb_into_vc + a_add_b_into_b, + a_mul_b_montgomery_into_a, + a_mul_b_montgomery_into_c, + a_ith_digit_unsigned_base_scalar_b_into_c, + a_ith_digit_signed_base_scalar_b_into_c_balanced_false, + a_ith_digit_signed_base_scalar_b_into_c_balanced_true, ); criterion_main!(benches); diff --git a/math/tests/ring_switch.rs b/math/tests/ring_switch.rs index 6be79ec..48366e2 100644 --- a/math/tests/ring_switch.rs +++ b/math/tests/ring_switch.rs @@ -1,5 +1,3 @@ -use itertools::izip; -use math::automorphism::AutoPerm; use math::poly::Poly; use math::ring::Ring;