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