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