yum/vfft

git clone https://git.yummers.dev/yum/vfft

yumRewrite benchmarkdc1eb1b

master
3.0 KiB101 linesraw
1use criterion::{BatchSize, Criterion, black_box, criterion_group, criterion_main};
2use num::complex::Complex;
3use num::traits::Float;
4use vfft::cpu::{ExecutionPlan, fft};
5
6// Cast one float type to another, truncating if needed.
7fn t0_to_t1<T0: Float, T1: Float>(val: T0) -> T1 {
8    return num::cast(val).unwrap();
9}
10
11// Casts one Complex<T> to another.
12fn complex_to_t<T0: Float, T1: Float>(data: &[Complex<T0>]) -> Vec<Complex<T1>> {
13    data.iter()
14        .map(|c| Complex::new(t0_to_t1(c.re), t0_to_t1(c.im)))
15        .collect()
16}
17
18fn get_data(n: usize) -> Vec<Complex<f32>> {
19    let mut data: Vec<Complex<f32>> = Vec::new();
20    data.resize(n, Complex::ZERO);
21    // Randomize data.
22    for i in 0..data.len() {
23        data[i] = Complex::new(rand::random(), rand::random());
24    }
25    data
26}
27
28fn do_fft_v8_benchmark_for_n(c: &mut Criterion, n: usize) {
29    let data = get_data(n);
30    let mut plan = ExecutionPlan::new(&data).unwrap();
31    let result_ref: Vec<rustfft::num_complex::Complex<f32>> = complex_to_t(&data);
32
33    c.bench_function(format!("size {}, fft v8", n).as_str(), |b| {
34        b.iter_batched_ref(
35            || result_ref.clone(),
36            |result_ref| {
37                fft::<f32>(result_ref, &mut plan);
38                black_box(result_ref);
39            },
40            BatchSize::PerIteration,
41        );
42    });
43}
44
45fn do_ref_benchmark_for_n(c: &mut Criterion, n: usize) {
46    let data = get_data(n);
47
48    let result_ref: Vec<rustfft::num_complex::Complex<f32>> = complex_to_t(&data);
49    let mut ref_planner = rustfft::FftPlanner::<f32>::new();
50    let mut scratch: Vec<rustfft::num_complex::Complex<f32>> =
51        vec![Complex::<f32>::new(0.0, 0.0); n];
52    let ref_fft = ref_planner.plan_fft_forward(result_ref.len());
53
54    c.bench_function(format!("size {}, reference", n).as_str(), |b| {
55        b.iter_batched_ref(
56            || result_ref.clone(),
57            |result_ref| {
58                ref_fft.process_with_scratch(result_ref, &mut scratch);
59                black_box(result_ref);
60            },
61            BatchSize::PerIteration,
62        );
63    });
64}
65
66fn do_bench(c: &mut Criterion, n: usize) {
67    do_ref_benchmark_for_n(c, n);
68    do_fft_v8_benchmark_for_n(c, n);
69}
70
71fn get_composites(primes: &[usize], max_number: usize) -> Vec<usize> {
72    let mut composites = Vec::new();
73    composites.push(1);
74
75    for prime in primes {
76        let num_before = composites.len();
77        for i in 0..num_before {
78            let mut composite = composites[i] * prime;
79            while composite <= max_number {
80                composites.push(composite);
81                composite *= prime;
82            }
83        }
84    }
85
86    composites.retain(|&x| x >= 11);
87    composites.sort();
88    composites
89}
90
91pub fn criterion_benchmark(c: &mut Criterion) {
92    let radices = [2, 3, 5, 7];
93    const MAX_SIZE: usize = 8192;
94    let composites = get_composites(&radices, MAX_SIZE);
95    for composite in &composites {
96        do_bench(c, *composite);
97    }
98}
99
100criterion_group!(benches, criterion_benchmark);
101criterion_main!(benches);