// Benchmarks for Eigen Tensor FFT. #include #include using namespace Eigen; #ifndef SCALAR #define SCALAR float #endif typedef SCALAR Scalar; // --- 1D FFT --- static void BM_TensorFFT_1D(benchmark::State& state) { const int N = state.range(0); Tensor input(N); input.setRandom(); Eigen::array fft_dims = {0}; for (auto _ : state) { Tensor, 1> result = input.template fft(fft_dims); benchmark::DoNotOptimize(result.data()); benchmark::ClobberMemory(); } double mflops = 5.0 * N * std::log2(static_cast(N)) / 2.0; // real->complex state.counters["MFLOPS"] = benchmark::Counter(mflops, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::kIs1000); } // --- 2D FFT --- static void BM_TensorFFT_2D(benchmark::State& state) { const int N = state.range(0); Tensor input(N, N); input.setRandom(); Eigen::array fft_dims = {0, 1}; for (auto _ : state) { Tensor, 2> result = input.template fft(fft_dims); benchmark::DoNotOptimize(result.data()); benchmark::ClobberMemory(); } double total = N * N; double mflops = 5.0 * total * std::log2(static_cast(N)); state.counters["MFLOPS"] = benchmark::Counter(mflops, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::kIs1000); } // --- 1D inverse FFT --- static void BM_TensorIFFT_1D(benchmark::State& state) { const int N = state.range(0); Tensor, 1> input(N); input.setRandom(); Eigen::array fft_dims = {0}; for (auto _ : state) { Tensor, 1> result = input.template fft(fft_dims); benchmark::DoNotOptimize(result.data()); benchmark::ClobberMemory(); } double mflops = 5.0 * N * std::log2(static_cast(N)); state.counters["MFLOPS"] = benchmark::Counter(mflops, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::kIs1000); } static void FFTSizes(::benchmark::Benchmark* b) { for (int n : {64, 256, 1024, 4096}) { b->Arg(n); } } BENCHMARK(BM_TensorFFT_1D)->Apply(FFTSizes); BENCHMARK(BM_TensorFFT_2D)->Apply(FFTSizes); BENCHMARK(BM_TensorIFFT_1D)->Apply(FFTSizes);