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 |
|
---|
26 | template <> string nameof<float>() {return "float";}
|
---|
27 | template <> string nameof<double>() {return "double";}
|
---|
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>
|
---|
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 |
|
---|
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 | }
|
---|