-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathbasic_interface.cpp
More file actions
144 lines (118 loc) · 4 KB
/
Copy pathbasic_interface.cpp
File metadata and controls
144 lines (118 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* xtensor-fftw
* Copyright (c) 2017, Patrick Bos
* Distributed under the terms of the BSD 3-Clause License.
*
* The full license is in the file LICENSE, distributed with this software.
*/
#include <stdexcept> // workaround for xt bug, where only including xarray does not include stdexcept; TODO: remove this include when bug is fixed!
#include <xtensor/xarray.hpp>
#include <iostream>
#include <xtensor/xio.hpp>
#include <xtensor/xrandom.hpp>
#include <cmath> // pow
#include <array>
#include "xtensor-fftw/basic.hpp"
#include "benchmark/benchmark.h"
// Generates a dim-dimensional array of size n in each dimension, filled with random numbers between 0 and the numeric
// limit of type T divided by pow(n, dim) (the latter to keep the FFTs from generating infs and nans).
template <typename T, std::size_t dim>
auto generate_data(std::size_t n) {
std::array<std::size_t, dim> shape;
shape.fill(n);
return xt::random::rand<T>(shape, 0, std::numeric_limits<T>::max() / std::pow(n, dim));
}
////
// Real FFT: 1D
////
template<typename precision_t>
class rfft1Dxarray : public ::benchmark::Fixture {
public:
void SetUp(const ::benchmark::State& state) {
data_size = 1024;
a = generate_data<precision_t, 1>(data_size);
// let fftw accumulate wisdom
// auto b = xt::fftw::rfft(a); // DOES NOT HAVE ANY NOTICEABLE EFFECT...
// auto c = xt::fftw::irfft(b);
}
void TearDown(const ::benchmark::State& /*state*/) {}
std::size_t data_size;
xt::xarray<precision_t> a;
};
using rfft1Dxarray_float = rfft1Dxarray<float>;
BENCHMARK_F(rfft1Dxarray_float, TransformAndInvert)(::benchmark::State& st) {
while (st.KeepRunning()) {
auto a_fourier = xt::fftw::rfft(a);
::benchmark::DoNotOptimize(a_fourier);
auto should_be_a = xt::fftw::irfft(a_fourier);
::benchmark::DoNotOptimize(should_be_a);
}
}
////
// Real FFT: nD with n = 1
////
BENCHMARK_F(rfft1Dxarray_float, TransformAndInvert_nD)(::benchmark::State& st) {
while (st.KeepRunning()) {
auto a_fourier = xt::fftw::rfftn<1>(a);
::benchmark::DoNotOptimize(a_fourier);
auto should_be_a = xt::fftw::irfftn<1>(a_fourier);
::benchmark::DoNotOptimize(should_be_a);
}
}
////
// Real FFT: 2D
////
template<typename precision_t>
class rfft2Dxarray : public ::benchmark::Fixture {
public:
void SetUp(const ::benchmark::State& state) {
data_size = 64;
a = generate_data<precision_t, 2>(data_size);
// let fftw accumulate wisdom
// auto b = xt::fftw::rfft(a); // DOES NOT HAVE ANY NOTICEABLE EFFECT...
// auto c = xt::fftw::irfft(b);
}
void TearDown(const ::benchmark::State& /*state*/) {}
std::size_t data_size;
xt::xarray<precision_t> a;
};
using rfft2Dxarray_float = rfft2Dxarray<float>;
BENCHMARK_F(rfft2Dxarray_float, TransformAndInvert)(::benchmark::State& st) {
while (st.KeepRunning()) {
auto a_fourier = xt::fftw::rfft2(a);
::benchmark::DoNotOptimize(a_fourier);
auto should_be_a = xt::fftw::irfft2(a_fourier);
::benchmark::DoNotOptimize(should_be_a);
}
}
////
// Real FFT: nD with n = 2
////
BENCHMARK_F(rfft2Dxarray_float, TransformAndInvert_nD)(::benchmark::State& st) {
while (st.KeepRunning()) {
auto a_fourier = xt::fftw::rfftn<2>(a);
::benchmark::DoNotOptimize(a_fourier);
auto should_be_a = xt::fftw::irfftn<2>(a_fourier);
::benchmark::DoNotOptimize(should_be_a);
}
}
//BENCHMARK_TEMPLATE_F(rfft1Dxarray, TransformAndInvert, double)(::benchmark::State& st) {
// for (auto _ : st) {
// auto a_fourier = xt::fftw::rfft(a);
// ::benchmark::DoNotOptimize(a_fourier);
// auto should_be_a = xt::fftw::irfft(a_fourier);
// ::benchmark::DoNotOptimize(should_be_a);
// }
//}
//
//#ifndef FFTW_NO_LONGDOUBLE
//BENCHMARK_TEMPLATE_F(rfft1Dxarray, TransformAndInvert, long double)(::benchmark::State& st) {
// for (auto _ : st) {
// auto a_fourier = xt::fftw::rfft(a);
// ::benchmark::DoNotOptimize(a_fourier);
// auto should_be_a = xt::fftw::irfft(a_fourier);
// ::benchmark::DoNotOptimize(should_be_a);
// }
//}
//#endif // FFTW_NO_LONGDOUBLE
BENCHMARK_MAIN()