1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2009 Mark Borgerding mark a borgerding net
5*bf2c3715SXin Li //
6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9*bf2c3715SXin Li
10*bf2c3715SXin Li #include <iostream>
11*bf2c3715SXin Li
12*bf2c3715SXin Li #include <bench/BenchUtil.h>
13*bf2c3715SXin Li #include <complex>
14*bf2c3715SXin Li #include <vector>
15*bf2c3715SXin Li #include <Eigen/Core>
16*bf2c3715SXin Li
17*bf2c3715SXin Li #include <unsupported/Eigen/FFT>
18*bf2c3715SXin Li
19*bf2c3715SXin Li using namespace Eigen;
20*bf2c3715SXin Li using namespace std;
21*bf2c3715SXin Li
22*bf2c3715SXin Li
23*bf2c3715SXin Li template <typename T>
24*bf2c3715SXin Li string nameof();
25*bf2c3715SXin Li
nameof()26*bf2c3715SXin Li template <> string nameof<float>() {return "float";}
nameof()27*bf2c3715SXin Li template <> string nameof<double>() {return "double";}
nameof()28*bf2c3715SXin Li template <> string nameof<long double>() {return "long double";}
29*bf2c3715SXin Li
30*bf2c3715SXin Li #ifndef TYPE
31*bf2c3715SXin Li #define TYPE float
32*bf2c3715SXin Li #endif
33*bf2c3715SXin Li
34*bf2c3715SXin Li #ifndef NFFT
35*bf2c3715SXin Li #define NFFT 1024
36*bf2c3715SXin Li #endif
37*bf2c3715SXin Li #ifndef NDATA
38*bf2c3715SXin Li #define NDATA 1000000
39*bf2c3715SXin Li #endif
40*bf2c3715SXin Li
41*bf2c3715SXin Li using namespace Eigen;
42*bf2c3715SXin Li
43*bf2c3715SXin Li template <typename T>
bench(int nfft,bool fwd,bool unscaled=false,bool halfspec=false)44*bf2c3715SXin Li void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false)
45*bf2c3715SXin Li {
46*bf2c3715SXin Li typedef typename NumTraits<T>::Real Scalar;
47*bf2c3715SXin Li typedef typename std::complex<Scalar> Complex;
48*bf2c3715SXin Li int nits = NDATA/nfft;
49*bf2c3715SXin Li vector<T> inbuf(nfft);
50*bf2c3715SXin Li vector<Complex > outbuf(nfft);
51*bf2c3715SXin Li FFT< Scalar > fft;
52*bf2c3715SXin Li
53*bf2c3715SXin Li if (unscaled) {
54*bf2c3715SXin Li fft.SetFlag(fft.Unscaled);
55*bf2c3715SXin Li cout << "unscaled ";
56*bf2c3715SXin Li }
57*bf2c3715SXin Li if (halfspec) {
58*bf2c3715SXin Li fft.SetFlag(fft.HalfSpectrum);
59*bf2c3715SXin Li cout << "halfspec ";
60*bf2c3715SXin Li }
61*bf2c3715SXin Li
62*bf2c3715SXin Li
63*bf2c3715SXin Li std::fill(inbuf.begin(),inbuf.end(),0);
64*bf2c3715SXin Li fft.fwd( outbuf , inbuf);
65*bf2c3715SXin Li
66*bf2c3715SXin Li BenchTimer timer;
67*bf2c3715SXin Li timer.reset();
68*bf2c3715SXin Li for (int k=0;k<8;++k) {
69*bf2c3715SXin Li timer.start();
70*bf2c3715SXin Li if (fwd)
71*bf2c3715SXin Li for(int i = 0; i < nits; i++)
72*bf2c3715SXin Li fft.fwd( outbuf , inbuf);
73*bf2c3715SXin Li else
74*bf2c3715SXin Li for(int i = 0; i < nits; i++)
75*bf2c3715SXin Li fft.inv(inbuf,outbuf);
76*bf2c3715SXin Li timer.stop();
77*bf2c3715SXin Li }
78*bf2c3715SXin Li
79*bf2c3715SXin Li cout << nameof<Scalar>() << " ";
80*bf2c3715SXin Li double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits );
81*bf2c3715SXin Li if ( NumTraits<T>::IsComplex ) {
82*bf2c3715SXin Li cout << "complex";
83*bf2c3715SXin Li }else{
84*bf2c3715SXin Li cout << "real ";
85*bf2c3715SXin Li mflops /= 2;
86*bf2c3715SXin Li }
87*bf2c3715SXin Li
88*bf2c3715SXin Li
89*bf2c3715SXin Li if (fwd)
90*bf2c3715SXin Li cout << " fwd";
91*bf2c3715SXin Li else
92*bf2c3715SXin Li cout << " inv";
93*bf2c3715SXin Li
94*bf2c3715SXin Li cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n";
95*bf2c3715SXin Li }
96*bf2c3715SXin Li
main(int argc,char ** argv)97*bf2c3715SXin Li int main(int argc,char ** argv)
98*bf2c3715SXin Li {
99*bf2c3715SXin Li bench<complex<float> >(NFFT,true);
100*bf2c3715SXin Li bench<complex<float> >(NFFT,false);
101*bf2c3715SXin Li bench<float>(NFFT,true);
102*bf2c3715SXin Li bench<float>(NFFT,false);
103*bf2c3715SXin Li bench<float>(NFFT,false,true);
104*bf2c3715SXin Li bench<float>(NFFT,false,true,true);
105*bf2c3715SXin Li
106*bf2c3715SXin Li bench<complex<double> >(NFFT,true);
107*bf2c3715SXin Li bench<complex<double> >(NFFT,false);
108*bf2c3715SXin Li bench<double>(NFFT,true);
109*bf2c3715SXin Li bench<double>(NFFT,false);
110*bf2c3715SXin Li bench<complex<long double> >(NFFT,true);
111*bf2c3715SXin Li bench<complex<long double> >(NFFT,false);
112*bf2c3715SXin Li bench<long double>(NFFT,true);
113*bf2c3715SXin Li bench<long double>(NFFT,false);
114*bf2c3715SXin Li return 0;
115*bf2c3715SXin Li }
116