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 } 116