poulpy/poulpy-hal/src/bench_suite/svp.rs
poulpy-hal/src/bench_suite/svp.rsRaw
1use std::hint::black_box;
2
3use criterion::{BenchmarkId, Criterion};
4use rand::RngCore;
5
6use crate::{
7 api::{
8 ModuleNew, SvpApplyDft, SvpApplyDftToDft, SvpApplyDftToDftAdd, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPrepare,
9 VecZnxDftAlloc,
10 },
11 layouts::{Backend, DataViewMut, FillUniform, Module, ScalarZnx, SvpPPol, VecZnx, VecZnxDft},
12 source::Source,
13};
14
15pub fn bench_svp_prepare<B>(c: &mut Criterion, label: &str)
16where
17 Module<B>: SvpPrepare<B> + SvpPPolAlloc<B> + ModuleNew<B>,
18 B: Backend<ScalarPrep = f64>,
19{
20 let group_name: String = format!("svp_prepare::{}", label);
21
22 let mut group = c.benchmark_group(group_name);
23
24 fn runner<B>(log_n: usize) -> impl FnMut()
25 where
26 Module<B>: SvpPrepare<B> + SvpPPolAlloc<B> + ModuleNew<B>,
27 B: Backend<ScalarPrep = f64>,
28 {
29 let module: Module<B> = Module::<B>::new(1 << log_n);
30
31 let cols: usize = 2;
32
33 let mut svp: SvpPPol<Vec<u8>, B> = module.svp_ppol_alloc(cols);
34 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(module.n(), cols);
35 let mut source = Source::new([0u8; 32]);
36 a.fill_uniform(50, &mut source);
37
38 move || {
39 module.svp_prepare(&mut svp, 0, &a, 0);
40 black_box(());
41 }
42 }
43
44 for log_n in [10, 11, 12, 13, 14] {
45 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}", 1 << log_n));
46 let mut runner = runner::<B>(log_n);
47 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
48 }
49
50 group.finish();
51}
52
53pub fn bench_svp_apply_dft<B>(c: &mut Criterion, label: &str)
54where
55 Module<B>: SvpApplyDft<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
56 B: Backend<ScalarPrep = f64>,
57{
58 let group_name: String = format!("svp_apply_dft::{}", label);
59
60 let mut group = c.benchmark_group(group_name);
61
62 fn runner<B>(params: [usize; 3]) -> impl FnMut()
63 where
64 Module<B>: SvpApplyDft<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
65 B: Backend<ScalarPrep = f64>,
66 {
67 let n: usize = 1 << params[0];
68 let cols: usize = params[1];
69 let size: usize = params[2];
70
71 let module: Module<B> = Module::<B>::new(n as u64);
72
73 let mut svp: SvpPPol<Vec<u8>, B> = module.svp_ppol_alloc(cols);
74 let mut res: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
75 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
76
77 let mut source = Source::new([0u8; 32]);
78
79 source.fill_bytes(svp.data_mut());
80 source.fill_bytes(res.data_mut());
81 source.fill_bytes(a.data_mut());
82
83 move || {
84 for j in 0..cols {
85 module.svp_apply_dft(&mut res, j, &svp, j, &a, j);
86 }
87 black_box(());
88 }
89 }
90
91 for params in [[10, 2, 2], [11, 2, 4], [12, 2, 7], [13, 2, 15], [14, 2, 31]] {
92 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2]));
93 let mut runner = runner::<B>(params);
94 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
95 }
96
97 group.finish();
98}
99
100pub fn bench_svp_apply_dft_to_dft<B>(c: &mut Criterion, label: &str)
101where
102 Module<B>: SvpApplyDftToDft<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
103 B: Backend<ScalarPrep = f64>,
104{
105 let group_name: String = format!("svp_apply_dft_to_dft::{}", label);
106
107 let mut group = c.benchmark_group(group_name);
108
109 fn runner<B>(params: [usize; 3]) -> impl FnMut()
110 where
111 Module<B>: SvpApplyDftToDft<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
112 B: Backend<ScalarPrep = f64>,
113 {
114 let n: usize = 1 << params[0];
115 let cols: usize = params[1];
116 let size: usize = params[2];
117
118 let module: Module<B> = Module::<B>::new(n as u64);
119
120 let mut svp: SvpPPol<Vec<u8>, B> = module.svp_ppol_alloc(cols);
121 let mut res: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
122 let mut a: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
123
124 let mut source = Source::new([0u8; 32]);
125
126 source.fill_bytes(svp.data_mut());
127 source.fill_bytes(res.data_mut());
128 source.fill_bytes(a.data_mut());
129
130 move || {
131 for j in 0..cols {
132 module.svp_apply_dft_to_dft(&mut res, j, &svp, j, &a, j);
133 }
134 black_box(());
135 }
136 }
137
138 for params in [[10, 2, 2], [11, 2, 4], [12, 2, 7], [13, 2, 15], [14, 2, 31]] {
139 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2]));
140 let mut runner = runner::<B>(params);
141 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
142 }
143
144 group.finish();
145}
146
147pub fn bench_svp_apply_dft_to_dft_add<B>(c: &mut Criterion, label: &str)
148where
149 Module<B>: SvpApplyDftToDftAdd<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
150 B: Backend<ScalarPrep = f64>,
151{
152 let group_name: String = format!("svp_apply_dft_to_dft_add::{}", label);
153
154 let mut group = c.benchmark_group(group_name);
155
156 fn runner<B>(params: [usize; 3]) -> impl FnMut()
157 where
158 Module<B>: SvpApplyDftToDftAdd<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
159 B: Backend<ScalarPrep = f64>,
160 {
161 let n: usize = 1 << params[0];
162 let cols: usize = params[1];
163 let size: usize = params[2];
164
165 let module: Module<B> = Module::<B>::new(n as u64);
166
167 let mut svp: SvpPPol<Vec<u8>, B> = module.svp_ppol_alloc(cols);
168 let mut res: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
169 let mut a: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
170
171 let mut source = Source::new([0u8; 32]);
172
173 source.fill_bytes(svp.data_mut());
174 source.fill_bytes(res.data_mut());
175 source.fill_bytes(a.data_mut());
176
177 move || {
178 for j in 0..cols {
179 module.svp_apply_dft_to_dft_add(&mut res, j, &svp, j, &a, j);
180 }
181 black_box(());
182 }
183 }
184
185 for params in [[10, 2, 2], [11, 2, 4], [12, 2, 7], [13, 2, 15], [14, 2, 31]] {
186 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2]));
187 let mut runner = runner::<B>(params);
188 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
189 }
190
191 group.finish();
192}
193
194pub fn bench_svp_apply_dft_to_dft_inplace<B>(c: &mut Criterion, label: &str)
195where
196 Module<B>: SvpApplyDftToDftInplace<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
197 B: Backend<ScalarPrep = f64>,
198{
199 let group_name: String = format!("svp_apply_dft_to_dft_inplace::{}", label);
200
201 let mut group = c.benchmark_group(group_name);
202
203 fn runner<B>(params: [usize; 3]) -> impl FnMut()
204 where
205 Module<B>: SvpApplyDftToDftInplace<B> + SvpPPolAlloc<B> + ModuleNew<B> + VecZnxDftAlloc<B>,
206 B: Backend<ScalarPrep = f64>,
207 {
208 let n: usize = 1 << params[0];
209 let cols: usize = params[1];
210 let size: usize = params[2];
211
212 let module: Module<B> = Module::<B>::new(n as u64);
213
214 let mut svp: SvpPPol<Vec<u8>, B> = module.svp_ppol_alloc(cols);
215 let mut res: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(cols, size);
216
217 let mut source = Source::new([0u8; 32]);
218
219 source.fill_bytes(svp.data_mut());
220 source.fill_bytes(res.data_mut());
221
222 move || {
223 for j in 0..cols {
224 module.svp_apply_dft_to_dft_inplace(&mut res, j, &svp, j);
225 }
226 black_box(());
227 }
228 }
229
230 for params in [[10, 2, 2], [11, 2, 4], [12, 2, 7], [13, 2, 15], [14, 2, 31]] {
231 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2]));
232 let mut runner = runner::<B>(params);
233 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
234 }
235
236 group.finish();
237}