comparison fft/fftw/fftw-3.3.4/tests/fftw-bench.c @ 19:26056e866c29

Add FFTW to comparison table
author Chris Cannam
date Tue, 06 Oct 2015 13:08:39 +0100
parents
children
comparison
equal deleted inserted replaced
18:8db794ca3e0b 19:26056e866c29
1 /* See bench.c. We keep a few common subroutines in this file so
2 that they can be re-used in the MPI test program. */
3
4 #include <math.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "fftw-bench.h"
8
9 #ifdef _OPENMP
10 # include <omp.h>
11 #endif
12
13 #ifdef HAVE_SMP
14 int threads_ok = 1;
15 #endif
16
17 FFTW(plan) the_plan = 0;
18
19 static const char *wisdat = "wis.dat";
20 unsigned the_flags = 0;
21 int paranoid = 0;
22 int usewisdom = 0;
23 int havewisdom = 0;
24 int nthreads = 1;
25 int amnesia = 0;
26
27 extern void install_hook(void); /* in hook.c */
28 extern void uninstall_hook(void); /* in hook.c */
29
30 #ifdef FFTW_RANDOM_ESTIMATOR
31 extern unsigned FFTW(random_estimate_seed);
32 #endif
33
34 void useropt(const char *arg)
35 {
36 int x;
37 double y;
38
39 if (!strcmp(arg, "patient")) the_flags |= FFTW_PATIENT;
40 else if (!strcmp(arg, "estimate")) the_flags |= FFTW_ESTIMATE;
41 else if (!strcmp(arg, "estimatepat")) the_flags |= FFTW_ESTIMATE_PATIENT;
42 else if (!strcmp(arg, "exhaustive")) the_flags |= FFTW_EXHAUSTIVE;
43 else if (!strcmp(arg, "unaligned")) the_flags |= FFTW_UNALIGNED;
44 else if (!strcmp(arg, "nosimd")) the_flags |= FFTW_NO_SIMD;
45 else if (!strcmp(arg, "noindirectop")) the_flags |= FFTW_NO_INDIRECT_OP;
46 else if (!strcmp(arg, "wisdom-only")) the_flags |= FFTW_WISDOM_ONLY;
47 else if (sscanf(arg, "flag=%d", &x) == 1) the_flags |= x;
48 else if (sscanf(arg, "bflag=%d", &x) == 1) the_flags |= 1U << x;
49 else if (!strcmp(arg, "paranoid")) paranoid = 1;
50 else if (!strcmp(arg, "wisdom")) usewisdom = 1;
51 else if (!strcmp(arg, "amnesia")) amnesia = 1;
52 else if (sscanf(arg, "nthreads=%d", &x) == 1) nthreads = x;
53 #ifdef FFTW_RANDOM_ESTIMATOR
54 else if (sscanf(arg, "eseed=%d", &x) == 1) FFTW(random_estimate_seed) = x;
55 #endif
56 else if (sscanf(arg, "timelimit=%lg", &y) == 1) {
57 FFTW(set_timelimit)(y);
58 }
59
60 else fprintf(stderr, "unknown user option: %s. Ignoring.\n", arg);
61 }
62
63 void rdwisdom(void)
64 {
65 FILE *f;
66 double tim;
67 int success = 0;
68
69 if (havewisdom) return;
70
71 #ifdef HAVE_SMP
72 if (threads_ok) {
73 BENCH_ASSERT(FFTW(init_threads)());
74 FFTW(plan_with_nthreads)(nthreads);
75 #ifdef _OPENMP
76 omp_set_num_threads(nthreads);
77 #endif
78 }
79 else if (nthreads > 1 && verbose > 1) {
80 fprintf(stderr, "bench: WARNING - nthreads = %d, but threads not supported\n", nthreads);
81 nthreads = 1;
82 }
83 #endif
84
85 if (!usewisdom) return;
86
87 timer_start(USER_TIMER);
88 if ((f = fopen(wisdat, "r"))) {
89 if (!import_wisdom(f))
90 fprintf(stderr, "bench: ERROR reading wisdom\n");
91 else
92 success = 1;
93 fclose(f);
94 }
95 tim = timer_stop(USER_TIMER);
96
97 if (success) {
98 if (verbose > 1) printf("READ WISDOM (%g seconds): ", tim);
99
100 if (verbose > 3)
101 export_wisdom(stdout);
102 if (verbose > 1)
103 printf("\n");
104 }
105 havewisdom = 1;
106 }
107
108 void wrwisdom(void)
109 {
110 FILE *f;
111 double tim;
112 if (!havewisdom) return;
113
114 timer_start(USER_TIMER);
115 if ((f = fopen(wisdat, "w"))) {
116 export_wisdom(f);
117 fclose(f);
118 }
119 tim = timer_stop(USER_TIMER);
120 if (verbose > 1) printf("write wisdom took %g seconds\n", tim);
121 }
122
123 static unsigned preserve_input_flags(bench_problem *p)
124 {
125 /*
126 * fftw3 cannot preserve input for multidimensional c2r transforms.
127 * Enforce FFTW_DESTROY_INPUT
128 */
129 if (p->kind == PROBLEM_REAL &&
130 p->sign > 0 &&
131 !p->in_place &&
132 p->sz->rnk > 1)
133 p->destroy_input = 1;
134
135 if (p->destroy_input)
136 return FFTW_DESTROY_INPUT;
137 else
138 return FFTW_PRESERVE_INPUT;
139 }
140
141 int can_do(bench_problem *p)
142 {
143 double tim;
144
145 if (verbose > 2 && p->pstring)
146 printf("Planning %s...\n", p->pstring);
147 rdwisdom();
148
149 timer_start(USER_TIMER);
150 the_plan = mkplan(p, preserve_input_flags(p) | the_flags | FFTW_ESTIMATE);
151 tim = timer_stop(USER_TIMER);
152 if (verbose > 2) printf("estimate-planner time: %g s\n", tim);
153
154 if (the_plan) {
155 FFTW(destroy_plan)(the_plan);
156 return 1;
157 }
158 return 0;
159 }
160
161 void setup(bench_problem *p)
162 {
163 double tim;
164
165 if (amnesia) {
166 FFTW(forget_wisdom)();
167 havewisdom = 0;
168 }
169
170 /* Regression test: check that fftw_malloc exists and links
171 * properly */
172 FFTW(free(FFTW(malloc(42))));
173
174 rdwisdom();
175 install_hook();
176
177 #ifdef HAVE_SMP
178 if (verbose > 1 && nthreads > 1) printf("NTHREADS = %d\n", nthreads);
179 #endif
180
181 timer_start(USER_TIMER);
182 the_plan = mkplan(p, preserve_input_flags(p) | the_flags);
183 tim = timer_stop(USER_TIMER);
184 if (verbose > 1) printf("planner time: %g s\n", tim);
185
186 BENCH_ASSERT(the_plan);
187
188 {
189 double add, mul, nfma, cost, pcost;
190 FFTW(flops)(the_plan, &add, &mul, &nfma);
191 cost = FFTW(estimate_cost)(the_plan);
192 pcost = FFTW(cost)(the_plan);
193 if (verbose > 1) {
194 FFTW(print_plan)(the_plan);
195 printf("\n");
196 printf("flops: %0.0f add, %0.0f mul, %0.0f fma\n",
197 add, mul, nfma);
198 printf("estimated cost: %f, pcost = %f\n", cost, pcost);
199 }
200 }
201 }
202
203
204 void doit(int iter, bench_problem *p)
205 {
206 int i;
207 FFTW(plan) q = the_plan;
208
209 UNUSED(p);
210 for (i = 0; i < iter; ++i)
211 FFTW(execute)(q);
212 }
213
214 void done(bench_problem *p)
215 {
216 UNUSED(p);
217
218 FFTW(destroy_plan)(the_plan);
219 uninstall_hook();
220 }
221
222 void cleanup(void)
223 {
224 initial_cleanup();
225
226 wrwisdom();
227 #ifdef HAVE_SMP
228 FFTW(cleanup_threads)();
229 #else
230 FFTW(cleanup)();
231 #endif
232
233 # ifdef FFTW_DEBUG_MALLOC
234 {
235 /* undocumented memory checker */
236 FFTW_EXTERN void FFTW(malloc_print_minfo)(int v);
237 FFTW(malloc_print_minfo)(verbose);
238 }
239 # endif
240
241 final_cleanup();
242 }