xref: /aosp_15_r20/external/pffft/bench_pffft.c (revision 3f1979aa0d7ad34fcf3763de7b7b8f8cd67e5bdd)
1*3f1979aaSAndroid Build Coastguard Worker /*
2*3f1979aaSAndroid Build Coastguard Worker   Copyright (c) 2013 Julien Pommier.
3*3f1979aaSAndroid Build Coastguard Worker   Copyright (c) 2019  Hayati Ayguen ( [email protected] )
4*3f1979aaSAndroid Build Coastguard Worker 
5*3f1979aaSAndroid Build Coastguard Worker   Small test & bench for PFFFT, comparing its performance with the scalar FFTPACK, FFTW, and Apple vDSP
6*3f1979aaSAndroid Build Coastguard Worker 
7*3f1979aaSAndroid Build Coastguard Worker   How to build:
8*3f1979aaSAndroid Build Coastguard Worker 
9*3f1979aaSAndroid Build Coastguard Worker   on linux, with fftw3:
10*3f1979aaSAndroid Build Coastguard Worker   gcc -o test_pffft -DHAVE_FFTW -msse -mfpmath=sse -O3 -Wall -W pffft.c test_pffft.c fftpack.c -L/usr/local/lib -I/usr/local/include/ -lfftw3f -lm
11*3f1979aaSAndroid Build Coastguard Worker 
12*3f1979aaSAndroid Build Coastguard Worker   on macos, without fftw3:
13*3f1979aaSAndroid Build Coastguard Worker   clang -o test_pffft -DHAVE_VECLIB -O3 -Wall -W pffft.c test_pffft.c fftpack.c -L/usr/local/lib -I/usr/local/include/ -framework Accelerate
14*3f1979aaSAndroid Build Coastguard Worker 
15*3f1979aaSAndroid Build Coastguard Worker   on macos, with fftw3:
16*3f1979aaSAndroid Build Coastguard Worker   clang -o test_pffft -DHAVE_FFTW -DHAVE_VECLIB -O3 -Wall -W pffft.c test_pffft.c fftpack.c -L/usr/local/lib -I/usr/local/include/ -lfftw3f -framework Accelerate
17*3f1979aaSAndroid Build Coastguard Worker 
18*3f1979aaSAndroid Build Coastguard Worker   as alternative: replace clang by gcc.
19*3f1979aaSAndroid Build Coastguard Worker 
20*3f1979aaSAndroid Build Coastguard Worker   on windows, with visual c++:
21*3f1979aaSAndroid Build Coastguard Worker   cl /Ox -D_USE_MATH_DEFINES /arch:SSE test_pffft.c pffft.c fftpack.c
22*3f1979aaSAndroid Build Coastguard Worker 
23*3f1979aaSAndroid Build Coastguard Worker   build without SIMD instructions:
24*3f1979aaSAndroid Build Coastguard Worker   gcc -o test_pffft -DPFFFT_SIMD_DISABLE -O3 -Wall -W pffft.c test_pffft.c fftpack.c -lm
25*3f1979aaSAndroid Build Coastguard Worker 
26*3f1979aaSAndroid Build Coastguard Worker  */
27*3f1979aaSAndroid Build Coastguard Worker 
28*3f1979aaSAndroid Build Coastguard Worker #define CONCAT_TOKENS(A, B)  A ## B
29*3f1979aaSAndroid Build Coastguard Worker #define CONCAT_THREE_TOKENS(A, B, C)  A ## B ## C
30*3f1979aaSAndroid Build Coastguard Worker 
31*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
32*3f1979aaSAndroid Build Coastguard Worker #include "pffft.h"
33*3f1979aaSAndroid Build Coastguard Worker 
34*3f1979aaSAndroid Build Coastguard Worker typedef float pffft_scalar;
35*3f1979aaSAndroid Build Coastguard Worker typedef PFFFT_Setup PFFFT_SETUP;
36*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_FUNC(F)  CONCAT_TOKENS(pffft_, F)
37*3f1979aaSAndroid Build Coastguard Worker 
38*3f1979aaSAndroid Build Coastguard Worker #else
39*3f1979aaSAndroid Build Coastguard Worker /*
40*3f1979aaSAndroid Build Coastguard Worker Note: adapted for double precision dynamic range version.
41*3f1979aaSAndroid Build Coastguard Worker */
42*3f1979aaSAndroid Build Coastguard Worker #include "pffft_double.h"
43*3f1979aaSAndroid Build Coastguard Worker 
44*3f1979aaSAndroid Build Coastguard Worker typedef double pffft_scalar;
45*3f1979aaSAndroid Build Coastguard Worker typedef PFFFTD_Setup PFFFT_SETUP;
46*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_FUNC(F)  CONCAT_TOKENS(pffftd_, F)
47*3f1979aaSAndroid Build Coastguard Worker #endif
48*3f1979aaSAndroid Build Coastguard Worker 
49*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
50*3f1979aaSAndroid Build Coastguard Worker 
51*3f1979aaSAndroid Build Coastguard Worker #include "fftpack.h"
52*3f1979aaSAndroid Build Coastguard Worker 
53*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_GREEN_FFTS
54*3f1979aaSAndroid Build Coastguard Worker #include "fftext.h"
55*3f1979aaSAndroid Build Coastguard Worker #endif
56*3f1979aaSAndroid Build Coastguard Worker 
57*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_KISS_FFT
58*3f1979aaSAndroid Build Coastguard Worker #include <kiss_fft.h>
59*3f1979aaSAndroid Build Coastguard Worker #include <kiss_fftr.h>
60*3f1979aaSAndroid Build Coastguard Worker #endif
61*3f1979aaSAndroid Build Coastguard Worker 
62*3f1979aaSAndroid Build Coastguard Worker #endif
63*3f1979aaSAndroid Build Coastguard Worker 
64*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_POCKET_FFT
65*3f1979aaSAndroid Build Coastguard Worker #include <pocketfft_double.h>
66*3f1979aaSAndroid Build Coastguard Worker #include <pocketfft_single.h>
67*3f1979aaSAndroid Build Coastguard Worker #endif
68*3f1979aaSAndroid Build Coastguard Worker 
69*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
70*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTR_PRE(R)   CONCAT_TOKENS(rffts, R)
71*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTC_PRE(R)   CONCAT_TOKENS(cffts, R)
72*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTR_MID(L,R) CONCAT_THREE_TOKENS(L, rffts, R)
73*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTC_MID(L,R) CONCAT_THREE_TOKENS(L, cffts, R)
74*3f1979aaSAndroid Build Coastguard Worker #else
75*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTR_PRE(R)   CONCAT_TOKENS(rfft, R)
76*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTC_PRE(R)   CONCAT_TOKENS(cfft, R)
77*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTR_MID(L,R) CONCAT_THREE_TOKENS(L, rfft, R)
78*3f1979aaSAndroid Build Coastguard Worker   #define POCKFFTC_MID(L,R) CONCAT_THREE_TOKENS(L, cfft, R)
79*3f1979aaSAndroid Build Coastguard Worker #endif
80*3f1979aaSAndroid Build Coastguard Worker 
81*3f1979aaSAndroid Build Coastguard Worker 
82*3f1979aaSAndroid Build Coastguard Worker 
83*3f1979aaSAndroid Build Coastguard Worker #include <math.h>
84*3f1979aaSAndroid Build Coastguard Worker #include <stdio.h>
85*3f1979aaSAndroid Build Coastguard Worker #include <stdlib.h>
86*3f1979aaSAndroid Build Coastguard Worker #include <time.h>
87*3f1979aaSAndroid Build Coastguard Worker #include <assert.h>
88*3f1979aaSAndroid Build Coastguard Worker #include <string.h>
89*3f1979aaSAndroid Build Coastguard Worker 
90*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_SYS_TIMES
91*3f1979aaSAndroid Build Coastguard Worker #  include <sys/times.h>
92*3f1979aaSAndroid Build Coastguard Worker #  include <unistd.h>
93*3f1979aaSAndroid Build Coastguard Worker #endif
94*3f1979aaSAndroid Build Coastguard Worker 
95*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_VECLIB
96*3f1979aaSAndroid Build Coastguard Worker #  include <Accelerate/Accelerate.h>
97*3f1979aaSAndroid Build Coastguard Worker #endif
98*3f1979aaSAndroid Build Coastguard Worker 
99*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_FFTW
100*3f1979aaSAndroid Build Coastguard Worker #  include <fftw3.h>
101*3f1979aaSAndroid Build Coastguard Worker 
102*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
103*3f1979aaSAndroid Build Coastguard Worker typedef fftwf_plan FFTW_PLAN;
104*3f1979aaSAndroid Build Coastguard Worker typedef fftwf_complex FFTW_COMPLEX;
105*3f1979aaSAndroid Build Coastguard Worker #define FFTW_FUNC(F)  CONCAT_TOKENS(fftwf_, F)
106*3f1979aaSAndroid Build Coastguard Worker #else
107*3f1979aaSAndroid Build Coastguard Worker typedef fftw_plan FFTW_PLAN;
108*3f1979aaSAndroid Build Coastguard Worker typedef fftw_complex FFTW_COMPLEX;
109*3f1979aaSAndroid Build Coastguard Worker #define FFTW_FUNC(F)  CONCAT_TOKENS(fftw_, F)
110*3f1979aaSAndroid Build Coastguard Worker #endif
111*3f1979aaSAndroid Build Coastguard Worker 
112*3f1979aaSAndroid Build Coastguard Worker #endif /* HAVE_FFTW */
113*3f1979aaSAndroid Build Coastguard Worker 
114*3f1979aaSAndroid Build Coastguard Worker #ifndef M_LN2
115*3f1979aaSAndroid Build Coastguard Worker   #define M_LN2   0.69314718055994530942  /* log_e 2 */
116*3f1979aaSAndroid Build Coastguard Worker #endif
117*3f1979aaSAndroid Build Coastguard Worker 
118*3f1979aaSAndroid Build Coastguard Worker 
119*3f1979aaSAndroid Build Coastguard Worker #define NUM_FFT_ALGOS  9
120*3f1979aaSAndroid Build Coastguard Worker enum {
121*3f1979aaSAndroid Build Coastguard Worker   ALGO_FFTPACK = 0,
122*3f1979aaSAndroid Build Coastguard Worker   ALGO_VECLIB,
123*3f1979aaSAndroid Build Coastguard Worker   ALGO_FFTW_ESTIM,
124*3f1979aaSAndroid Build Coastguard Worker   ALGO_FFTW_AUTO,
125*3f1979aaSAndroid Build Coastguard Worker   ALGO_GREEN,
126*3f1979aaSAndroid Build Coastguard Worker   ALGO_KISS,
127*3f1979aaSAndroid Build Coastguard Worker   ALGO_POCKET,
128*3f1979aaSAndroid Build Coastguard Worker   ALGO_PFFFT_U, /* = 7 */
129*3f1979aaSAndroid Build Coastguard Worker   ALGO_PFFFT_O  /* = 8 */
130*3f1979aaSAndroid Build Coastguard Worker };
131*3f1979aaSAndroid Build Coastguard Worker 
132*3f1979aaSAndroid Build Coastguard Worker #define NUM_TYPES      7
133*3f1979aaSAndroid Build Coastguard Worker enum {
134*3f1979aaSAndroid Build Coastguard Worker   TYPE_PREP = 0,         /* time for preparation in ms */
135*3f1979aaSAndroid Build Coastguard Worker   TYPE_DUR_NS = 1,       /* time per fft in ns */
136*3f1979aaSAndroid Build Coastguard Worker   TYPE_DUR_FASTEST = 2,  /* relative time to fastest */
137*3f1979aaSAndroid Build Coastguard Worker   TYPE_REL_PFFFT = 3,    /* relative time to ALGO_PFFFT */
138*3f1979aaSAndroid Build Coastguard Worker   TYPE_ITER = 4,         /* # of iterations in measurement */
139*3f1979aaSAndroid Build Coastguard Worker   TYPE_MFLOPS = 5,       /* MFlops/sec */
140*3f1979aaSAndroid Build Coastguard Worker   TYPE_DUR_TOT = 6       /* test duration in sec */
141*3f1979aaSAndroid Build Coastguard Worker };
142*3f1979aaSAndroid Build Coastguard Worker /* double tmeas[NUM_TYPES][NUM_FFT_ALGOS]; */
143*3f1979aaSAndroid Build Coastguard Worker 
144*3f1979aaSAndroid Build Coastguard Worker const char * algoName[NUM_FFT_ALGOS] = {
145*3f1979aaSAndroid Build Coastguard Worker   "FFTPack      ",
146*3f1979aaSAndroid Build Coastguard Worker   "vDSP (vec)   ",
147*3f1979aaSAndroid Build Coastguard Worker   "FFTW F(estim)",
148*3f1979aaSAndroid Build Coastguard Worker   "FFTW F(auto) ",
149*3f1979aaSAndroid Build Coastguard Worker   "Green        ",
150*3f1979aaSAndroid Build Coastguard Worker   "Kiss         ",
151*3f1979aaSAndroid Build Coastguard Worker   "Pocket       ",
152*3f1979aaSAndroid Build Coastguard Worker   "PFFFT-U(simd)",  /* unordered */
153*3f1979aaSAndroid Build Coastguard Worker   "PFFFT (simd) "   /* ordered */
154*3f1979aaSAndroid Build Coastguard Worker };
155*3f1979aaSAndroid Build Coastguard Worker 
156*3f1979aaSAndroid Build Coastguard Worker 
157*3f1979aaSAndroid Build Coastguard Worker int compiledInAlgo[NUM_FFT_ALGOS] = {
158*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
159*3f1979aaSAndroid Build Coastguard Worker   1, /* "FFTPack    " */
160*3f1979aaSAndroid Build Coastguard Worker #else
161*3f1979aaSAndroid Build Coastguard Worker   0, /* "FFTPack    " */
162*3f1979aaSAndroid Build Coastguard Worker #endif
163*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_VECLIB) && defined(PFFFT_ENABLE_FLOAT)
164*3f1979aaSAndroid Build Coastguard Worker   1, /* "vDSP (vec) " */
165*3f1979aaSAndroid Build Coastguard Worker #else
166*3f1979aaSAndroid Build Coastguard Worker   0,
167*3f1979aaSAndroid Build Coastguard Worker #endif
168*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_FFTW)
169*3f1979aaSAndroid Build Coastguard Worker   1, /* "FFTW(estim)" */
170*3f1979aaSAndroid Build Coastguard Worker   1, /* "FFTW (auto)" */
171*3f1979aaSAndroid Build Coastguard Worker #else
172*3f1979aaSAndroid Build Coastguard Worker   0, 0,
173*3f1979aaSAndroid Build Coastguard Worker #endif
174*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_GREEN_FFTS) && defined(PFFFT_ENABLE_FLOAT)
175*3f1979aaSAndroid Build Coastguard Worker   1, /* "Green      " */
176*3f1979aaSAndroid Build Coastguard Worker #else
177*3f1979aaSAndroid Build Coastguard Worker   0,
178*3f1979aaSAndroid Build Coastguard Worker #endif
179*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_KISS_FFT) && defined(PFFFT_ENABLE_FLOAT)
180*3f1979aaSAndroid Build Coastguard Worker   1, /* "Kiss       " */
181*3f1979aaSAndroid Build Coastguard Worker #else
182*3f1979aaSAndroid Build Coastguard Worker   0,
183*3f1979aaSAndroid Build Coastguard Worker #endif
184*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_POCKET_FFT)
185*3f1979aaSAndroid Build Coastguard Worker   1, /* "Pocket     " */
186*3f1979aaSAndroid Build Coastguard Worker #else
187*3f1979aaSAndroid Build Coastguard Worker   0,
188*3f1979aaSAndroid Build Coastguard Worker #endif
189*3f1979aaSAndroid Build Coastguard Worker   1, /* "PFFFT_U    " */
190*3f1979aaSAndroid Build Coastguard Worker   1  /* "PFFFT_O    " */
191*3f1979aaSAndroid Build Coastguard Worker };
192*3f1979aaSAndroid Build Coastguard Worker 
193*3f1979aaSAndroid Build Coastguard Worker const char * algoTableHeader[NUM_FFT_ALGOS][2] = {
194*3f1979aaSAndroid Build Coastguard Worker { "| real FFTPack ", "| cplx FFTPack " },
195*3f1979aaSAndroid Build Coastguard Worker { "|  real   vDSP ", "|  cplx   vDSP " },
196*3f1979aaSAndroid Build Coastguard Worker { "|real FFTWestim", "|cplx FFTWestim" },
197*3f1979aaSAndroid Build Coastguard Worker { "|real FFTWauto ", "|cplx FFTWauto " },
198*3f1979aaSAndroid Build Coastguard Worker { "|  real  Green ", "|  cplx  Green " },
199*3f1979aaSAndroid Build Coastguard Worker { "|  real   Kiss ", "|  cplx   Kiss " },
200*3f1979aaSAndroid Build Coastguard Worker { "|  real Pocket ", "|  cplx Pocket " },
201*3f1979aaSAndroid Build Coastguard Worker { "| real PFFFT-U ", "| cplx PFFFT-U " },
202*3f1979aaSAndroid Build Coastguard Worker { "|  real  PFFFT ", "|  cplx  PFFFT " } };
203*3f1979aaSAndroid Build Coastguard Worker 
204*3f1979aaSAndroid Build Coastguard Worker const char * typeText[NUM_TYPES] = {
205*3f1979aaSAndroid Build Coastguard Worker   "preparation in ms",
206*3f1979aaSAndroid Build Coastguard Worker   "time per fft in ns",
207*3f1979aaSAndroid Build Coastguard Worker   "relative to fastest",
208*3f1979aaSAndroid Build Coastguard Worker   "relative to pffft",
209*3f1979aaSAndroid Build Coastguard Worker   "measured_num_iters",
210*3f1979aaSAndroid Build Coastguard Worker   "mflops",
211*3f1979aaSAndroid Build Coastguard Worker   "test duration in sec"
212*3f1979aaSAndroid Build Coastguard Worker };
213*3f1979aaSAndroid Build Coastguard Worker 
214*3f1979aaSAndroid Build Coastguard Worker const char * typeFilenamePart[NUM_TYPES] = {
215*3f1979aaSAndroid Build Coastguard Worker   "1-preparation-in-ms",
216*3f1979aaSAndroid Build Coastguard Worker   "2-timePerFft-in-ns",
217*3f1979aaSAndroid Build Coastguard Worker   "3-rel-fastest",
218*3f1979aaSAndroid Build Coastguard Worker   "4-rel-pffft",
219*3f1979aaSAndroid Build Coastguard Worker   "5-num-iter",
220*3f1979aaSAndroid Build Coastguard Worker   "6-mflops",
221*3f1979aaSAndroid Build Coastguard Worker   "7-duration-in-sec"
222*3f1979aaSAndroid Build Coastguard Worker };
223*3f1979aaSAndroid Build Coastguard Worker 
224*3f1979aaSAndroid Build Coastguard Worker #define SAVE_ALL_TYPES  0
225*3f1979aaSAndroid Build Coastguard Worker 
226*3f1979aaSAndroid Build Coastguard Worker const int saveType[NUM_TYPES] = {
227*3f1979aaSAndroid Build Coastguard Worker   1, /* "1-preparation-in-ms" */
228*3f1979aaSAndroid Build Coastguard Worker   0, /* "2-timePerFft-in-ns"  */
229*3f1979aaSAndroid Build Coastguard Worker   0, /* "3-rel-fastest"       */
230*3f1979aaSAndroid Build Coastguard Worker   1, /* "4-rel-pffft"         */
231*3f1979aaSAndroid Build Coastguard Worker   1, /* "5-num-iter"          */
232*3f1979aaSAndroid Build Coastguard Worker   1, /* "6-mflops"            */
233*3f1979aaSAndroid Build Coastguard Worker   1, /* "7-duration-in-sec"   */
234*3f1979aaSAndroid Build Coastguard Worker };
235*3f1979aaSAndroid Build Coastguard Worker 
236*3f1979aaSAndroid Build Coastguard Worker 
237*3f1979aaSAndroid Build Coastguard Worker #define MAX(x,y) ((x)>(y)?(x):(y))
238*3f1979aaSAndroid Build Coastguard Worker #define MIN(x,y) ((x)<(y)?(x):(y))
239*3f1979aaSAndroid Build Coastguard Worker 
Log2(unsigned v)240*3f1979aaSAndroid Build Coastguard Worker unsigned Log2(unsigned v) {
241*3f1979aaSAndroid Build Coastguard Worker   /* we don't need speed records .. obvious way is good enough */
242*3f1979aaSAndroid Build Coastguard Worker   /* https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious */
243*3f1979aaSAndroid Build Coastguard Worker   /* Find the log base 2 of an integer with the MSB N set in O(N) operations (the obvious way):
244*3f1979aaSAndroid Build Coastguard Worker    * unsigned v: 32-bit word to find the log base 2 of */
245*3f1979aaSAndroid Build Coastguard Worker   unsigned r = 0; /* r will be lg(v) */
246*3f1979aaSAndroid Build Coastguard Worker   while (v >>= 1)
247*3f1979aaSAndroid Build Coastguard Worker   {
248*3f1979aaSAndroid Build Coastguard Worker     r++;
249*3f1979aaSAndroid Build Coastguard Worker   }
250*3f1979aaSAndroid Build Coastguard Worker   return r;
251*3f1979aaSAndroid Build Coastguard Worker }
252*3f1979aaSAndroid Build Coastguard Worker 
253*3f1979aaSAndroid Build Coastguard Worker 
frand()254*3f1979aaSAndroid Build Coastguard Worker double frand() {
255*3f1979aaSAndroid Build Coastguard Worker   return rand()/(double)RAND_MAX;
256*3f1979aaSAndroid Build Coastguard Worker }
257*3f1979aaSAndroid Build Coastguard Worker 
258*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_SYS_TIMES)
uclock_sec(void)259*3f1979aaSAndroid Build Coastguard Worker   inline double uclock_sec(void) {
260*3f1979aaSAndroid Build Coastguard Worker     static double ttclk = 0.;
261*3f1979aaSAndroid Build Coastguard Worker     struct tms t;
262*3f1979aaSAndroid Build Coastguard Worker     if (ttclk == 0.)
263*3f1979aaSAndroid Build Coastguard Worker       ttclk = sysconf(_SC_CLK_TCK);
264*3f1979aaSAndroid Build Coastguard Worker     times(&t);
265*3f1979aaSAndroid Build Coastguard Worker     /* use only the user time of this process - not realtime, which depends on OS-scheduler .. */
266*3f1979aaSAndroid Build Coastguard Worker     return ((double)t.tms_utime)) / ttclk;
267*3f1979aaSAndroid Build Coastguard Worker   }
268*3f1979aaSAndroid Build Coastguard Worker # else
269*3f1979aaSAndroid Build Coastguard Worker   double uclock_sec(void)
270*3f1979aaSAndroid Build Coastguard Worker { return (double)clock()/(double)CLOCKS_PER_SEC; }
271*3f1979aaSAndroid Build Coastguard Worker #endif
272*3f1979aaSAndroid Build Coastguard Worker 
273*3f1979aaSAndroid Build Coastguard Worker 
274*3f1979aaSAndroid Build Coastguard Worker /* compare results with the regular fftpack */
275*3f1979aaSAndroid Build Coastguard Worker void pffft_validate_N(int N, int cplx) {
276*3f1979aaSAndroid Build Coastguard Worker 
277*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
278*3f1979aaSAndroid Build Coastguard Worker 
279*3f1979aaSAndroid Build Coastguard Worker   int Nfloat = N*(cplx?2:1);
280*3f1979aaSAndroid Build Coastguard Worker   int Nbytes = Nfloat * sizeof(pffft_scalar);
281*3f1979aaSAndroid Build Coastguard Worker   float *ref, *in, *out, *tmp, *tmp2;
282*3f1979aaSAndroid Build Coastguard Worker   PFFFT_SETUP *s = PFFFT_FUNC(new_setup)(N, cplx ? PFFFT_COMPLEX : PFFFT_REAL);
283*3f1979aaSAndroid Build Coastguard Worker   int pass;
284*3f1979aaSAndroid Build Coastguard Worker 
285*3f1979aaSAndroid Build Coastguard Worker 
286*3f1979aaSAndroid Build Coastguard Worker   if (!s) { printf("Skipping N=%d, not supported\n", N); return; }
287*3f1979aaSAndroid Build Coastguard Worker   ref = PFFFT_FUNC(aligned_malloc)(Nbytes);
288*3f1979aaSAndroid Build Coastguard Worker   in = PFFFT_FUNC(aligned_malloc)(Nbytes);
289*3f1979aaSAndroid Build Coastguard Worker   out = PFFFT_FUNC(aligned_malloc)(Nbytes);
290*3f1979aaSAndroid Build Coastguard Worker   tmp = PFFFT_FUNC(aligned_malloc)(Nbytes);
291*3f1979aaSAndroid Build Coastguard Worker   tmp2 = PFFFT_FUNC(aligned_malloc)(Nbytes);
292*3f1979aaSAndroid Build Coastguard Worker 
293*3f1979aaSAndroid Build Coastguard Worker   for (pass=0; pass < 2; ++pass) {
294*3f1979aaSAndroid Build Coastguard Worker     float ref_max = 0;
295*3f1979aaSAndroid Build Coastguard Worker     int k;
296*3f1979aaSAndroid Build Coastguard Worker     /* printf("N=%d pass=%d cplx=%d\n", N, pass, cplx); */
297*3f1979aaSAndroid Build Coastguard Worker     /* compute reference solution with FFTPACK */
298*3f1979aaSAndroid Build Coastguard Worker     if (pass == 0) {
299*3f1979aaSAndroid Build Coastguard Worker       float *wrk = malloc(2*Nbytes+15*sizeof(pffft_scalar));
300*3f1979aaSAndroid Build Coastguard Worker       for (k=0; k < Nfloat; ++k) {
301*3f1979aaSAndroid Build Coastguard Worker         ref[k] = in[k] = (float)( frand()*2-1 );
302*3f1979aaSAndroid Build Coastguard Worker         out[k] = 1e30F;
303*3f1979aaSAndroid Build Coastguard Worker       }
304*3f1979aaSAndroid Build Coastguard Worker       if (!cplx) {
305*3f1979aaSAndroid Build Coastguard Worker         rffti(N, wrk);
306*3f1979aaSAndroid Build Coastguard Worker         rfftf(N, ref, wrk);
307*3f1979aaSAndroid Build Coastguard Worker         /* use our ordering for real ffts instead of the one of fftpack */
308*3f1979aaSAndroid Build Coastguard Worker         {
309*3f1979aaSAndroid Build Coastguard Worker           float refN=ref[N-1];
310*3f1979aaSAndroid Build Coastguard Worker           for (k=N-2; k >= 1; --k) ref[k+1] = ref[k];
311*3f1979aaSAndroid Build Coastguard Worker           ref[1] = refN;
312*3f1979aaSAndroid Build Coastguard Worker         }
313*3f1979aaSAndroid Build Coastguard Worker       } else {
314*3f1979aaSAndroid Build Coastguard Worker         cffti(N, wrk);
315*3f1979aaSAndroid Build Coastguard Worker         cfftf(N, ref, wrk);
316*3f1979aaSAndroid Build Coastguard Worker       }
317*3f1979aaSAndroid Build Coastguard Worker       free(wrk);
318*3f1979aaSAndroid Build Coastguard Worker     }
319*3f1979aaSAndroid Build Coastguard Worker 
320*3f1979aaSAndroid Build Coastguard Worker     for (k = 0; k < Nfloat; ++k) ref_max = MAX(ref_max, (float)( fabs(ref[k]) ));
321*3f1979aaSAndroid Build Coastguard Worker 
322*3f1979aaSAndroid Build Coastguard Worker 
323*3f1979aaSAndroid Build Coastguard Worker     /* pass 0 : non canonical ordering of transform coefficients */
324*3f1979aaSAndroid Build Coastguard Worker     if (pass == 0) {
325*3f1979aaSAndroid Build Coastguard Worker       /* test forward transform, with different input / output */
326*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform)(s, in, tmp, 0, PFFFT_FORWARD);
327*3f1979aaSAndroid Build Coastguard Worker       memcpy(tmp2, tmp, Nbytes);
328*3f1979aaSAndroid Build Coastguard Worker       memcpy(tmp, in, Nbytes);
329*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform)(s, tmp, tmp, 0, PFFFT_FORWARD);
330*3f1979aaSAndroid Build Coastguard Worker       for (k = 0; k < Nfloat; ++k) {
331*3f1979aaSAndroid Build Coastguard Worker         assert(tmp2[k] == tmp[k]);
332*3f1979aaSAndroid Build Coastguard Worker       }
333*3f1979aaSAndroid Build Coastguard Worker 
334*3f1979aaSAndroid Build Coastguard Worker       /* test reordering */
335*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zreorder)(s, tmp, out, PFFFT_FORWARD);
336*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zreorder)(s, out, tmp, PFFFT_BACKWARD);
337*3f1979aaSAndroid Build Coastguard Worker       for (k = 0; k < Nfloat; ++k) {
338*3f1979aaSAndroid Build Coastguard Worker         assert(tmp2[k] == tmp[k]);
339*3f1979aaSAndroid Build Coastguard Worker       }
340*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zreorder)(s, tmp, out, PFFFT_FORWARD);
341*3f1979aaSAndroid Build Coastguard Worker     } else {
342*3f1979aaSAndroid Build Coastguard Worker       /* pass 1 : canonical ordering of transform coeffs. */
343*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform_ordered)(s, in, tmp, 0, PFFFT_FORWARD);
344*3f1979aaSAndroid Build Coastguard Worker       memcpy(tmp2, tmp, Nbytes);
345*3f1979aaSAndroid Build Coastguard Worker       memcpy(tmp, in, Nbytes);
346*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform_ordered)(s, tmp, tmp, 0, PFFFT_FORWARD);
347*3f1979aaSAndroid Build Coastguard Worker       for (k = 0; k < Nfloat; ++k) {
348*3f1979aaSAndroid Build Coastguard Worker         assert(tmp2[k] == tmp[k]);
349*3f1979aaSAndroid Build Coastguard Worker       }
350*3f1979aaSAndroid Build Coastguard Worker       memcpy(out, tmp, Nbytes);
351*3f1979aaSAndroid Build Coastguard Worker     }
352*3f1979aaSAndroid Build Coastguard Worker 
353*3f1979aaSAndroid Build Coastguard Worker     {
354*3f1979aaSAndroid Build Coastguard Worker       for (k=0; k < Nfloat; ++k) {
355*3f1979aaSAndroid Build Coastguard Worker         if (!(fabs(ref[k] - out[k]) < 1e-3*ref_max)) {
356*3f1979aaSAndroid Build Coastguard Worker           printf("%s forward PFFFT mismatch found for N=%d\n", (cplx?"CPLX":"REAL"), N);
357*3f1979aaSAndroid Build Coastguard Worker           exit(1);
358*3f1979aaSAndroid Build Coastguard Worker         }
359*3f1979aaSAndroid Build Coastguard Worker       }
360*3f1979aaSAndroid Build Coastguard Worker 
361*3f1979aaSAndroid Build Coastguard Worker       if (pass == 0) PFFFT_FUNC(transform)(s, tmp, out, 0, PFFFT_BACKWARD);
362*3f1979aaSAndroid Build Coastguard Worker       else   PFFFT_FUNC(transform_ordered)(s, tmp, out, 0, PFFFT_BACKWARD);
363*3f1979aaSAndroid Build Coastguard Worker       memcpy(tmp2, out, Nbytes);
364*3f1979aaSAndroid Build Coastguard Worker       memcpy(out, tmp, Nbytes);
365*3f1979aaSAndroid Build Coastguard Worker       if (pass == 0) PFFFT_FUNC(transform)(s, out, out, 0, PFFFT_BACKWARD);
366*3f1979aaSAndroid Build Coastguard Worker       else   PFFFT_FUNC(transform_ordered)(s, out, out, 0, PFFFT_BACKWARD);
367*3f1979aaSAndroid Build Coastguard Worker       for (k = 0; k < Nfloat; ++k) {
368*3f1979aaSAndroid Build Coastguard Worker         assert(tmp2[k] == out[k]);
369*3f1979aaSAndroid Build Coastguard Worker         out[k] *= 1.f/N;
370*3f1979aaSAndroid Build Coastguard Worker       }
371*3f1979aaSAndroid Build Coastguard Worker       for (k = 0; k < Nfloat; ++k) {
372*3f1979aaSAndroid Build Coastguard Worker         if (fabs(in[k] - out[k]) > 1e-3 * ref_max) {
373*3f1979aaSAndroid Build Coastguard Worker           printf("pass=%d, %s IFFFT does not match for N=%d\n", pass, (cplx?"CPLX":"REAL"), N); break;
374*3f1979aaSAndroid Build Coastguard Worker           exit(1);
375*3f1979aaSAndroid Build Coastguard Worker         }
376*3f1979aaSAndroid Build Coastguard Worker       }
377*3f1979aaSAndroid Build Coastguard Worker     }
378*3f1979aaSAndroid Build Coastguard Worker 
379*3f1979aaSAndroid Build Coastguard Worker     /* quick test of the circular convolution in fft domain */
380*3f1979aaSAndroid Build Coastguard Worker     {
381*3f1979aaSAndroid Build Coastguard Worker       float conv_err = 0, conv_max = 0;
382*3f1979aaSAndroid Build Coastguard Worker 
383*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zreorder)(s, ref, tmp, PFFFT_FORWARD);
384*3f1979aaSAndroid Build Coastguard Worker       memset(out, 0, Nbytes);
385*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zconvolve_accumulate)(s, ref, ref, out, 1.0);
386*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(zreorder)(s, out, tmp2, PFFFT_FORWARD);
387*3f1979aaSAndroid Build Coastguard Worker 
388*3f1979aaSAndroid Build Coastguard Worker       for (k=0; k < Nfloat; k += 2) {
389*3f1979aaSAndroid Build Coastguard Worker         float ar = tmp[k], ai=tmp[k+1];
390*3f1979aaSAndroid Build Coastguard Worker         if (cplx || k > 0) {
391*3f1979aaSAndroid Build Coastguard Worker           tmp[k] = ar*ar - ai*ai;
392*3f1979aaSAndroid Build Coastguard Worker           tmp[k+1] = 2*ar*ai;
393*3f1979aaSAndroid Build Coastguard Worker         } else {
394*3f1979aaSAndroid Build Coastguard Worker           tmp[0] = ar*ar;
395*3f1979aaSAndroid Build Coastguard Worker           tmp[1] = ai*ai;
396*3f1979aaSAndroid Build Coastguard Worker         }
397*3f1979aaSAndroid Build Coastguard Worker       }
398*3f1979aaSAndroid Build Coastguard Worker 
399*3f1979aaSAndroid Build Coastguard Worker       for (k=0; k < Nfloat; ++k) {
400*3f1979aaSAndroid Build Coastguard Worker         float d = fabs(tmp[k] - tmp2[k]), e = fabs(tmp[k]);
401*3f1979aaSAndroid Build Coastguard Worker         if (d > conv_err) conv_err = d;
402*3f1979aaSAndroid Build Coastguard Worker         if (e > conv_max) conv_max = e;
403*3f1979aaSAndroid Build Coastguard Worker       }
404*3f1979aaSAndroid Build Coastguard Worker       if (conv_err > 1e-5*conv_max) {
405*3f1979aaSAndroid Build Coastguard Worker         printf("zconvolve error ? %g %g\n", conv_err, conv_max); exit(1);
406*3f1979aaSAndroid Build Coastguard Worker       }
407*3f1979aaSAndroid Build Coastguard Worker     }
408*3f1979aaSAndroid Build Coastguard Worker 
409*3f1979aaSAndroid Build Coastguard Worker   }
410*3f1979aaSAndroid Build Coastguard Worker 
411*3f1979aaSAndroid Build Coastguard Worker   printf("%s PFFFT is OK for N=%d\n", (cplx?"CPLX":"REAL"), N); fflush(stdout);
412*3f1979aaSAndroid Build Coastguard Worker 
413*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(destroy_setup)(s);
414*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(ref);
415*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(in);
416*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(out);
417*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(tmp);
418*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(tmp2);
419*3f1979aaSAndroid Build Coastguard Worker 
420*3f1979aaSAndroid Build Coastguard Worker #endif /* PFFFT_ENABLE_FLOAT */
421*3f1979aaSAndroid Build Coastguard Worker }
422*3f1979aaSAndroid Build Coastguard Worker 
423*3f1979aaSAndroid Build Coastguard Worker void pffft_validate(int cplx) {
424*3f1979aaSAndroid Build Coastguard Worker   static int Ntest[] = { 16, 32, 64, 96, 128, 160, 192, 256, 288, 384, 5*96, 512, 576, 5*128, 800, 864, 1024, 2048, 2592, 4000, 4096, 12000, 36864, 0};
425*3f1979aaSAndroid Build Coastguard Worker   int k;
426*3f1979aaSAndroid Build Coastguard Worker   for (k = 0; Ntest[k]; ++k) {
427*3f1979aaSAndroid Build Coastguard Worker     int N = Ntest[k];
428*3f1979aaSAndroid Build Coastguard Worker     if (N == 16 && !cplx) continue;
429*3f1979aaSAndroid Build Coastguard Worker     pffft_validate_N(N, cplx);
430*3f1979aaSAndroid Build Coastguard Worker   }
431*3f1979aaSAndroid Build Coastguard Worker }
432*3f1979aaSAndroid Build Coastguard Worker 
433*3f1979aaSAndroid Build Coastguard Worker int array_output_format = 1;
434*3f1979aaSAndroid Build Coastguard Worker 
435*3f1979aaSAndroid Build Coastguard Worker 
436*3f1979aaSAndroid Build Coastguard Worker void print_table(const char *txt, FILE *tableFile) {
437*3f1979aaSAndroid Build Coastguard Worker   fprintf(stdout, "%s", txt);
438*3f1979aaSAndroid Build Coastguard Worker   if (tableFile && tableFile != stdout)
439*3f1979aaSAndroid Build Coastguard Worker     fprintf(tableFile, "%s", txt);
440*3f1979aaSAndroid Build Coastguard Worker }
441*3f1979aaSAndroid Build Coastguard Worker 
442*3f1979aaSAndroid Build Coastguard Worker void print_table_flops(float mflops, FILE *tableFile) {
443*3f1979aaSAndroid Build Coastguard Worker   fprintf(stdout, "|%11.0f   ", mflops);
444*3f1979aaSAndroid Build Coastguard Worker   if (tableFile && tableFile != stdout)
445*3f1979aaSAndroid Build Coastguard Worker     fprintf(tableFile, "|%11.0f   ", mflops);
446*3f1979aaSAndroid Build Coastguard Worker }
447*3f1979aaSAndroid Build Coastguard Worker 
448*3f1979aaSAndroid Build Coastguard Worker void print_table_fftsize(int N, FILE *tableFile) {
449*3f1979aaSAndroid Build Coastguard Worker   fprintf(stdout, "|%9d  ", N);
450*3f1979aaSAndroid Build Coastguard Worker   if (tableFile && tableFile != stdout)
451*3f1979aaSAndroid Build Coastguard Worker     fprintf(tableFile, "|%9d  ", N);
452*3f1979aaSAndroid Build Coastguard Worker }
453*3f1979aaSAndroid Build Coastguard Worker 
454*3f1979aaSAndroid Build Coastguard Worker double show_output(const char *name, int N, int cplx, float flops, float t0, float t1, int max_iter, FILE *tableFile) {
455*3f1979aaSAndroid Build Coastguard Worker   double T = (double)(t1-t0)/2/max_iter * 1e9;
456*3f1979aaSAndroid Build Coastguard Worker   float mflops = flops/1e6/(t1 - t0 + 1e-16);
457*3f1979aaSAndroid Build Coastguard Worker   if (array_output_format) {
458*3f1979aaSAndroid Build Coastguard Worker     if (flops != -1)
459*3f1979aaSAndroid Build Coastguard Worker       print_table_flops(mflops, tableFile);
460*3f1979aaSAndroid Build Coastguard Worker     else
461*3f1979aaSAndroid Build Coastguard Worker       print_table("|        n/a   ", tableFile);
462*3f1979aaSAndroid Build Coastguard Worker   } else {
463*3f1979aaSAndroid Build Coastguard Worker     if (flops != -1) {
464*3f1979aaSAndroid Build Coastguard Worker       printf("N=%5d, %s %16s : %6.0f MFlops [t=%6.0f ns, %d runs]\n", N, (cplx?"CPLX":"REAL"), name, mflops, (t1-t0)/2/max_iter * 1e9, max_iter);
465*3f1979aaSAndroid Build Coastguard Worker     }
466*3f1979aaSAndroid Build Coastguard Worker   }
467*3f1979aaSAndroid Build Coastguard Worker   fflush(stdout);
468*3f1979aaSAndroid Build Coastguard Worker   return T;
469*3f1979aaSAndroid Build Coastguard Worker }
470*3f1979aaSAndroid Build Coastguard Worker 
471*3f1979aaSAndroid Build Coastguard Worker double cal_benchmark(int N, int cplx) {
472*3f1979aaSAndroid Build Coastguard Worker   const int log2N = Log2(N);
473*3f1979aaSAndroid Build Coastguard Worker   int Nfloat = (cplx ? N*2 : N);
474*3f1979aaSAndroid Build Coastguard Worker   int Nbytes = Nfloat * sizeof(pffft_scalar);
475*3f1979aaSAndroid Build Coastguard Worker   pffft_scalar *X = PFFFT_FUNC(aligned_malloc)(Nbytes), *Y = PFFFT_FUNC(aligned_malloc)(Nbytes), *Z = PFFFT_FUNC(aligned_malloc)(Nbytes);
476*3f1979aaSAndroid Build Coastguard Worker   double t0, t1, tstop, T, nI;
477*3f1979aaSAndroid Build Coastguard Worker   int k, iter;
478*3f1979aaSAndroid Build Coastguard Worker 
479*3f1979aaSAndroid Build Coastguard Worker   assert( PFFFT_FUNC(is_power_of_two)(N) );
480*3f1979aaSAndroid Build Coastguard Worker   for (k = 0; k < Nfloat; ++k) {
481*3f1979aaSAndroid Build Coastguard Worker     X[k] = sqrtf(k+1);
482*3f1979aaSAndroid Build Coastguard Worker   }
483*3f1979aaSAndroid Build Coastguard Worker 
484*3f1979aaSAndroid Build Coastguard Worker   /* PFFFT-U (unordered) benchmark */
485*3f1979aaSAndroid Build Coastguard Worker   PFFFT_SETUP *s = PFFFT_FUNC(new_setup)(N, cplx ? PFFFT_COMPLEX : PFFFT_REAL);
486*3f1979aaSAndroid Build Coastguard Worker   assert(s);
487*3f1979aaSAndroid Build Coastguard Worker   iter = 0;
488*3f1979aaSAndroid Build Coastguard Worker   t0 = uclock_sec();
489*3f1979aaSAndroid Build Coastguard Worker   tstop = t0 + 0.25;  /* benchmark duration: 250 ms */
490*3f1979aaSAndroid Build Coastguard Worker   do {
491*3f1979aaSAndroid Build Coastguard Worker     for ( k = 0; k < 512; ++k ) {
492*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform)(s, X, Z, Y, PFFFT_FORWARD);
493*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(transform)(s, X, Z, Y, PFFFT_BACKWARD);
494*3f1979aaSAndroid Build Coastguard Worker       ++iter;
495*3f1979aaSAndroid Build Coastguard Worker     }
496*3f1979aaSAndroid Build Coastguard Worker     t1 = uclock_sec();
497*3f1979aaSAndroid Build Coastguard Worker   } while ( t1 < tstop );
498*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(destroy_setup)(s);
499*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(X);
500*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(Y);
501*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(Z);
502*3f1979aaSAndroid Build Coastguard Worker 
503*3f1979aaSAndroid Build Coastguard Worker   T = ( t1 - t0 );  /* duration per fft() */
504*3f1979aaSAndroid Build Coastguard Worker   nI = ((double)iter) * ( log2N * N );  /* number of iterations "normalized" to O(N) = N*log2(N) */
505*3f1979aaSAndroid Build Coastguard Worker   return (nI / T);    /* normalized iterations per second */
506*3f1979aaSAndroid Build Coastguard Worker }
507*3f1979aaSAndroid Build Coastguard Worker 
508*3f1979aaSAndroid Build Coastguard Worker 
509*3f1979aaSAndroid Build Coastguard Worker 
510*3f1979aaSAndroid Build Coastguard Worker void benchmark_ffts(int N, int cplx, int withFFTWfullMeas, double iterCal, double tmeas[NUM_TYPES][NUM_FFT_ALGOS], int haveAlgo[NUM_FFT_ALGOS], FILE *tableFile ) {
511*3f1979aaSAndroid Build Coastguard Worker   const int log2N = Log2(N);
512*3f1979aaSAndroid Build Coastguard Worker   int nextPow2N = PFFFT_FUNC(next_power_of_two)(N);
513*3f1979aaSAndroid Build Coastguard Worker   int log2NextN = Log2(nextPow2N);
514*3f1979aaSAndroid Build Coastguard Worker   int pffftPow2N = nextPow2N;
515*3f1979aaSAndroid Build Coastguard Worker 
516*3f1979aaSAndroid Build Coastguard Worker   int Nfloat = (cplx ? MAX(nextPow2N, pffftPow2N)*2 : MAX(nextPow2N, pffftPow2N));
517*3f1979aaSAndroid Build Coastguard Worker   int Nmax, k, iter;
518*3f1979aaSAndroid Build Coastguard Worker   int Nbytes = Nfloat * sizeof(pffft_scalar);
519*3f1979aaSAndroid Build Coastguard Worker 
520*3f1979aaSAndroid Build Coastguard Worker   pffft_scalar *X = PFFFT_FUNC(aligned_malloc)(Nbytes + sizeof(pffft_scalar)), *Y = PFFFT_FUNC(aligned_malloc)(Nbytes + 2*sizeof(pffft_scalar) ), *Z = PFFFT_FUNC(aligned_malloc)(Nbytes);
521*3f1979aaSAndroid Build Coastguard Worker   double te, t0, t1, tstop, flops, Tfastest;
522*3f1979aaSAndroid Build Coastguard Worker 
523*3f1979aaSAndroid Build Coastguard Worker   const double max_test_duration = 0.150;   /* test duration 150 ms */
524*3f1979aaSAndroid Build Coastguard Worker   double numIter = max_test_duration * iterCal / ( log2N * N );  /* number of iteration for max_test_duration */
525*3f1979aaSAndroid Build Coastguard Worker   const int step_iter = MAX(1, ((int)(0.01 * numIter)) );  /* one hundredth */
526*3f1979aaSAndroid Build Coastguard Worker   int max_iter = MAX(1, ((int)numIter) );  /* minimum 1 iteration */
527*3f1979aaSAndroid Build Coastguard Worker 
528*3f1979aaSAndroid Build Coastguard Worker   const float checkVal = 12345.0F;
529*3f1979aaSAndroid Build Coastguard Worker 
530*3f1979aaSAndroid Build Coastguard Worker   /* printf("benchmark_ffts(N = %d, cplx = %d): Nfloat = %d, X_mem = 0x%p, X = %p\n", N, cplx, Nfloat, X_mem, X); */
531*3f1979aaSAndroid Build Coastguard Worker 
532*3f1979aaSAndroid Build Coastguard Worker   memset( X, 0, Nfloat * sizeof(pffft_scalar) );
533*3f1979aaSAndroid Build Coastguard Worker   if ( Nfloat < 32 ) {
534*3f1979aaSAndroid Build Coastguard Worker     for (k = 0; k < Nfloat; k += 4)
535*3f1979aaSAndroid Build Coastguard Worker       X[k] = sqrtf(k+1);
536*3f1979aaSAndroid Build Coastguard Worker   } else {
537*3f1979aaSAndroid Build Coastguard Worker     for (k = 0; k < Nfloat; k += (Nfloat/16) )
538*3f1979aaSAndroid Build Coastguard Worker       X[k] = sqrtf(k+1);
539*3f1979aaSAndroid Build Coastguard Worker   }
540*3f1979aaSAndroid Build Coastguard Worker 
541*3f1979aaSAndroid Build Coastguard Worker   for ( k = 0; k < NUM_TYPES; ++k )
542*3f1979aaSAndroid Build Coastguard Worker   {
543*3f1979aaSAndroid Build Coastguard Worker     for ( iter = 0; iter < NUM_FFT_ALGOS; ++iter )
544*3f1979aaSAndroid Build Coastguard Worker       tmeas[k][iter] = 0.0;
545*3f1979aaSAndroid Build Coastguard Worker   }
546*3f1979aaSAndroid Build Coastguard Worker 
547*3f1979aaSAndroid Build Coastguard Worker 
548*3f1979aaSAndroid Build Coastguard Worker   /* FFTPack benchmark */
549*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? N*2 : N);
550*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
551*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
552*3f1979aaSAndroid Build Coastguard Worker   {
553*3f1979aaSAndroid Build Coastguard Worker     float *wrk = malloc(2*Nbytes + 15*sizeof(pffft_scalar));
554*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
555*3f1979aaSAndroid Build Coastguard Worker     if (cplx) cffti(N, wrk);
556*3f1979aaSAndroid Build Coastguard Worker     else      rffti(N, wrk);
557*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
558*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
559*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
560*3f1979aaSAndroid Build Coastguard Worker     do {
561*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
562*3f1979aaSAndroid Build Coastguard Worker         if (cplx) {
563*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
564*3f1979aaSAndroid Build Coastguard Worker           cfftf(N, X, wrk);
565*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
566*3f1979aaSAndroid Build Coastguard Worker           cfftb(N, X, wrk);
567*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
568*3f1979aaSAndroid Build Coastguard Worker         } else {
569*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
570*3f1979aaSAndroid Build Coastguard Worker           rfftf(N, X, wrk);
571*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
572*3f1979aaSAndroid Build Coastguard Worker           rfftb(N, X, wrk);
573*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
574*3f1979aaSAndroid Build Coastguard Worker         }
575*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
576*3f1979aaSAndroid Build Coastguard Worker       }
577*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
578*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
579*3f1979aaSAndroid Build Coastguard Worker 
580*3f1979aaSAndroid Build Coastguard Worker     free(wrk);
581*3f1979aaSAndroid Build Coastguard Worker 
582*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
583*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_FFTPACK] = max_iter;
584*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_FFTPACK] = flops/1e6/(t1 - t0 + 1e-16);
585*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_FFTPACK] = t1 - t0;
586*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_FFTPACK] = show_output("FFTPack", N, cplx, flops, t0, t1, max_iter, tableFile);
587*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_FFTPACK] = (t0 - te) * 1e3;
588*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_FFTPACK] = 1;
589*3f1979aaSAndroid Build Coastguard Worker   }
590*3f1979aaSAndroid Build Coastguard Worker #endif
591*3f1979aaSAndroid Build Coastguard Worker 
592*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_VECLIB) && defined(PFFFT_ENABLE_FLOAT)
593*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? nextPow2N*2 : nextPow2N);
594*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
595*3f1979aaSAndroid Build Coastguard Worker   te = uclock_sec();
596*3f1979aaSAndroid Build Coastguard Worker   if ( 1 || PFFFT_FUNC(is_power_of_two)(N) ) {
597*3f1979aaSAndroid Build Coastguard Worker     FFTSetup setup;
598*3f1979aaSAndroid Build Coastguard Worker 
599*3f1979aaSAndroid Build Coastguard Worker     setup = vDSP_create_fftsetup(log2NextN, FFT_RADIX2);
600*3f1979aaSAndroid Build Coastguard Worker     DSPSplitComplex zsamples;
601*3f1979aaSAndroid Build Coastguard Worker     zsamples.realp = &X[0];
602*3f1979aaSAndroid Build Coastguard Worker     zsamples.imagp = &X[Nfloat/2];
603*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
604*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
605*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
606*3f1979aaSAndroid Build Coastguard Worker     do {
607*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
608*3f1979aaSAndroid Build Coastguard Worker         if (cplx) {
609*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
610*3f1979aaSAndroid Build Coastguard Worker           vDSP_fft_zip(setup, &zsamples, 1, log2NextN, kFFTDirection_Forward);
611*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
612*3f1979aaSAndroid Build Coastguard Worker           vDSP_fft_zip(setup, &zsamples, 1, log2NextN, kFFTDirection_Inverse);
613*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
614*3f1979aaSAndroid Build Coastguard Worker         } else {
615*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
616*3f1979aaSAndroid Build Coastguard Worker           vDSP_fft_zrip(setup, &zsamples, 1, log2NextN, kFFTDirection_Forward);
617*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
618*3f1979aaSAndroid Build Coastguard Worker           vDSP_fft_zrip(setup, &zsamples, 1, log2NextN, kFFTDirection_Inverse);
619*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
620*3f1979aaSAndroid Build Coastguard Worker         }
621*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
622*3f1979aaSAndroid Build Coastguard Worker       }
623*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
624*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
625*3f1979aaSAndroid Build Coastguard Worker 
626*3f1979aaSAndroid Build Coastguard Worker     vDSP_destroy_fftsetup(setup);
627*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
628*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_VECLIB] = max_iter;
629*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_VECLIB] = flops/1e6/(t1 - t0 + 1e-16);
630*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_VECLIB] = t1 - t0;
631*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_VECLIB] = show_output("vDSP", N, cplx, flops, t0, t1, max_iter, tableFile);
632*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_VECLIB] = (t0 - te) * 1e3;
633*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_VECLIB] = 1;
634*3f1979aaSAndroid Build Coastguard Worker   } else {
635*3f1979aaSAndroid Build Coastguard Worker     show_output("vDSP", N, cplx, -1, -1, -1, -1, tableFile);
636*3f1979aaSAndroid Build Coastguard Worker   }
637*3f1979aaSAndroid Build Coastguard Worker #endif
638*3f1979aaSAndroid Build Coastguard Worker 
639*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_FFTW)
640*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? N*2 : N);
641*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
642*3f1979aaSAndroid Build Coastguard Worker   {
643*3f1979aaSAndroid Build Coastguard Worker     /* int flags = (N <= (256*1024) ? FFTW_MEASURE : FFTW_ESTIMATE);  measure takes a lot of time on largest ffts */
644*3f1979aaSAndroid Build Coastguard Worker     int flags = FFTW_ESTIMATE;
645*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
646*3f1979aaSAndroid Build Coastguard Worker 
647*3f1979aaSAndroid Build Coastguard Worker     FFTW_PLAN planf, planb;
648*3f1979aaSAndroid Build Coastguard Worker     FFTW_COMPLEX *in = (FFTW_COMPLEX*) FFTW_FUNC(malloc)(sizeof(FFTW_COMPLEX) * N);
649*3f1979aaSAndroid Build Coastguard Worker     FFTW_COMPLEX *out = (FFTW_COMPLEX*) FFTW_FUNC(malloc)(sizeof(FFTW_COMPLEX) * N);
650*3f1979aaSAndroid Build Coastguard Worker     memset(in, 0, sizeof(FFTW_COMPLEX) * N);
651*3f1979aaSAndroid Build Coastguard Worker     if (cplx) {
652*3f1979aaSAndroid Build Coastguard Worker       planf = FFTW_FUNC(plan_dft_1d)(N, in, out, FFTW_FORWARD, flags);
653*3f1979aaSAndroid Build Coastguard Worker       planb = FFTW_FUNC(plan_dft_1d)(N, in, out, FFTW_BACKWARD, flags);
654*3f1979aaSAndroid Build Coastguard Worker     } else {
655*3f1979aaSAndroid Build Coastguard Worker       planf = FFTW_FUNC(plan_dft_r2c_1d)(N, (pffft_scalar*)in, out, flags);
656*3f1979aaSAndroid Build Coastguard Worker       planb = FFTW_FUNC(plan_dft_c2r_1d)(N, in, (pffft_scalar*)out, flags);
657*3f1979aaSAndroid Build Coastguard Worker     }
658*3f1979aaSAndroid Build Coastguard Worker 
659*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
660*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
661*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
662*3f1979aaSAndroid Build Coastguard Worker     do {
663*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
664*3f1979aaSAndroid Build Coastguard Worker         assert( X[Nmax] == checkVal );
665*3f1979aaSAndroid Build Coastguard Worker         FFTW_FUNC(execute)(planf);
666*3f1979aaSAndroid Build Coastguard Worker         assert( X[Nmax] == checkVal );
667*3f1979aaSAndroid Build Coastguard Worker         FFTW_FUNC(execute)(planb);
668*3f1979aaSAndroid Build Coastguard Worker         assert( X[Nmax] == checkVal );
669*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
670*3f1979aaSAndroid Build Coastguard Worker       }
671*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
672*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
673*3f1979aaSAndroid Build Coastguard Worker 
674*3f1979aaSAndroid Build Coastguard Worker     FFTW_FUNC(destroy_plan)(planf);
675*3f1979aaSAndroid Build Coastguard Worker     FFTW_FUNC(destroy_plan)(planb);
676*3f1979aaSAndroid Build Coastguard Worker     FFTW_FUNC(free)(in); FFTW_FUNC(free)(out);
677*3f1979aaSAndroid Build Coastguard Worker 
678*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
679*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_FFTW_ESTIM] = max_iter;
680*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_FFTW_ESTIM] = flops/1e6/(t1 - t0 + 1e-16);
681*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_FFTW_ESTIM] = t1 - t0;
682*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_FFTW_ESTIM] = show_output((flags == FFTW_MEASURE ? algoName[ALGO_FFTW_AUTO] : algoName[ALGO_FFTW_ESTIM]), N, cplx, flops, t0, t1, max_iter, tableFile);
683*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_FFTW_ESTIM] = (t0 - te) * 1e3;
684*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_FFTW_ESTIM] = 1;
685*3f1979aaSAndroid Build Coastguard Worker   }
686*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? N*2 : N);
687*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
688*3f1979aaSAndroid Build Coastguard Worker   do {
689*3f1979aaSAndroid Build Coastguard Worker     /* int flags = (N <= (256*1024) ? FFTW_MEASURE : FFTW_ESTIMATE);  measure takes a lot of time on largest ffts */
690*3f1979aaSAndroid Build Coastguard Worker     /* int flags = FFTW_MEASURE; */
691*3f1979aaSAndroid Build Coastguard Worker #if ( defined(__arm__) || defined(__aarch64__) || defined(__arm64__) )
692*3f1979aaSAndroid Build Coastguard Worker     int limitFFTsize = 31;  /* takes over a second on Raspberry Pi 3 B+ -- and much much more on higher ffts sizes! */
693*3f1979aaSAndroid Build Coastguard Worker #else
694*3f1979aaSAndroid Build Coastguard Worker     int limitFFTsize = 2400;  /* take over a second on i7 for fft size 2400 */
695*3f1979aaSAndroid Build Coastguard Worker #endif
696*3f1979aaSAndroid Build Coastguard Worker     int flags = (N < limitFFTsize ? FFTW_MEASURE : (withFFTWfullMeas ? FFTW_MEASURE : FFTW_ESTIMATE));
697*3f1979aaSAndroid Build Coastguard Worker 
698*3f1979aaSAndroid Build Coastguard Worker     if (flags == FFTW_ESTIMATE) {
699*3f1979aaSAndroid Build Coastguard Worker       show_output((flags == FFTW_MEASURE ? algoName[ALGO_FFTW_AUTO] : algoName[ALGO_FFTW_ESTIM]), N, cplx, -1, -1, -1, -1, tableFile);
700*3f1979aaSAndroid Build Coastguard Worker       /* copy values from estimation */
701*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_ITER][ALGO_FFTW_AUTO] = tmeas[TYPE_ITER][ALGO_FFTW_ESTIM];
702*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_TOT][ALGO_FFTW_AUTO] = tmeas[TYPE_DUR_TOT][ALGO_FFTW_ESTIM];
703*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_NS][ALGO_FFTW_AUTO] = tmeas[TYPE_DUR_NS][ALGO_FFTW_ESTIM];
704*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_PREP][ALGO_FFTW_AUTO] = tmeas[TYPE_PREP][ALGO_FFTW_ESTIM];
705*3f1979aaSAndroid Build Coastguard Worker     } else {
706*3f1979aaSAndroid Build Coastguard Worker       te = uclock_sec();
707*3f1979aaSAndroid Build Coastguard Worker       FFTW_PLAN planf, planb;
708*3f1979aaSAndroid Build Coastguard Worker       FFTW_COMPLEX *in = (FFTW_COMPLEX*) FFTW_FUNC(malloc)(sizeof(FFTW_COMPLEX) * N);
709*3f1979aaSAndroid Build Coastguard Worker       FFTW_COMPLEX *out = (FFTW_COMPLEX*) FFTW_FUNC(malloc)(sizeof(FFTW_COMPLEX) * N);
710*3f1979aaSAndroid Build Coastguard Worker       memset(in, 0, sizeof(FFTW_COMPLEX) * N);
711*3f1979aaSAndroid Build Coastguard Worker       if (cplx) {
712*3f1979aaSAndroid Build Coastguard Worker         planf = FFTW_FUNC(plan_dft_1d)(N, in, out, FFTW_FORWARD, flags);
713*3f1979aaSAndroid Build Coastguard Worker         planb = FFTW_FUNC(plan_dft_1d)(N, in, out, FFTW_BACKWARD, flags);
714*3f1979aaSAndroid Build Coastguard Worker       } else {
715*3f1979aaSAndroid Build Coastguard Worker         planf = FFTW_FUNC(plan_dft_r2c_1d)(N, (pffft_scalar*)in, out, flags);
716*3f1979aaSAndroid Build Coastguard Worker         planb = FFTW_FUNC(plan_dft_c2r_1d)(N, in, (pffft_scalar*)out, flags);
717*3f1979aaSAndroid Build Coastguard Worker       }
718*3f1979aaSAndroid Build Coastguard Worker 
719*3f1979aaSAndroid Build Coastguard Worker       t0 = uclock_sec();
720*3f1979aaSAndroid Build Coastguard Worker       tstop = t0 + max_test_duration;
721*3f1979aaSAndroid Build Coastguard Worker       max_iter = 0;
722*3f1979aaSAndroid Build Coastguard Worker       do {
723*3f1979aaSAndroid Build Coastguard Worker         for ( k = 0; k < step_iter; ++k ) {
724*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
725*3f1979aaSAndroid Build Coastguard Worker           FFTW_FUNC(execute)(planf);
726*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
727*3f1979aaSAndroid Build Coastguard Worker           FFTW_FUNC(execute)(planb);
728*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
729*3f1979aaSAndroid Build Coastguard Worker           ++max_iter;
730*3f1979aaSAndroid Build Coastguard Worker         }
731*3f1979aaSAndroid Build Coastguard Worker         t1 = uclock_sec();
732*3f1979aaSAndroid Build Coastguard Worker       } while ( t1 < tstop );
733*3f1979aaSAndroid Build Coastguard Worker 
734*3f1979aaSAndroid Build Coastguard Worker       FFTW_FUNC(destroy_plan)(planf);
735*3f1979aaSAndroid Build Coastguard Worker       FFTW_FUNC(destroy_plan)(planb);
736*3f1979aaSAndroid Build Coastguard Worker       FFTW_FUNC(free)(in); FFTW_FUNC(free)(out);
737*3f1979aaSAndroid Build Coastguard Worker 
738*3f1979aaSAndroid Build Coastguard Worker       flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
739*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_ITER][ALGO_FFTW_AUTO] = max_iter;
740*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_MFLOPS][ALGO_FFTW_AUTO] = flops/1e6/(t1 - t0 + 1e-16);
741*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_TOT][ALGO_FFTW_AUTO] = t1 - t0;
742*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_NS][ALGO_FFTW_AUTO] = show_output((flags == FFTW_MEASURE ? algoName[ALGO_FFTW_AUTO] : algoName[ALGO_FFTW_ESTIM]), N, cplx, flops, t0, t1, max_iter, tableFile);
743*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_PREP][ALGO_FFTW_AUTO] = (t0 - te) * 1e3;
744*3f1979aaSAndroid Build Coastguard Worker       haveAlgo[ALGO_FFTW_AUTO] = 1;
745*3f1979aaSAndroid Build Coastguard Worker     }
746*3f1979aaSAndroid Build Coastguard Worker   } while (0);
747*3f1979aaSAndroid Build Coastguard Worker #else
748*3f1979aaSAndroid Build Coastguard Worker   (void)withFFTWfullMeas;
749*3f1979aaSAndroid Build Coastguard Worker #endif
750*3f1979aaSAndroid Build Coastguard Worker 
751*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_GREEN_FFTS) && defined(PFFFT_ENABLE_FLOAT)
752*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? nextPow2N*2 : nextPow2N);
753*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
754*3f1979aaSAndroid Build Coastguard Worker   if ( 1 || PFFFT_FUNC(is_power_of_two)(N) )
755*3f1979aaSAndroid Build Coastguard Worker   {
756*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
757*3f1979aaSAndroid Build Coastguard Worker     fftInit(log2NextN);
758*3f1979aaSAndroid Build Coastguard Worker 
759*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
760*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
761*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
762*3f1979aaSAndroid Build Coastguard Worker     do {
763*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
764*3f1979aaSAndroid Build Coastguard Worker         if (cplx) {
765*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
766*3f1979aaSAndroid Build Coastguard Worker           ffts(X, log2NextN, 1);
767*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
768*3f1979aaSAndroid Build Coastguard Worker           iffts(X, log2NextN, 1);
769*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
770*3f1979aaSAndroid Build Coastguard Worker         } else {
771*3f1979aaSAndroid Build Coastguard Worker           rffts(X, log2NextN, 1);
772*3f1979aaSAndroid Build Coastguard Worker           riffts(X, log2NextN, 1);
773*3f1979aaSAndroid Build Coastguard Worker         }
774*3f1979aaSAndroid Build Coastguard Worker 
775*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
776*3f1979aaSAndroid Build Coastguard Worker       }
777*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
778*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
779*3f1979aaSAndroid Build Coastguard Worker 
780*3f1979aaSAndroid Build Coastguard Worker     fftFree();
781*3f1979aaSAndroid Build Coastguard Worker 
782*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
783*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_GREEN] = max_iter;
784*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_GREEN] = flops/1e6/(t1 - t0 + 1e-16);
785*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_GREEN] = t1 - t0;
786*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_GREEN] = show_output("Green", N, cplx, flops, t0, t1, max_iter, tableFile);
787*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_GREEN] = (t0 - te) * 1e3;
788*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_GREEN] = 1;
789*3f1979aaSAndroid Build Coastguard Worker   } else {
790*3f1979aaSAndroid Build Coastguard Worker     show_output("Green", N, cplx, -1, -1, -1, -1, tableFile);
791*3f1979aaSAndroid Build Coastguard Worker   }
792*3f1979aaSAndroid Build Coastguard Worker #endif
793*3f1979aaSAndroid Build Coastguard Worker 
794*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_KISS_FFT) && defined(PFFFT_ENABLE_FLOAT)
795*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? nextPow2N*2 : nextPow2N);
796*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
797*3f1979aaSAndroid Build Coastguard Worker   if ( 1 || PFFFT_FUNC(is_power_of_two)(N) )
798*3f1979aaSAndroid Build Coastguard Worker   {
799*3f1979aaSAndroid Build Coastguard Worker     kiss_fft_cfg stf;
800*3f1979aaSAndroid Build Coastguard Worker     kiss_fft_cfg sti;
801*3f1979aaSAndroid Build Coastguard Worker     kiss_fftr_cfg stfr;
802*3f1979aaSAndroid Build Coastguard Worker     kiss_fftr_cfg stir;
803*3f1979aaSAndroid Build Coastguard Worker 
804*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
805*3f1979aaSAndroid Build Coastguard Worker     if (cplx) {
806*3f1979aaSAndroid Build Coastguard Worker       stf = kiss_fft_alloc(nextPow2N, 0, 0, 0);
807*3f1979aaSAndroid Build Coastguard Worker       sti = kiss_fft_alloc(nextPow2N, 1, 0, 0);
808*3f1979aaSAndroid Build Coastguard Worker     } else {
809*3f1979aaSAndroid Build Coastguard Worker       stfr = kiss_fftr_alloc(nextPow2N, 0, 0, 0);
810*3f1979aaSAndroid Build Coastguard Worker       stir = kiss_fftr_alloc(nextPow2N, 1, 0, 0);
811*3f1979aaSAndroid Build Coastguard Worker     }
812*3f1979aaSAndroid Build Coastguard Worker 
813*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
814*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
815*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
816*3f1979aaSAndroid Build Coastguard Worker     do {
817*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
818*3f1979aaSAndroid Build Coastguard Worker         if (cplx) {
819*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
820*3f1979aaSAndroid Build Coastguard Worker           kiss_fft(stf, (const kiss_fft_cpx *)X, (kiss_fft_cpx *)Y);
821*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
822*3f1979aaSAndroid Build Coastguard Worker           kiss_fft(sti, (const kiss_fft_cpx *)Y, (kiss_fft_cpx *)X);
823*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
824*3f1979aaSAndroid Build Coastguard Worker         } else {
825*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
826*3f1979aaSAndroid Build Coastguard Worker           kiss_fftr(stfr, X, (kiss_fft_cpx *)Y);
827*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
828*3f1979aaSAndroid Build Coastguard Worker           kiss_fftri(stir, (const kiss_fft_cpx *)Y, X);
829*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
830*3f1979aaSAndroid Build Coastguard Worker         }
831*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
832*3f1979aaSAndroid Build Coastguard Worker       }
833*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
834*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
835*3f1979aaSAndroid Build Coastguard Worker 
836*3f1979aaSAndroid Build Coastguard Worker     kiss_fft_cleanup();
837*3f1979aaSAndroid Build Coastguard Worker 
838*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
839*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_KISS] = max_iter;
840*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_KISS] = flops/1e6/(t1 - t0 + 1e-16);
841*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_KISS] = t1 - t0;
842*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_KISS] = show_output("Kiss", N, cplx, flops, t0, t1, max_iter, tableFile);
843*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_KISS] = (t0 - te) * 1e3;
844*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_KISS] = 1;
845*3f1979aaSAndroid Build Coastguard Worker   } else {
846*3f1979aaSAndroid Build Coastguard Worker     show_output("Kiss", N, cplx, -1, -1, -1, -1, tableFile);
847*3f1979aaSAndroid Build Coastguard Worker   }
848*3f1979aaSAndroid Build Coastguard Worker #endif
849*3f1979aaSAndroid Build Coastguard Worker 
850*3f1979aaSAndroid Build Coastguard Worker #if defined(HAVE_POCKET_FFT)
851*3f1979aaSAndroid Build Coastguard Worker 
852*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? nextPow2N*2 : nextPow2N);
853*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
854*3f1979aaSAndroid Build Coastguard Worker   if ( 1 || PFFFT_FUNC(is_power_of_two)(N) )
855*3f1979aaSAndroid Build Coastguard Worker   {
856*3f1979aaSAndroid Build Coastguard Worker     POCKFFTR_PRE(_plan) planr;
857*3f1979aaSAndroid Build Coastguard Worker     POCKFFTC_PRE(_plan) planc;
858*3f1979aaSAndroid Build Coastguard Worker 
859*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
860*3f1979aaSAndroid Build Coastguard Worker     if (cplx) {
861*3f1979aaSAndroid Build Coastguard Worker       planc = POCKFFTC_MID(make_,_plan)(nextPow2N);
862*3f1979aaSAndroid Build Coastguard Worker     } else {
863*3f1979aaSAndroid Build Coastguard Worker       planr = POCKFFTR_MID(make_,_plan)(nextPow2N);
864*3f1979aaSAndroid Build Coastguard Worker     }
865*3f1979aaSAndroid Build Coastguard Worker 
866*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
867*3f1979aaSAndroid Build Coastguard Worker     tstop = t0 + max_test_duration;
868*3f1979aaSAndroid Build Coastguard Worker     max_iter = 0;
869*3f1979aaSAndroid Build Coastguard Worker     do {
870*3f1979aaSAndroid Build Coastguard Worker       for ( k = 0; k < step_iter; ++k ) {
871*3f1979aaSAndroid Build Coastguard Worker         if (cplx) {
872*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
873*3f1979aaSAndroid Build Coastguard Worker           memcpy(Y, X, 2*nextPow2N * sizeof(pffft_scalar) );
874*3f1979aaSAndroid Build Coastguard Worker           POCKFFTC_PRE(_forward)(planc, Y, 1.);
875*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
876*3f1979aaSAndroid Build Coastguard Worker           memcpy(X, Y, 2*nextPow2N * sizeof(pffft_scalar) );
877*3f1979aaSAndroid Build Coastguard Worker           POCKFFTC_PRE(_backward)(planc, X, 1./nextPow2N);
878*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
879*3f1979aaSAndroid Build Coastguard Worker         } else {
880*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
881*3f1979aaSAndroid Build Coastguard Worker           memcpy(Y, X, nextPow2N * sizeof(pffft_scalar) );
882*3f1979aaSAndroid Build Coastguard Worker           POCKFFTR_PRE(_forward)(planr, Y, 1.);
883*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
884*3f1979aaSAndroid Build Coastguard Worker           memcpy(X, Y, nextPow2N * sizeof(pffft_scalar) );
885*3f1979aaSAndroid Build Coastguard Worker           POCKFFTR_PRE(_backward)(planr, X, 1./nextPow2N);
886*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
887*3f1979aaSAndroid Build Coastguard Worker         }
888*3f1979aaSAndroid Build Coastguard Worker         ++max_iter;
889*3f1979aaSAndroid Build Coastguard Worker       }
890*3f1979aaSAndroid Build Coastguard Worker       t1 = uclock_sec();
891*3f1979aaSAndroid Build Coastguard Worker     } while ( t1 < tstop );
892*3f1979aaSAndroid Build Coastguard Worker 
893*3f1979aaSAndroid Build Coastguard Worker     if (cplx) {
894*3f1979aaSAndroid Build Coastguard Worker       POCKFFTC_MID(destroy_,_plan)(planc);
895*3f1979aaSAndroid Build Coastguard Worker     } else {
896*3f1979aaSAndroid Build Coastguard Worker       POCKFFTR_MID(destroy_,_plan)(planr);
897*3f1979aaSAndroid Build Coastguard Worker     }
898*3f1979aaSAndroid Build Coastguard Worker 
899*3f1979aaSAndroid Build Coastguard Worker     flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
900*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_ITER][ALGO_POCKET] = max_iter;
901*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_MFLOPS][ALGO_POCKET] = flops/1e6/(t1 - t0 + 1e-16);
902*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_TOT][ALGO_POCKET] = t1 - t0;
903*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_DUR_NS][ALGO_POCKET] = show_output("Pocket", N, cplx, flops, t0, t1, max_iter, tableFile);
904*3f1979aaSAndroid Build Coastguard Worker     tmeas[TYPE_PREP][ALGO_POCKET] = (t0 - te) * 1e3;
905*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[ALGO_POCKET] = 1;
906*3f1979aaSAndroid Build Coastguard Worker   } else {
907*3f1979aaSAndroid Build Coastguard Worker     show_output("Pocket", N, cplx, -1, -1, -1, -1, tableFile);
908*3f1979aaSAndroid Build Coastguard Worker   }
909*3f1979aaSAndroid Build Coastguard Worker #endif
910*3f1979aaSAndroid Build Coastguard Worker 
911*3f1979aaSAndroid Build Coastguard Worker 
912*3f1979aaSAndroid Build Coastguard Worker   /* PFFFT-U (unordered) benchmark */
913*3f1979aaSAndroid Build Coastguard Worker   Nmax = (cplx ? pffftPow2N*2 : pffftPow2N);
914*3f1979aaSAndroid Build Coastguard Worker   X[Nmax] = checkVal;
915*3f1979aaSAndroid Build Coastguard Worker   if ( pffftPow2N >= PFFFT_FUNC(min_fft_size)(cplx ? PFFFT_COMPLEX : PFFFT_REAL) )
916*3f1979aaSAndroid Build Coastguard Worker   {
917*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
918*3f1979aaSAndroid Build Coastguard Worker     PFFFT_SETUP *s = PFFFT_FUNC(new_setup)(pffftPow2N, cplx ? PFFFT_COMPLEX : PFFFT_REAL);
919*3f1979aaSAndroid Build Coastguard Worker     if (s) {
920*3f1979aaSAndroid Build Coastguard Worker       t0 = uclock_sec();
921*3f1979aaSAndroid Build Coastguard Worker       tstop = t0 + max_test_duration;
922*3f1979aaSAndroid Build Coastguard Worker       max_iter = 0;
923*3f1979aaSAndroid Build Coastguard Worker       do {
924*3f1979aaSAndroid Build Coastguard Worker         for ( k = 0; k < step_iter; ++k ) {
925*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
926*3f1979aaSAndroid Build Coastguard Worker           PFFFT_FUNC(transform)(s, X, Z, Y, PFFFT_FORWARD);
927*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
928*3f1979aaSAndroid Build Coastguard Worker           PFFFT_FUNC(transform)(s, X, Z, Y, PFFFT_BACKWARD);
929*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
930*3f1979aaSAndroid Build Coastguard Worker           ++max_iter;
931*3f1979aaSAndroid Build Coastguard Worker         }
932*3f1979aaSAndroid Build Coastguard Worker         t1 = uclock_sec();
933*3f1979aaSAndroid Build Coastguard Worker       } while ( t1 < tstop );
934*3f1979aaSAndroid Build Coastguard Worker 
935*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(destroy_setup)(s);
936*3f1979aaSAndroid Build Coastguard Worker 
937*3f1979aaSAndroid Build Coastguard Worker       flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
938*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_ITER][ALGO_PFFFT_U] = max_iter;
939*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_MFLOPS][ALGO_PFFFT_U] = flops/1e6/(t1 - t0 + 1e-16);
940*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_TOT][ALGO_PFFFT_U] = t1 - t0;
941*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_NS][ALGO_PFFFT_U] = show_output("PFFFT-U", N, cplx, flops, t0, t1, max_iter, tableFile);
942*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_PREP][ALGO_PFFFT_U] = (t0 - te) * 1e3;
943*3f1979aaSAndroid Build Coastguard Worker       haveAlgo[ALGO_PFFFT_U] = 1;
944*3f1979aaSAndroid Build Coastguard Worker     }
945*3f1979aaSAndroid Build Coastguard Worker   } else {
946*3f1979aaSAndroid Build Coastguard Worker     show_output("PFFFT-U", N, cplx, -1, -1, -1, -1, tableFile);
947*3f1979aaSAndroid Build Coastguard Worker   }
948*3f1979aaSAndroid Build Coastguard Worker 
949*3f1979aaSAndroid Build Coastguard Worker 
950*3f1979aaSAndroid Build Coastguard Worker   if ( pffftPow2N >= PFFFT_FUNC(min_fft_size)(cplx ? PFFFT_COMPLEX : PFFFT_REAL) )
951*3f1979aaSAndroid Build Coastguard Worker   {
952*3f1979aaSAndroid Build Coastguard Worker     te = uclock_sec();
953*3f1979aaSAndroid Build Coastguard Worker     PFFFT_SETUP *s = PFFFT_FUNC(new_setup)(pffftPow2N, cplx ? PFFFT_COMPLEX : PFFFT_REAL);
954*3f1979aaSAndroid Build Coastguard Worker     if (s) {
955*3f1979aaSAndroid Build Coastguard Worker       t0 = uclock_sec();
956*3f1979aaSAndroid Build Coastguard Worker       tstop = t0 + max_test_duration;
957*3f1979aaSAndroid Build Coastguard Worker       max_iter = 0;
958*3f1979aaSAndroid Build Coastguard Worker       do {
959*3f1979aaSAndroid Build Coastguard Worker         for ( k = 0; k < step_iter; ++k ) {
960*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
961*3f1979aaSAndroid Build Coastguard Worker           PFFFT_FUNC(transform_ordered)(s, X, Z, Y, PFFFT_FORWARD);
962*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
963*3f1979aaSAndroid Build Coastguard Worker           PFFFT_FUNC(transform_ordered)(s, X, Z, Y, PFFFT_BACKWARD);
964*3f1979aaSAndroid Build Coastguard Worker           assert( X[Nmax] == checkVal );
965*3f1979aaSAndroid Build Coastguard Worker           ++max_iter;
966*3f1979aaSAndroid Build Coastguard Worker         }
967*3f1979aaSAndroid Build Coastguard Worker         t1 = uclock_sec();
968*3f1979aaSAndroid Build Coastguard Worker       } while ( t1 < tstop );
969*3f1979aaSAndroid Build Coastguard Worker 
970*3f1979aaSAndroid Build Coastguard Worker       PFFFT_FUNC(destroy_setup)(s);
971*3f1979aaSAndroid Build Coastguard Worker 
972*3f1979aaSAndroid Build Coastguard Worker       flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); /* see http://www.fftw.org/speed/method.html */
973*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_ITER][ALGO_PFFFT_O] = max_iter;
974*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_MFLOPS][ALGO_PFFFT_O] = flops/1e6/(t1 - t0 + 1e-16);
975*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_TOT][ALGO_PFFFT_O] = t1 - t0;
976*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_DUR_NS][ALGO_PFFFT_O] = show_output("PFFFT", N, cplx, flops, t0, t1, max_iter, tableFile);
977*3f1979aaSAndroid Build Coastguard Worker       tmeas[TYPE_PREP][ALGO_PFFFT_O] = (t0 - te) * 1e3;
978*3f1979aaSAndroid Build Coastguard Worker       haveAlgo[ALGO_PFFFT_O] = 1;
979*3f1979aaSAndroid Build Coastguard Worker     }
980*3f1979aaSAndroid Build Coastguard Worker   } else {
981*3f1979aaSAndroid Build Coastguard Worker     show_output("PFFFT", N, cplx, -1, -1, -1, -1, tableFile);
982*3f1979aaSAndroid Build Coastguard Worker   }
983*3f1979aaSAndroid Build Coastguard Worker 
984*3f1979aaSAndroid Build Coastguard Worker   if (!array_output_format)
985*3f1979aaSAndroid Build Coastguard Worker   {
986*3f1979aaSAndroid Build Coastguard Worker     printf("prepare/ms:     ");
987*3f1979aaSAndroid Build Coastguard Worker     for ( iter = 0; iter < NUM_FFT_ALGOS; ++iter )
988*3f1979aaSAndroid Build Coastguard Worker     {
989*3f1979aaSAndroid Build Coastguard Worker       if ( haveAlgo[iter] && tmeas[TYPE_DUR_NS][iter] > 0.0 ) {
990*3f1979aaSAndroid Build Coastguard Worker         printf("%s %.3f    ", algoName[iter], tmeas[TYPE_PREP][iter] );
991*3f1979aaSAndroid Build Coastguard Worker       }
992*3f1979aaSAndroid Build Coastguard Worker     }
993*3f1979aaSAndroid Build Coastguard Worker     printf("\n");
994*3f1979aaSAndroid Build Coastguard Worker   }
995*3f1979aaSAndroid Build Coastguard Worker   Tfastest = 0.0;
996*3f1979aaSAndroid Build Coastguard Worker   for ( iter = 0; iter < NUM_FFT_ALGOS; ++iter )
997*3f1979aaSAndroid Build Coastguard Worker   {
998*3f1979aaSAndroid Build Coastguard Worker     if ( Tfastest == 0.0 || ( tmeas[TYPE_DUR_NS][iter] != 0.0 && tmeas[TYPE_DUR_NS][iter] < Tfastest ) )
999*3f1979aaSAndroid Build Coastguard Worker       Tfastest = tmeas[TYPE_DUR_NS][iter];
1000*3f1979aaSAndroid Build Coastguard Worker   }
1001*3f1979aaSAndroid Build Coastguard Worker   if ( Tfastest > 0.0 )
1002*3f1979aaSAndroid Build Coastguard Worker   {
1003*3f1979aaSAndroid Build Coastguard Worker     if (!array_output_format)
1004*3f1979aaSAndroid Build Coastguard Worker       printf("relative fast:  ");
1005*3f1979aaSAndroid Build Coastguard Worker     for ( iter = 0; iter < NUM_FFT_ALGOS; ++iter )
1006*3f1979aaSAndroid Build Coastguard Worker     {
1007*3f1979aaSAndroid Build Coastguard Worker       if ( haveAlgo[iter] && tmeas[TYPE_DUR_NS][iter] > 0.0 ) {
1008*3f1979aaSAndroid Build Coastguard Worker         tmeas[TYPE_DUR_FASTEST][iter] = tmeas[TYPE_DUR_NS][iter] / Tfastest;
1009*3f1979aaSAndroid Build Coastguard Worker         if (!array_output_format)
1010*3f1979aaSAndroid Build Coastguard Worker           printf("%s %.3f    ", algoName[iter], tmeas[TYPE_DUR_FASTEST][iter] );
1011*3f1979aaSAndroid Build Coastguard Worker       }
1012*3f1979aaSAndroid Build Coastguard Worker     }
1013*3f1979aaSAndroid Build Coastguard Worker     if (!array_output_format)
1014*3f1979aaSAndroid Build Coastguard Worker       printf("\n");
1015*3f1979aaSAndroid Build Coastguard Worker   }
1016*3f1979aaSAndroid Build Coastguard Worker 
1017*3f1979aaSAndroid Build Coastguard Worker   {
1018*3f1979aaSAndroid Build Coastguard Worker     if (!array_output_format)
1019*3f1979aaSAndroid Build Coastguard Worker       printf("relative pffft: ");
1020*3f1979aaSAndroid Build Coastguard Worker     for ( iter = 0; iter < NUM_FFT_ALGOS; ++iter )
1021*3f1979aaSAndroid Build Coastguard Worker     {
1022*3f1979aaSAndroid Build Coastguard Worker       if ( haveAlgo[iter] && tmeas[TYPE_DUR_NS][iter] > 0.0 ) {
1023*3f1979aaSAndroid Build Coastguard Worker         tmeas[TYPE_REL_PFFFT][iter] = tmeas[TYPE_DUR_NS][iter] / tmeas[TYPE_DUR_NS][ALGO_PFFFT_O];
1024*3f1979aaSAndroid Build Coastguard Worker         if (!array_output_format)
1025*3f1979aaSAndroid Build Coastguard Worker           printf("%s %.3f    ", algoName[iter], tmeas[TYPE_REL_PFFFT][iter] );
1026*3f1979aaSAndroid Build Coastguard Worker       }
1027*3f1979aaSAndroid Build Coastguard Worker     }
1028*3f1979aaSAndroid Build Coastguard Worker     if (!array_output_format)
1029*3f1979aaSAndroid Build Coastguard Worker       printf("\n");
1030*3f1979aaSAndroid Build Coastguard Worker   }
1031*3f1979aaSAndroid Build Coastguard Worker 
1032*3f1979aaSAndroid Build Coastguard Worker   if (!array_output_format) {
1033*3f1979aaSAndroid Build Coastguard Worker     printf("--\n");
1034*3f1979aaSAndroid Build Coastguard Worker   }
1035*3f1979aaSAndroid Build Coastguard Worker 
1036*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(X);
1037*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(Y);
1038*3f1979aaSAndroid Build Coastguard Worker   PFFFT_FUNC(aligned_free)(Z);
1039*3f1979aaSAndroid Build Coastguard Worker }
1040*3f1979aaSAndroid Build Coastguard Worker 
1041*3f1979aaSAndroid Build Coastguard Worker 
1042*3f1979aaSAndroid Build Coastguard Worker /* small functions inside pffft.c that will detect (compiler) bugs with respect to simd instructions */
1043*3f1979aaSAndroid Build Coastguard Worker void validate_pffft_simd();
1044*3f1979aaSAndroid Build Coastguard Worker int  validate_pffft_simd_ex(FILE * DbgOut);
1045*3f1979aaSAndroid Build Coastguard Worker void validate_pffftd_simd();
1046*3f1979aaSAndroid Build Coastguard Worker int  validate_pffftd_simd_ex(FILE * DbgOut);
1047*3f1979aaSAndroid Build Coastguard Worker 
1048*3f1979aaSAndroid Build Coastguard Worker 
1049*3f1979aaSAndroid Build Coastguard Worker 
1050*3f1979aaSAndroid Build Coastguard Worker int main(int argc, char **argv) {
1051*3f1979aaSAndroid Build Coastguard Worker   /* unfortunately, the fft size must be a multiple of 16 for complex FFTs
1052*3f1979aaSAndroid Build Coastguard Worker      and 32 for real FFTs -- a lot of stuff would need to be rewritten to
1053*3f1979aaSAndroid Build Coastguard Worker      handle other cases (or maybe just switch to a scalar fft, I don't know..) */
1054*3f1979aaSAndroid Build Coastguard Worker 
1055*3f1979aaSAndroid Build Coastguard Worker #if 0  /* include powers of 2 ? */
1056*3f1979aaSAndroid Build Coastguard Worker #define NUMNONPOW2LENS  23
1057*3f1979aaSAndroid Build Coastguard Worker   int NnonPow2[NUMNONPOW2LENS] = {
1058*3f1979aaSAndroid Build Coastguard Worker     64, 96, 128, 160, 192,   256, 384, 5*96, 512, 5*128,
1059*3f1979aaSAndroid Build Coastguard Worker     3*256, 800, 1024, 2048, 2400,   4096, 8192, 9*1024, 16384, 32768,
1060*3f1979aaSAndroid Build Coastguard Worker     256*1024, 1024*1024, -1 };
1061*3f1979aaSAndroid Build Coastguard Worker #else
1062*3f1979aaSAndroid Build Coastguard Worker #define NUMNONPOW2LENS  11
1063*3f1979aaSAndroid Build Coastguard Worker   int NnonPow2[NUMNONPOW2LENS] = {
1064*3f1979aaSAndroid Build Coastguard Worker     96, 160, 192, 384, 5*96,   5*128,3*256, 800, 2400, 9*1024,
1065*3f1979aaSAndroid Build Coastguard Worker     -1 };
1066*3f1979aaSAndroid Build Coastguard Worker #endif
1067*3f1979aaSAndroid Build Coastguard Worker 
1068*3f1979aaSAndroid Build Coastguard Worker #define NUMPOW2FFTLENS  22
1069*3f1979aaSAndroid Build Coastguard Worker #define MAXNUMFFTLENS MAX( NUMPOW2FFTLENS, NUMNONPOW2LENS )
1070*3f1979aaSAndroid Build Coastguard Worker   int Npow2[NUMPOW2FFTLENS];  /* exp = 1 .. 21, -1 */
1071*3f1979aaSAndroid Build Coastguard Worker   const int *Nvalues = NULL;
1072*3f1979aaSAndroid Build Coastguard Worker   double tmeas[2][MAXNUMFFTLENS][NUM_TYPES][NUM_FFT_ALGOS];
1073*3f1979aaSAndroid Build Coastguard Worker   double iterCalReal, iterCalCplx;
1074*3f1979aaSAndroid Build Coastguard Worker 
1075*3f1979aaSAndroid Build Coastguard Worker   int benchReal=1, benchCplx=1, withFFTWfullMeas=0, outputTable2File=1, usePow2=1;
1076*3f1979aaSAndroid Build Coastguard Worker   int realCplxIdx, typeIdx;
1077*3f1979aaSAndroid Build Coastguard Worker   int i, k;
1078*3f1979aaSAndroid Build Coastguard Worker   FILE *tableFile = NULL;
1079*3f1979aaSAndroid Build Coastguard Worker 
1080*3f1979aaSAndroid Build Coastguard Worker   int haveAlgo[NUM_FFT_ALGOS];
1081*3f1979aaSAndroid Build Coastguard Worker   char acCsvFilename[64];
1082*3f1979aaSAndroid Build Coastguard Worker 
1083*3f1979aaSAndroid Build Coastguard Worker   for ( k = 1; k <= NUMPOW2FFTLENS; ++k )
1084*3f1979aaSAndroid Build Coastguard Worker     Npow2[k-1] = (k == NUMPOW2FFTLENS) ? -1 : (1 << k);
1085*3f1979aaSAndroid Build Coastguard Worker   Nvalues = Npow2;  /* set default .. for comparisons .. */
1086*3f1979aaSAndroid Build Coastguard Worker 
1087*3f1979aaSAndroid Build Coastguard Worker   for ( i = 0; i < NUM_FFT_ALGOS; ++i )
1088*3f1979aaSAndroid Build Coastguard Worker     haveAlgo[i] = 0;
1089*3f1979aaSAndroid Build Coastguard Worker 
1090*3f1979aaSAndroid Build Coastguard Worker   printf("pffft architecture:    '%s'\n", PFFFT_FUNC(simd_arch)());
1091*3f1979aaSAndroid Build Coastguard Worker   printf("pffft SIMD size:       %d\n", PFFFT_FUNC(simd_size)());
1092*3f1979aaSAndroid Build Coastguard Worker   printf("pffft min real fft:    %d\n", PFFFT_FUNC(min_fft_size)(PFFFT_REAL));
1093*3f1979aaSAndroid Build Coastguard Worker   printf("pffft min complex fft: %d\n", PFFFT_FUNC(min_fft_size)(PFFFT_COMPLEX));
1094*3f1979aaSAndroid Build Coastguard Worker   printf("\n");
1095*3f1979aaSAndroid Build Coastguard Worker 
1096*3f1979aaSAndroid Build Coastguard Worker   for ( i = 1; i < argc; ++i ) {
1097*3f1979aaSAndroid Build Coastguard Worker     if (!strcmp(argv[i], "--array-format") || !strcmp(argv[i], "--table")) {
1098*3f1979aaSAndroid Build Coastguard Worker       array_output_format = 1;
1099*3f1979aaSAndroid Build Coastguard Worker     }
1100*3f1979aaSAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "--no-tab")) {
1101*3f1979aaSAndroid Build Coastguard Worker       array_output_format = 0;
1102*3f1979aaSAndroid Build Coastguard Worker     }
1103*3f1979aaSAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "--real")) {
1104*3f1979aaSAndroid Build Coastguard Worker       benchCplx = 0;
1105*3f1979aaSAndroid Build Coastguard Worker     }
1106*3f1979aaSAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "--cplx")) {
1107*3f1979aaSAndroid Build Coastguard Worker       benchReal = 0;
1108*3f1979aaSAndroid Build Coastguard Worker     }
1109*3f1979aaSAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "--fftw-full-measure")) {
1110*3f1979aaSAndroid Build Coastguard Worker       withFFTWfullMeas = 1;
1111*3f1979aaSAndroid Build Coastguard Worker     }
1112*3f1979aaSAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "--non-pow2")) {
1113*3f1979aaSAndroid Build Coastguard Worker       Nvalues = NnonPow2;
1114*3f1979aaSAndroid Build Coastguard Worker       usePow2 = 0;
1115*3f1979aaSAndroid Build Coastguard Worker     }
1116*3f1979aaSAndroid Build Coastguard Worker     else /* if (!strcmp(argv[i], "--help")) */ {
1117*3f1979aaSAndroid Build Coastguard Worker       printf("usage: %s [--array-format|--table] [--no-tab] [--real|--cplx] [--fftw-full-measure] [--non-pow2]\n", argv[0]);
1118*3f1979aaSAndroid Build Coastguard Worker       exit(0);
1119*3f1979aaSAndroid Build Coastguard Worker     }
1120*3f1979aaSAndroid Build Coastguard Worker   }
1121*3f1979aaSAndroid Build Coastguard Worker 
1122*3f1979aaSAndroid Build Coastguard Worker #ifdef HAVE_FFTW
1123*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_DOUBLE
1124*3f1979aaSAndroid Build Coastguard Worker   algoName[ALGO_FFTW_ESTIM] = "FFTW D(estim)";
1125*3f1979aaSAndroid Build Coastguard Worker   algoName[ALGO_FFTW_AUTO]  = "FFTW D(auto) ";
1126*3f1979aaSAndroid Build Coastguard Worker #endif
1127*3f1979aaSAndroid Build Coastguard Worker 
1128*3f1979aaSAndroid Build Coastguard Worker   if (withFFTWfullMeas)
1129*3f1979aaSAndroid Build Coastguard Worker   {
1130*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_ENABLE_FLOAT
1131*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_FFTW_AUTO] = "FFTWF(meas)"; /* "FFTW (auto)" */
1132*3f1979aaSAndroid Build Coastguard Worker #else
1133*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_FFTW_AUTO] = "FFTWD(meas)"; /* "FFTW (auto)" */
1134*3f1979aaSAndroid Build Coastguard Worker #endif
1135*3f1979aaSAndroid Build Coastguard Worker     algoTableHeader[NUM_FFT_ALGOS][0] = "|real FFTWmeas "; /* "|real FFTWauto " */
1136*3f1979aaSAndroid Build Coastguard Worker     algoTableHeader[NUM_FFT_ALGOS][0] = "|cplx FFTWmeas "; /* "|cplx FFTWauto " */
1137*3f1979aaSAndroid Build Coastguard Worker   }
1138*3f1979aaSAndroid Build Coastguard Worker #endif
1139*3f1979aaSAndroid Build Coastguard Worker 
1140*3f1979aaSAndroid Build Coastguard Worker   if ( PFFFT_FUNC(simd_size)() == 1 )
1141*3f1979aaSAndroid Build Coastguard Worker   {
1142*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_PFFFT_U] = "PFFFTU scal-1";
1143*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_PFFFT_O] = "PFFFT scal-1 ";
1144*3f1979aaSAndroid Build Coastguard Worker   }
1145*3f1979aaSAndroid Build Coastguard Worker   else if ( !strcmp(PFFFT_FUNC(simd_arch)(), "4xScalar") )
1146*3f1979aaSAndroid Build Coastguard Worker   {
1147*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_PFFFT_U] = "PFFFT-U scal4";
1148*3f1979aaSAndroid Build Coastguard Worker     algoName[ALGO_PFFFT_O] = "PFFFT scal-4 ";
1149*3f1979aaSAndroid Build Coastguard Worker   }
1150*3f1979aaSAndroid Build Coastguard Worker 
1151*3f1979aaSAndroid Build Coastguard Worker 
1152*3f1979aaSAndroid Build Coastguard Worker   clock();
1153*3f1979aaSAndroid Build Coastguard Worker   /* double TClockDur = 1.0 / CLOCKS_PER_SEC;
1154*3f1979aaSAndroid Build Coastguard Worker   printf("clock() duration for CLOCKS_PER_SEC = %f sec = %f ms\n", TClockDur, 1000.0 * TClockDur );
1155*3f1979aaSAndroid Build Coastguard Worker   */
1156*3f1979aaSAndroid Build Coastguard Worker 
1157*3f1979aaSAndroid Build Coastguard Worker   /* calibrate test duration */
1158*3f1979aaSAndroid Build Coastguard Worker   {
1159*3f1979aaSAndroid Build Coastguard Worker     double t0, t1, dur;
1160*3f1979aaSAndroid Build Coastguard Worker     printf("calibrating fft benchmark duration at size N = 512 ..\n");
1161*3f1979aaSAndroid Build Coastguard Worker     t0 = uclock_sec();
1162*3f1979aaSAndroid Build Coastguard Worker     if (benchReal) {
1163*3f1979aaSAndroid Build Coastguard Worker       iterCalReal = cal_benchmark(512, 0 /* real fft */);
1164*3f1979aaSAndroid Build Coastguard Worker       printf("real fft iterCal = %f\n", iterCalReal);
1165*3f1979aaSAndroid Build Coastguard Worker     }
1166*3f1979aaSAndroid Build Coastguard Worker     if (benchCplx) {
1167*3f1979aaSAndroid Build Coastguard Worker       iterCalCplx = cal_benchmark(512, 1 /* cplx fft */);
1168*3f1979aaSAndroid Build Coastguard Worker       printf("cplx fft iterCal = %f\n", iterCalCplx);
1169*3f1979aaSAndroid Build Coastguard Worker     }
1170*3f1979aaSAndroid Build Coastguard Worker     t1 = uclock_sec();
1171*3f1979aaSAndroid Build Coastguard Worker     dur = t1 - t0;
1172*3f1979aaSAndroid Build Coastguard Worker     printf("calibration done in %f sec.\n\n", dur);
1173*3f1979aaSAndroid Build Coastguard Worker   }
1174*3f1979aaSAndroid Build Coastguard Worker 
1175*3f1979aaSAndroid Build Coastguard Worker   if (!array_output_format) {
1176*3f1979aaSAndroid Build Coastguard Worker     if (benchReal) {
1177*3f1979aaSAndroid Build Coastguard Worker       for (i=0; Nvalues[i] > 0; ++i)
1178*3f1979aaSAndroid Build Coastguard Worker         benchmark_ffts(Nvalues[i], 0 /* real fft */, withFFTWfullMeas, iterCalReal, tmeas[0][i], haveAlgo, NULL);
1179*3f1979aaSAndroid Build Coastguard Worker     }
1180*3f1979aaSAndroid Build Coastguard Worker     if (benchCplx) {
1181*3f1979aaSAndroid Build Coastguard Worker       for (i=0; Nvalues[i] > 0; ++i)
1182*3f1979aaSAndroid Build Coastguard Worker         benchmark_ffts(Nvalues[i], 1 /* cplx fft */, withFFTWfullMeas, iterCalCplx, tmeas[1][i], haveAlgo, NULL);
1183*3f1979aaSAndroid Build Coastguard Worker     }
1184*3f1979aaSAndroid Build Coastguard Worker 
1185*3f1979aaSAndroid Build Coastguard Worker   } else {
1186*3f1979aaSAndroid Build Coastguard Worker 
1187*3f1979aaSAndroid Build Coastguard Worker     if (outputTable2File) {
1188*3f1979aaSAndroid Build Coastguard Worker       tableFile = fopen( usePow2 ? "bench-fft-table-pow2.txt" : "bench-fft-table-non2.txt", "w");
1189*3f1979aaSAndroid Build Coastguard Worker     }
1190*3f1979aaSAndroid Build Coastguard Worker     /* print table headers */
1191*3f1979aaSAndroid Build Coastguard Worker     printf("table shows MFlops; higher values indicate faster computation\n\n");
1192*3f1979aaSAndroid Build Coastguard Worker 
1193*3f1979aaSAndroid Build Coastguard Worker     {
1194*3f1979aaSAndroid Build Coastguard Worker       print_table("| input len ", tableFile);
1195*3f1979aaSAndroid Build Coastguard Worker       for (realCplxIdx = 0; realCplxIdx < 2; ++realCplxIdx)
1196*3f1979aaSAndroid Build Coastguard Worker       {
1197*3f1979aaSAndroid Build Coastguard Worker         if ( (realCplxIdx == 0 && !benchReal) || (realCplxIdx == 1 && !benchCplx) )
1198*3f1979aaSAndroid Build Coastguard Worker           continue;
1199*3f1979aaSAndroid Build Coastguard Worker         for (k=0; k < NUM_FFT_ALGOS; ++k)
1200*3f1979aaSAndroid Build Coastguard Worker         {
1201*3f1979aaSAndroid Build Coastguard Worker           if ( compiledInAlgo[k] )
1202*3f1979aaSAndroid Build Coastguard Worker             print_table(algoTableHeader[k][realCplxIdx], tableFile);
1203*3f1979aaSAndroid Build Coastguard Worker         }
1204*3f1979aaSAndroid Build Coastguard Worker       }
1205*3f1979aaSAndroid Build Coastguard Worker       print_table("|\n", tableFile);
1206*3f1979aaSAndroid Build Coastguard Worker     }
1207*3f1979aaSAndroid Build Coastguard Worker     /* print table value seperators */
1208*3f1979aaSAndroid Build Coastguard Worker     {
1209*3f1979aaSAndroid Build Coastguard Worker       print_table("|----------", tableFile);
1210*3f1979aaSAndroid Build Coastguard Worker       for (realCplxIdx = 0; realCplxIdx < 2; ++realCplxIdx)
1211*3f1979aaSAndroid Build Coastguard Worker       {
1212*3f1979aaSAndroid Build Coastguard Worker         if ( (realCplxIdx == 0 && !benchReal) || (realCplxIdx == 1 && !benchCplx) )
1213*3f1979aaSAndroid Build Coastguard Worker           continue;
1214*3f1979aaSAndroid Build Coastguard Worker         for (k=0; k < NUM_FFT_ALGOS; ++k)
1215*3f1979aaSAndroid Build Coastguard Worker         {
1216*3f1979aaSAndroid Build Coastguard Worker           if ( compiledInAlgo[k] )
1217*3f1979aaSAndroid Build Coastguard Worker             print_table(":|-------------", tableFile);
1218*3f1979aaSAndroid Build Coastguard Worker         }
1219*3f1979aaSAndroid Build Coastguard Worker       }
1220*3f1979aaSAndroid Build Coastguard Worker       print_table(":|\n", tableFile);
1221*3f1979aaSAndroid Build Coastguard Worker     }
1222*3f1979aaSAndroid Build Coastguard Worker 
1223*3f1979aaSAndroid Build Coastguard Worker     for (i=0; Nvalues[i] > 0; ++i) {
1224*3f1979aaSAndroid Build Coastguard Worker       {
1225*3f1979aaSAndroid Build Coastguard Worker         double t0, t1;
1226*3f1979aaSAndroid Build Coastguard Worker         print_table_fftsize(Nvalues[i], tableFile);
1227*3f1979aaSAndroid Build Coastguard Worker         t0 = uclock_sec();
1228*3f1979aaSAndroid Build Coastguard Worker         if (benchReal)
1229*3f1979aaSAndroid Build Coastguard Worker           benchmark_ffts(Nvalues[i], 0, withFFTWfullMeas, iterCalReal, tmeas[0][i], haveAlgo, tableFile);
1230*3f1979aaSAndroid Build Coastguard Worker         if (benchCplx)
1231*3f1979aaSAndroid Build Coastguard Worker           benchmark_ffts(Nvalues[i], 1, withFFTWfullMeas, iterCalCplx, tmeas[1][i], haveAlgo, tableFile);
1232*3f1979aaSAndroid Build Coastguard Worker         t1 = uclock_sec();
1233*3f1979aaSAndroid Build Coastguard Worker         print_table("|\n", tableFile);
1234*3f1979aaSAndroid Build Coastguard Worker         /* printf("all ffts for size %d took %f sec\n", Nvalues[i], t1-t0); */
1235*3f1979aaSAndroid Build Coastguard Worker         (void)t0;
1236*3f1979aaSAndroid Build Coastguard Worker         (void)t1;
1237*3f1979aaSAndroid Build Coastguard Worker       }
1238*3f1979aaSAndroid Build Coastguard Worker     }
1239*3f1979aaSAndroid Build Coastguard Worker     fprintf(stdout, " (numbers are given in MFlops)\n");
1240*3f1979aaSAndroid Build Coastguard Worker     if (outputTable2File) {
1241*3f1979aaSAndroid Build Coastguard Worker       fclose(tableFile);
1242*3f1979aaSAndroid Build Coastguard Worker     }
1243*3f1979aaSAndroid Build Coastguard Worker   }
1244*3f1979aaSAndroid Build Coastguard Worker 
1245*3f1979aaSAndroid Build Coastguard Worker   printf("\n");
1246*3f1979aaSAndroid Build Coastguard Worker   printf("now writing .csv files ..\n");
1247*3f1979aaSAndroid Build Coastguard Worker 
1248*3f1979aaSAndroid Build Coastguard Worker   for (realCplxIdx = 0; realCplxIdx < 2; ++realCplxIdx)
1249*3f1979aaSAndroid Build Coastguard Worker   {
1250*3f1979aaSAndroid Build Coastguard Worker     if ( (benchReal && realCplxIdx == 0) || (benchCplx && realCplxIdx == 1) )
1251*3f1979aaSAndroid Build Coastguard Worker     {
1252*3f1979aaSAndroid Build Coastguard Worker       for (typeIdx = 0; typeIdx < NUM_TYPES; ++typeIdx)
1253*3f1979aaSAndroid Build Coastguard Worker       {
1254*3f1979aaSAndroid Build Coastguard Worker         FILE *f = NULL;
1255*3f1979aaSAndroid Build Coastguard Worker         if ( !(SAVE_ALL_TYPES || saveType[typeIdx]) )
1256*3f1979aaSAndroid Build Coastguard Worker           continue;
1257*3f1979aaSAndroid Build Coastguard Worker         acCsvFilename[0] = 0;
1258*3f1979aaSAndroid Build Coastguard Worker #ifdef PFFFT_SIMD_DISABLE
1259*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, "scal-");
1260*3f1979aaSAndroid Build Coastguard Worker #else
1261*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, "simd-");
1262*3f1979aaSAndroid Build Coastguard Worker #endif
1263*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, (realCplxIdx == 0 ? "real-" : "cplx-"));
1264*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, ( usePow2 ? "pow2-" : "non2-"));
1265*3f1979aaSAndroid Build Coastguard Worker         assert( strlen(acCsvFilename) + strlen(typeFilenamePart[typeIdx]) + 5 < (sizeof(acCsvFilename) / sizeof(acCsvFilename[0])) );
1266*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, typeFilenamePart[typeIdx]);
1267*3f1979aaSAndroid Build Coastguard Worker         strcat(acCsvFilename, ".csv");
1268*3f1979aaSAndroid Build Coastguard Worker         f = fopen(acCsvFilename, "w");
1269*3f1979aaSAndroid Build Coastguard Worker         if (!f)
1270*3f1979aaSAndroid Build Coastguard Worker           continue;
1271*3f1979aaSAndroid Build Coastguard Worker         {
1272*3f1979aaSAndroid Build Coastguard Worker           fprintf(f, "size, log2, ");
1273*3f1979aaSAndroid Build Coastguard Worker           for (k=0; k < NUM_FFT_ALGOS; ++k)
1274*3f1979aaSAndroid Build Coastguard Worker             if ( haveAlgo[k] )
1275*3f1979aaSAndroid Build Coastguard Worker               fprintf(f, "%s, ", algoName[k]);
1276*3f1979aaSAndroid Build Coastguard Worker           fprintf(f, "\n");
1277*3f1979aaSAndroid Build Coastguard Worker         }
1278*3f1979aaSAndroid Build Coastguard Worker         for (i=0; Nvalues[i] > 0; ++i)
1279*3f1979aaSAndroid Build Coastguard Worker         {
1280*3f1979aaSAndroid Build Coastguard Worker           {
1281*3f1979aaSAndroid Build Coastguard Worker             fprintf(f, "%d, %.3f, ", Nvalues[i], log10((double)Nvalues[i])/log10(2.0) );
1282*3f1979aaSAndroid Build Coastguard Worker             for (k=0; k < NUM_FFT_ALGOS; ++k)
1283*3f1979aaSAndroid Build Coastguard Worker               if ( haveAlgo[k] )
1284*3f1979aaSAndroid Build Coastguard Worker                 fprintf(f, "%f, ", tmeas[realCplxIdx][i][typeIdx][k]);
1285*3f1979aaSAndroid Build Coastguard Worker             fprintf(f, "\n");
1286*3f1979aaSAndroid Build Coastguard Worker           }
1287*3f1979aaSAndroid Build Coastguard Worker         }
1288*3f1979aaSAndroid Build Coastguard Worker         fclose(f);
1289*3f1979aaSAndroid Build Coastguard Worker       }
1290*3f1979aaSAndroid Build Coastguard Worker     }
1291*3f1979aaSAndroid Build Coastguard Worker   }
1292*3f1979aaSAndroid Build Coastguard Worker 
1293*3f1979aaSAndroid Build Coastguard Worker   return 0;
1294*3f1979aaSAndroid Build Coastguard Worker }
1295*3f1979aaSAndroid Build Coastguard Worker 
1296