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