poulpy/spqlios/lib/test/spqlios_cplx_fft_bench.cpp
spqlios/lib/test/spqlios_cplx_fft_bench.cppRaw
1#include <benchmark/benchmark.h>
2#include <stdint.h>
3
4#include <cassert>
5#include <cmath>
6#include <complex>
7#include <cstdlib>
8#include <cstring>
9#include <iostream>
10#include <string>
11#include <vector>
12
13#include "../spqlios/cplx/cplx_fft_internal.h"
14#include "spqlios/reim/reim_fft.h"
15
16using namespace std;
17
18void init_random_values(uint64_t n, double* v) {
19 for (uint64_t i = 0; i < n; ++i) v[i] = rand() - (RAND_MAX >> 1);
20}
21
22void benchmark_cplx_fft(benchmark::State& state) {
23 const int32_t nn = state.range(0);
24 CPLX_FFT_PRECOMP* a = new_cplx_fft_precomp(nn / 2, 1);
25 double* c = (double*)cplx_fft_precomp_get_buffer(a, 0);
26 init_random_values(nn, c);
27 for (auto _ : state) {
28 // cplx_fft_simple(nn/2, c);
29 cplx_fft(a, c);
30 }
31 delete_cplx_fft_precomp(a);
32}
33
34void benchmark_cplx_ifft(benchmark::State& state) {
35 const int32_t nn = state.range(0);
36 CPLX_IFFT_PRECOMP* a = new_cplx_ifft_precomp(nn / 2, 1);
37 double* c = (double*)cplx_ifft_precomp_get_buffer(a, 0);
38 init_random_values(nn, c);
39 for (auto _ : state) {
40 // cplx_ifft_simple(nn/2, c);
41 cplx_ifft(a, c);
42 }
43 delete_cplx_ifft_precomp(a);
44}
45
46void benchmark_reim_fft(benchmark::State& state) {
47 const int32_t nn = state.range(0);
48 const uint32_t m = nn / 2;
49 REIM_FFT_PRECOMP* a = new_reim_fft_precomp(m, 1);
50 double* c = reim_fft_precomp_get_buffer(a, 0);
51 init_random_values(nn, c);
52 for (auto _ : state) {
53 // cplx_fft_simple(nn/2, c);
54 reim_fft(a, c);
55 }
56 delete_reim_fft_precomp(a);
57}
58
59#ifdef __aarch64__
60EXPORT REIM_FFT_PRECOMP* new_reim_fft_precomp_neon(uint32_t m, uint32_t num_buffers);
61EXPORT void reim_fft_neon(const REIM_FFT_PRECOMP* precomp, double* d);
62
63void benchmark_reim_fft_neon(benchmark::State& state) {
64 const int32_t nn = state.range(0);
65 const uint32_t m = nn / 2;
66 REIM_FFT_PRECOMP* a = new_reim_fft_precomp_neon(m, 1);
67 double* c = reim_fft_precomp_get_buffer(a, 0);
68 init_random_values(nn, c);
69 for (auto _ : state) {
70 // cplx_fft_simple(nn/2, c);
71 reim_fft_neon(a, c);
72 }
73 delete_reim_fft_precomp(a);
74}
75#endif
76
77void benchmark_reim_ifft(benchmark::State& state) {
78 const int32_t nn = state.range(0);
79 const uint32_t m = nn / 2;
80 REIM_IFFT_PRECOMP* a = new_reim_ifft_precomp(m, 1);
81 double* c = reim_ifft_precomp_get_buffer(a, 0);
82 init_random_values(nn, c);
83 for (auto _ : state) {
84 // cplx_ifft_simple(nn/2, c);
85 reim_ifft(a, c);
86 }
87 delete_reim_ifft_precomp(a);
88}
89
90// #define ARGS Arg(1024)->Arg(8192)->Arg(32768)->Arg(65536)
91#define ARGS Arg(64)->Arg(256)->Arg(1024)->Arg(2048)->Arg(4096)->Arg(8192)->Arg(16384)->Arg(32768)->Arg(65536)
92
93int main(int argc, char** argv) {
94 ::benchmark::Initialize(&argc, argv);
95 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
96 std::cout << "Dimensions n in the benchmark below are in \"real FFT\" modulo X^n+1" << std::endl;
97 std::cout << "The complex dimension m (modulo X^m-i) is half of it" << std::endl;
98 BENCHMARK(benchmark_cplx_fft)->ARGS;
99 BENCHMARK(benchmark_cplx_ifft)->ARGS;
100 BENCHMARK(benchmark_reim_fft)->ARGS;
101#ifdef __aarch64__
102 BENCHMARK(benchmark_reim_fft_neon)->ARGS;
103#endif
104 BENCHMARK(benchmark_reim_ifft)->ARGS;
105 // if (CPU_SUPPORTS("avx512f")) {
106 // BENCHMARK(bench_cplx_fftvec_twiddle_avx512)->ARGS;
107 // BENCHMARK(bench_cplx_fftvec_bitwiddle_avx512)->ARGS;
108 //}
109 ::benchmark::RunSpecifiedBenchmarks();
110 ::benchmark::Shutdown();
111 return 0;
112}