poulpy/poulpy-backend/benches/fft.rs
poulpy-backend/benches/fft.rsRaw
1use std::{ffi::c_void, hint::black_box};
2
3use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
4use poulpy_backend::cpu_spqlios::reim;
5use poulpy_hal::reference::fft64::reim::{ReimDFTExecute, ReimFFTRef, ReimFFTTable, ReimIFFTRef, ReimIFFTTable};
6
7pub fn bench_fft_ref(c: &mut Criterion) {
8 let group_name: String = "fft_ref".to_string();
9
10 let mut group = c.benchmark_group(group_name);
11
12 fn runner(m: usize) -> impl FnMut() {
13 let mut values: Vec<f64> = vec![0f64; m << 1];
14 let scale: f64 = 1.0f64 / (2 * m) as f64;
15 values
16 .iter_mut()
17 .enumerate()
18 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
19 let table: ReimFFTTable<f64> = ReimFFTTable::<f64>::new(m);
20 move || {
21 ReimFFTRef::reim_dft_execute(&table, &mut values);
22 black_box(());
23 }
24 }
25
26 for log_m in [9, 10, 11, 12, 13, 14, 15] {
27 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
28 let mut runner = runner(1 << log_m);
29 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
30 }
31
32 group.finish();
33}
34
35pub fn bench_fft_avx2_fma(c: &mut Criterion) {
36 let group_name: String = "fft_avx2_fma".to_string();
37
38 let mut group = c.benchmark_group(group_name);
39
40 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
41 #[target_feature(enable = "avx2,fma")]
42 fn runner(m: usize) -> impl FnMut() {
43 let mut values: Vec<f64> = vec![0f64; m << 1];
44
45 let scale = 1.0f64 / (2 * m) as f64;
46 values
47 .iter_mut()
48 .enumerate()
49 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
50
51 let table: ReimFFTTable<f64> = ReimFFTTable::<f64>::new(m);
52 move || {
53 use poulpy_backend::cpu_fft64_avx::ReimFFTAvx;
54
55 ReimFFTAvx::reim_dft_execute(&table, &mut values);
56 black_box(());
57 }
58 }
59
60 if std::is_x86_feature_detected!("avx2") {
61 for log_m in [9, 10, 11, 12, 13, 14, 15] {
62 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
63 unsafe {
64 let mut runner = runner(1 << log_m);
65 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
66 }
67 }
68 } else {
69 eprintln!("skipping: CPU lacks avx2");
70 return;
71 }
72
73 group.finish();
74}
75
76pub fn bench_fft_spqlios(c: &mut Criterion) {
77 let group_name: String = "fft_spqlios".to_string();
78
79 let mut group = c.benchmark_group(group_name);
80
81 fn runner(m: usize) -> impl FnMut() {
82 let mut values: Vec<f64> = vec![0f64; m << 1];
83
84 let scale = 1.0f64 / (2 * m) as f64;
85 values
86 .iter_mut()
87 .enumerate()
88 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
89
90 unsafe {
91 reim::reim_fft_simple(m as u32, values.as_mut_ptr() as *mut c_void);
92 }
93
94 move || {
95 unsafe {
96 reim::reim_fft_simple(m as u32, values.as_mut_ptr() as *mut c_void);
97 }
98 black_box(());
99 }
100 }
101
102 for log_m in [9, 10, 11, 12, 13, 14, 15] {
103 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
104 let mut runner = runner(1 << log_m);
105 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
106 }
107
108 group.finish();
109}
110
111pub fn bench_ifft_ref(c: &mut Criterion) {
112 let group_name: String = "ifft_ref".to_string();
113
114 let mut group = c.benchmark_group(group_name);
115
116 fn runner(m: usize) -> impl FnMut() {
117 let mut values: Vec<f64> = vec![0f64; m << 1];
118 let scale: f64 = 1.0f64 / (2 * m) as f64;
119 values
120 .iter_mut()
121 .enumerate()
122 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
123 let table: ReimIFFTTable<f64> = ReimIFFTTable::<f64>::new(m);
124 move || {
125 ReimIFFTRef::reim_dft_execute(&table, &mut values);
126 black_box(());
127 }
128 }
129
130 for log_m in [9, 10, 11, 12, 13, 14, 15] {
131 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
132 let mut runner = runner(1 << log_m);
133 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
134 }
135
136 group.finish();
137}
138
139pub fn bench_ifft_avx2_fma(c: &mut Criterion) {
140 let group_name: String = "ifft_avx2_fma".to_string();
141
142 let mut group = c.benchmark_group(group_name);
143
144 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
145 #[target_feature(enable = "avx2,fma")]
146 fn runner(m: usize) -> impl FnMut() {
147 let mut values: Vec<f64> = vec![0f64; m << 1];
148
149 let scale = 1.0f64 / (2 * m) as f64;
150 values
151 .iter_mut()
152 .enumerate()
153 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
154
155 let table: ReimIFFTTable<f64> = ReimIFFTTable::<f64>::new(m);
156 move || {
157 use poulpy_backend::cpu_fft64_avx::ReimIFFTAvx;
158
159 ReimIFFTAvx::reim_dft_execute(&table, &mut values);
160 black_box(());
161 }
162 }
163
164 if std::is_x86_feature_detected!("avx2") {
165 for log_m in [9, 10, 11, 12, 13, 14, 15] {
166 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
167 unsafe {
168 let mut runner = runner(1 << log_m);
169 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
170 }
171 }
172 } else {
173 eprintln!("skipping: CPU lacks avx2");
174 return;
175 }
176
177 group.finish();
178}
179
180pub fn bench_ifft_spqlios(c: &mut Criterion) {
181 let group_name: String = "ifft_spqlios".to_string();
182
183 let mut group = c.benchmark_group(group_name);
184
185 fn runner(m: usize) -> impl FnMut() {
186 let mut values: Vec<f64> = vec![0f64; m << 1];
187
188 let scale = 1.0f64 / (2 * m) as f64;
189 values
190 .iter_mut()
191 .enumerate()
192 .for_each(|(i, x)| *x = (i + 1) as f64 * scale);
193
194 unsafe {
195 reim::reim_ifft_simple(m as u32, values.as_mut_ptr() as *mut c_void);
196 }
197
198 move || {
199 unsafe {
200 reim::reim_ifft_simple(m as u32, values.as_mut_ptr() as *mut c_void);
201 }
202 black_box(());
203 }
204 }
205
206 for log_m in [9, 10, 11, 12, 13, 14, 15] {
207 let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
208 let mut runner = runner(1 << log_m);
209 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
210 }
211
212 group.finish();
213}
214
215criterion_group!(
216 benches,
217 bench_fft_ref,
218 bench_fft_avx2_fma,
219 bench_fft_spqlios,
220 bench_ifft_ref,
221 bench_ifft_avx2_fma,
222 bench_ifft_spqlios
223);
224criterion_main!(benches);