poulpy/poulpy-hal/src/bench_suite/convolution.rs
poulpy-hal/src/bench_suite/convolution.rsRaw
1use std::hint::black_box;
2
3use criterion::{BenchmarkId, Criterion};
4
5use crate::{
6 api::{CnvPVecAlloc, Convolution, ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxBigAlloc, VecZnxDftAlloc},
7 layouts::{Backend, CnvPVecL, CnvPVecR, FillUniform, Module, ScratchOwned, VecZnx, VecZnxBig},
8 source::Source,
9};
10
11pub fn bench_cnv_prepare_left<BE: Backend>(c: &mut Criterion, label: &str)
12where
13 Module<BE>: ModuleNew<BE> + Convolution<BE> + CnvPVecAlloc<BE>,
14 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
15{
16 let group_name: String = format!("cnv_prepare_left::{label}");
17
18 let mut group = c.benchmark_group(group_name);
19
20 fn runner<BE: Backend>(n: usize, size: usize) -> impl FnMut()
21 where
22 Module<BE>: ModuleNew<BE> + Convolution<BE> + CnvPVecAlloc<BE>,
23 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
24 {
25 let mut source: Source = Source::new([0u8; 32]);
26
27 let base2k: usize = 12;
28
29 let c_size: usize = size + size - 1;
30
31 let module: Module<BE> = Module::<BE>::new(n as u64);
32
33 let mut a_prep: CnvPVecL<Vec<u8>, BE> = module.cnv_pvec_left_alloc(1, size);
34
35 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), 1, size);
36
37 a.fill_uniform(base2k, &mut source);
38
39 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(module.cnv_prepare_left_tmp_bytes(c_size, size));
40
41 move || {
42 module.cnv_prepare_left(&mut a_prep, &a, scratch.borrow());
43 black_box(());
44 }
45 }
46
47 for params in [[10, 1], [11, 2], [12, 4], [13, 8], [14, 16], [15, 32], [16, 64]] {
48 let log_n: usize = params[0];
49 let size: usize = params[1];
50 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x{}", 1 << log_n, size));
51 let mut runner = runner(1 << log_n, size);
52 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
53 }
54
55 group.finish();
56}
57
58pub fn bench_cnv_prepare_right<BE: Backend>(c: &mut Criterion, label: &str)
59where
60 Module<BE>: ModuleNew<BE> + Convolution<BE> + CnvPVecAlloc<BE>,
61 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
62{
63 let group_name: String = format!("cnv_prepare_right::{label}");
64
65 let mut group = c.benchmark_group(group_name);
66
67 fn runner<BE: Backend>(n: usize, size: usize) -> impl FnMut()
68 where
69 Module<BE>: ModuleNew<BE> + Convolution<BE> + CnvPVecAlloc<BE>,
70 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
71 {
72 let mut source: Source = Source::new([0u8; 32]);
73
74 let base2k: usize = 12;
75
76 let c_size: usize = size + size - 1;
77
78 let module: Module<BE> = Module::<BE>::new(n as u64);
79
80 let mut a_prep: CnvPVecR<Vec<u8>, BE> = module.cnv_pvec_right_alloc(1, size);
81
82 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), 1, size);
83
84 a.fill_uniform(base2k, &mut source);
85
86 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(module.cnv_prepare_right_tmp_bytes(c_size, size));
87
88 move || {
89 module.cnv_prepare_right(&mut a_prep, &a, scratch.borrow());
90 black_box(());
91 }
92 }
93
94 for params in [[10, 1], [11, 2], [12, 4], [13, 8], [14, 16], [15, 32], [16, 64]] {
95 let log_n: usize = params[0];
96 let size: usize = params[1];
97 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x{}", 1 << log_n, size));
98 let mut runner = runner(1 << log_n, size);
99 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
100 }
101
102 group.finish();
103}
104
105pub fn bench_cnv_apply_dft<BE: Backend>(c: &mut Criterion, label: &str)
106where
107 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxDftAlloc<BE> + CnvPVecAlloc<BE>,
108 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
109{
110 let group_name: String = format!("cnv_apply_dft::{label}");
111
112 let mut group = c.benchmark_group(group_name);
113
114 fn runner<BE: Backend>(n: usize, size: usize) -> impl FnMut()
115 where
116 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxDftAlloc<BE> + CnvPVecAlloc<BE>,
117 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
118 {
119 let mut source: Source = Source::new([0u8; 32]);
120
121 let base2k: usize = 12;
122
123 let c_size: usize = size + size - 1;
124
125 let module: Module<BE> = Module::<BE>::new(n as u64);
126
127 let mut a_prep: CnvPVecL<Vec<u8>, BE> = module.cnv_pvec_left_alloc(1, size);
128 let mut b_prep: CnvPVecR<Vec<u8>, BE> = module.cnv_pvec_right_alloc(1, size);
129
130 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), 1, size);
131 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), 1, size);
132 let mut c_dft = module.vec_znx_dft_alloc(1, c_size);
133
134 a.fill_uniform(base2k, &mut source);
135 b.fill_uniform(base2k, &mut source);
136
137 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
138 module
139 .cnv_apply_dft_tmp_bytes(c_size, 0, size, size)
140 .max(module.cnv_prepare_left_tmp_bytes(c_size, size))
141 .max(module.cnv_prepare_right_tmp_bytes(c_size, size)),
142 );
143 module.cnv_prepare_left(&mut a_prep, &a, scratch.borrow());
144 module.cnv_prepare_right(&mut b_prep, &b, scratch.borrow());
145 move || {
146 module.cnv_apply_dft(&mut c_dft, 0, 0, &a_prep, 0, &b_prep, 0, scratch.borrow());
147 black_box(());
148 }
149 }
150
151 for params in [[10, 1], [11, 2], [12, 4], [13, 8], [14, 16], [15, 32], [16, 64]] {
152 let log_n: usize = params[0];
153 let size: usize = params[1];
154 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x{}", 1 << log_n, size));
155 let mut runner = runner(1 << log_n, size);
156 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
157 }
158
159 group.finish();
160}
161
162pub fn bench_cnv_pairwise_apply_dft<BE: Backend>(c: &mut Criterion, label: &str)
163where
164 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxDftAlloc<BE> + CnvPVecAlloc<BE>,
165 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
166{
167 let group_name: String = format!("cnv_pairwise_apply_dft::{label}");
168
169 let mut group = c.benchmark_group(group_name);
170
171 fn runner<BE: Backend>(n: usize, size: usize) -> impl FnMut()
172 where
173 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxDftAlloc<BE> + CnvPVecAlloc<BE>,
174 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
175 {
176 let mut source: Source = Source::new([0u8; 32]);
177
178 let base2k: usize = 12;
179
180 let module: Module<BE> = Module::<BE>::new(n as u64);
181
182 let cols = 2;
183 let c_size: usize = size + size - 1;
184
185 let mut a_prep: CnvPVecL<Vec<u8>, BE> = module.cnv_pvec_left_alloc(cols, size);
186 let mut b_prep: CnvPVecR<Vec<u8>, BE> = module.cnv_pvec_right_alloc(cols, size);
187
188 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), cols, size);
189 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), cols, size);
190 let mut c_dft = module.vec_znx_dft_alloc(1, c_size);
191
192 a.fill_uniform(base2k, &mut source);
193 b.fill_uniform(base2k, &mut source);
194
195 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
196 module
197 .cnv_pairwise_apply_dft_tmp_bytes(c_size, 0, size, size)
198 .max(module.cnv_prepare_left_tmp_bytes(c_size, size))
199 .max(module.cnv_prepare_right_tmp_bytes(c_size, size)),
200 );
201 module.cnv_prepare_left(&mut a_prep, &a, scratch.borrow());
202 module.cnv_prepare_right(&mut b_prep, &b, scratch.borrow());
203 move || {
204 module.cnv_pairwise_apply_dft(&mut c_dft, 0, 0, &a_prep, &b_prep, 0, 1, scratch.borrow());
205 black_box(());
206 }
207 }
208
209 for params in [[10, 1], [11, 2], [12, 4], [13, 8], [14, 16], [15, 32], [16, 64]] {
210 let log_n: usize = params[0];
211 let size: usize = params[1];
212 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x{}", 1 << log_n, size));
213 let mut runner = runner(1 << log_n, size);
214 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
215 }
216
217 group.finish();
218}
219
220pub fn bench_cnv_by_const_apply<BE: Backend>(c: &mut Criterion, label: &str)
221where
222 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxBigAlloc<BE> + CnvPVecAlloc<BE>,
223 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
224{
225 let group_name: String = format!("cnv_by_const::{label}");
226
227 let mut group = c.benchmark_group(group_name);
228
229 fn runner<BE: Backend>(n: usize, size: usize) -> impl FnMut()
230 where
231 Module<BE>: ModuleNew<BE> + Convolution<BE> + VecZnxBigAlloc<BE> + CnvPVecAlloc<BE>,
232 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
233 {
234 let mut source: Source = Source::new([0u8; 32]);
235
236 let base2k: usize = 12;
237
238 let module: Module<BE> = Module::<BE>::new(n as u64);
239
240 let cols = 2;
241 let c_size: usize = size + size - 1;
242
243 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(module.n(), cols, size);
244 let mut c_big: VecZnxBig<Vec<u8>, BE> = module.vec_znx_big_alloc(1, c_size);
245
246 a.fill_uniform(base2k, &mut source);
247 let mut b = vec![0i64; size];
248 for x in &mut b {
249 *x = source.next_i64();
250 }
251
252 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(module.cnv_by_const_apply_tmp_bytes(c_size, 0, size, size));
253 move || {
254 module.cnv_by_const_apply(&mut c_big, 0, 0, &a, 0, &b, scratch.borrow());
255 black_box(());
256 }
257 }
258
259 for params in [[10, 1], [11, 2], [12, 4], [13, 8], [14, 16], [15, 32], [16, 64]] {
260 let log_n: usize = params[0];
261 let size: usize = params[1];
262 let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x{}", 1 << log_n, size));
263 let mut runner = runner(1 << log_n, size);
264 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
265 }
266
267 group.finish();
268}