|
|
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Mark Borgerding mark a borgerding net
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iostream>
#include <bench/BenchUtil.h>
#include <complex>
#include <vector>
#include <Eigen/Core>
#include <unsupported/Eigen/FFT>
using namespace Eigen; using namespace std;
template <typename T> string nameof();
template <> string nameof<float>() {return "float";} template <> string nameof<double>() {return "double";} template <> string nameof<long double>() {return "long double";}
#ifndef TYPE
#define TYPE float
#endif
#ifndef NFFT
#define NFFT 1024
#endif
#ifndef NDATA
#define NDATA 1000000
#endif
using namespace Eigen;
template <typename T> void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false) { typedef typename NumTraits<T>::Real Scalar; typedef typename std::complex<Scalar> Complex; int nits = NDATA/nfft; vector<T> inbuf(nfft); vector<Complex > outbuf(nfft); FFT< Scalar > fft;
if (unscaled) { fft.SetFlag(fft.Unscaled); cout << "unscaled "; } if (halfspec) { fft.SetFlag(fft.HalfSpectrum); cout << "halfspec "; }
std::fill(inbuf.begin(),inbuf.end(),0); fft.fwd( outbuf , inbuf);
BenchTimer timer; timer.reset(); for (int k=0;k<8;++k) { timer.start(); if (fwd) for(int i = 0; i < nits; i++) fft.fwd( outbuf , inbuf); else for(int i = 0; i < nits; i++) fft.inv(inbuf,outbuf); timer.stop(); }
cout << nameof<Scalar>() << " "; double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits ); if ( NumTraits<T>::IsComplex ) { cout << "complex"; }else{ cout << "real "; mflops /= 2; }
if (fwd) cout << " fwd"; else cout << " inv";
cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n"; }
int main(int argc,char ** argv) { bench<complex<float> >(NFFT,true); bench<complex<float> >(NFFT,false); bench<float>(NFFT,true); bench<float>(NFFT,false); bench<float>(NFFT,false,true); bench<float>(NFFT,false,true,true);
bench<complex<double> >(NFFT,true); bench<complex<double> >(NFFT,false); bench<double>(NFFT,true); bench<double>(NFFT,false); bench<complex<long double> >(NFFT,true); bench<complex<long double> >(NFFT,false); bench<long double>(NFFT,true); bench<long double>(NFFT,false); return 0; }
|