Home | History | Annotate | Download | only in bench
      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