Mercurial > hg > js-dsp-test
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 } |