poulpy/math/benches/operations.rs
math/benches/operations.rsRaw
1use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
2use math::modulus::montgomery::Montgomery;
3use math::modulus::{WordOps, ONCE};
4use math::poly::Poly;
5use math::ring::Ring;
6
7fn a_add_b_into_b(c: &mut Criterion) {
8 fn runner(ring: Ring<u64>) -> Box<dyn FnMut()> {
9 let mut a: Poly<u64> = ring.new_poly();
10 let mut b: Poly<u64> = ring.new_poly();
11 for i in 0..ring.n() {
12 a.0[i] = i as u64;
13 b.0[i] = i as u64;
14 }
15 Box::new(move || {
16 ring.a_add_b_into_b::<ONCE>(&a, &mut b);
17 })
18 }
19
20 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
21 c.benchmark_group("a_add_b_into_b");
22 for log_n in 11..17 {
23 let n: usize = 1 << log_n as usize;
24 let q_base: u64 = 0x1fffffffffe00001u64;
25 let q_power: usize = 1usize;
26 let r: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
27 let runners = [("prime", { runner(r) })];
28 for (name, mut runner) in runners {
29 let id = BenchmarkId::new(name, n);
30 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
31 }
32 }
33}
34
35fn a_mul_b_montgomery_into_a(c: &mut Criterion) {
36 fn runner(ring: Ring<u64>) -> Box<dyn FnMut()> {
37 let mut a: Poly<Montgomery<u64>> = ring.new_poly();
38 let mut b: Poly<u64> = ring.new_poly();
39 for i in 0..ring.n() {
40 a.0[i] = ring.modulus.montgomery.prepare::<ONCE>(i as u64);
41 b.0[i] = i as u64;
42 }
43 Box::new(move || {
44 ring.a_mul_b_montgomery_into_a::<ONCE>(&a, &mut b);
45 })
46 }
47
48 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
49 c.benchmark_group("a_mul_b_montgomery_into_a");
50 for log_n in 11..17 {
51 let n: usize = 1 << log_n as usize;
52 let q_base: u64 = 0x1fffffffffe00001u64;
53 let q_power: usize = 1usize;
54 let r: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
55 let runners = [("prime", { runner(r) })];
56 for (name, mut runner) in runners {
57 let id = BenchmarkId::new(name, n);
58 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
59 }
60 }
61}
62
63fn a_mul_b_montgomery_into_c(c: &mut Criterion) {
64 fn runner(ring: Ring<u64>) -> Box<dyn FnMut()> {
65 let mut a: Poly<Montgomery<u64>> = ring.new_poly();
66 let mut b: Poly<u64> = ring.new_poly();
67 let mut c: Poly<u64> = ring.new_poly();
68 for i in 0..ring.n() {
69 a.0[i] = ring.modulus.montgomery.prepare::<ONCE>(i as u64);
70 b.0[i] = i as u64;
71 }
72 Box::new(move || {
73 ring.a_mul_b_montgomery_into_c::<ONCE>(&a, &b, &mut c);
74 })
75 }
76
77 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
78 c.benchmark_group("a_mul_b_montgomery_into_c");
79 for log_n in 11..17 {
80 let n: usize = 1 << log_n as usize;
81 let q_base: u64 = 0x1fffffffffe00001u64;
82 let q_power: usize = 1usize;
83 let r: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
84 let runners = [("prime", { runner(r) })];
85 for (name, mut runner) in runners {
86 let id = BenchmarkId::new(name, n);
87 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
88 }
89 }
90}
91
92fn a_ith_digit_unsigned_base_scalar_b_into_c(c: &mut Criterion) {
93 fn runner(ring: Ring<u64>, base: usize, d: usize) -> Box<dyn FnMut()> {
94 let mut a: Poly<Montgomery<u64>> = ring.new_poly();
95 let mut b: Poly<u64> = ring.new_poly();
96 for i in 0..ring.n() {
97 a.0[i] = i as u64;
98 }
99 Box::new(move || {
100 (0..d).for_each(|i| {
101 ring.a_ith_digit_unsigned_base_scalar_b_into_c(i, &a, &base, &mut b);
102 })
103 })
104 }
105
106 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
107 c.benchmark_group("a_ith_digit_unsigned_base_scalar_b_into_c");
108 for log_n in 11..12 {
109 let n: usize = 1 << log_n as usize;
110 let q_base: u64 = 0x1fffffffffe00001u64;
111 let q_power: usize = 1usize;
112 let ring: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
113 let base: usize = 7;
114 let logq: usize = ring.modulus.q.log2();
115 let d: usize = (logq + base - 1) / base;
116 let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), {
117 runner(ring, base, d)
118 })];
119 for (name, mut runner) in runners {
120 let id = BenchmarkId::new(name, n);
121 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
122 }
123 }
124}
125
126fn a_ith_digit_signed_base_scalar_b_into_c_balanced_false(c: &mut Criterion) {
127 fn runner(ring: Ring<u64>, base: usize, d: usize) -> Box<dyn FnMut()> {
128 let mut a: Poly<Montgomery<u64>> = ring.new_poly();
129 let mut carry: Poly<u64> = ring.new_poly();
130 let mut b: Poly<u64> = ring.new_poly();
131 for i in 0..ring.n() {
132 a.0[i] = i as u64;
133 }
134 Box::new(move || {
135 (0..d).for_each(|i| {
136 ring.a_ith_digit_signed_base_scalar_b_into_c::<false>(
137 i, &a, &base, &mut carry, &mut b,
138 );
139 })
140 })
141 }
142
143 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
144 c.benchmark_group("a_ith_digit_signed_base_scalar_b_into_c::<BALANCED=false>");
145 for log_n in 11..12 {
146 let n: usize = 1 << log_n as usize;
147 let q_base: u64 = 0x1fffffffffe00001u64;
148 let q_power: usize = 1usize;
149 let ring: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
150 let base: usize = 7;
151 let logq: usize = ring.modulus.q.log2();
152 let d: usize = (logq + base - 1) / base;
153 let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), {
154 runner(ring, base, d)
155 })];
156 for (name, mut runner) in runners {
157 let id = BenchmarkId::new(name, n);
158 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
159 }
160 }
161}
162
163fn a_ith_digit_signed_base_scalar_b_into_c_balanced_true(c: &mut Criterion) {
164 fn runner(ring: Ring<u64>, base: usize, d: usize) -> Box<dyn FnMut()> {
165 let mut a: Poly<Montgomery<u64>> = ring.new_poly();
166 let mut carry: Poly<u64> = ring.new_poly();
167 let mut b: Poly<u64> = ring.new_poly();
168 for i in 0..ring.n() {
169 a.0[i] = i as u64;
170 }
171 Box::new(move || {
172 (0..d).for_each(|i| {
173 ring.a_ith_digit_signed_base_scalar_b_into_c::<true>(
174 i, &a, &base, &mut carry, &mut b,
175 );
176 })
177 })
178 }
179
180 let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
181 c.benchmark_group("a_ith_digit_signed_base_scalar_b_into_c::<BALANCED=true>");
182 for log_n in 11..12 {
183 let n: usize = 1 << log_n as usize;
184 let q_base: u64 = 0x1fffffffffe00001u64;
185 let q_power: usize = 1usize;
186 let ring: Ring<u64> = Ring::<u64>::new(n, q_base, q_power);
187 let base: usize = 7;
188 let logq: usize = ring.modulus.q.log2();
189 let d: usize = (logq + base - 1) / base;
190 let runners = [(format!("prime/logq={}/w={}/d={}", logq, base, d), {
191 runner(ring, base, d)
192 })];
193 for (name, mut runner) in runners {
194 let id = BenchmarkId::new(name, n);
195 b.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
196 }
197 }
198}
199
200criterion_group!(
201 benches,
202 a_add_b_into_b,
203 a_mul_b_montgomery_into_a,
204 a_mul_b_montgomery_into_c,
205 a_ith_digit_unsigned_base_scalar_b_into_c,
206 a_ith_digit_signed_base_scalar_b_into_c_balanced_false,
207 a_ith_digit_signed_base_scalar_b_into_c_balanced_true,
208);
209criterion_main!(benches);