arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/spqlios_cplx_fft_bench.cpp
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/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}