-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathbasic_interface.cpp
More file actions
202 lines (170 loc) · 5.75 KB
/
basic_interface.cpp
File metadata and controls
202 lines (170 loc) · 5.75 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
* 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_option.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;
};
auto TransformAndInvert = [](auto& a, ::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
////
auto TransformAndInvert_nD = [](auto& a, ::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);
}
};
#ifdef XTENSOR_FFTW_USE_FLOAT
using rfft1Dxarray_float = rfft1Dxarray<float>;
BENCHMARK_F(rfft1Dxarray_float, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert(a, st);
}
BENCHMARK_F(rfft1Dxarray_float, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD(a, st);
}
#endif
#ifdef XTENSOR_FFTW_USE_DOUBLE
using rfft1Dxarray_double = rfft1Dxarray<double>;
BENCHMARK_F(rfft1Dxarray_double, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert(a, st);
}
BENCHMARK_F(rfft1Dxarray_double, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD(a, st);
}
#endif
#ifdef XTENSOR_FFTW_USE_LONG_DOUBLE
using rfft1Dxarray_longdouble = rfft1Dxarray<long double>;
BENCHMARK_F(rfft1Dxarray_longdouble, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert(a, st);
}
BENCHMARK_F(rfft1Dxarray_longdouble, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD(a, st);
}
#endif
////
// 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;
};
auto TransformAndInvert2 = [](auto& a, ::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
////
auto TransformAndInvert_nD2 = [](auto& a, ::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);
}
};
#ifdef XTENSOR_FFTW_USE_FLOAT
using rfft2Dxarray_float = rfft2Dxarray<float>;
BENCHMARK_F(rfft2Dxarray_float, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert2(a, st);
}
BENCHMARK_F(rfft2Dxarray_float, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD2(a, st);
}
#endif
#ifdef XTENSOR_FFTW_USE_DOUBLE
using rfft2Dxarray_double = rfft2Dxarray<double>;
BENCHMARK_F(rfft2Dxarray_double, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert2(a, st);
}
BENCHMARK_F(rfft2Dxarray_double, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD2(a, st);
}
#endif
#ifdef XTENSOR_FFTW_USE_LONG_DOUBLE
using rfft2Dxarray_longdouble = rfft2Dxarray<long double>;
BENCHMARK_F(rfft2Dxarray_longdouble, TransformAndInvert)(::benchmark::State& st) {
TransformAndInvert2(a, st);
}
BENCHMARK_F(rfft2Dxarray_longdouble, TransformAndInvert_nD)(::benchmark::State& st) {
TransformAndInvert_nD2(a, st);
}
#endif
//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()