comparison src/fftw-3.3.5/tests/hook.c @ 42:2cd0e3b3e1fd

Current fftw source
author Chris Cannam
date Tue, 18 Oct 2016 13:40:26 +0100
parents
children
comparison
equal deleted inserted replaced
41:481f5f8c5634 42:2cd0e3b3e1fd
1 /* fftw hook to be used in the benchmark program.
2
3 We keep it in a separate file because
4
5 1) bench.c is supposed to test the API---we do not want to #include
6 "ifftw.h" and accidentally use internal symbols/macros.
7 2) this code is a royal mess. The messiness is due to
8 A) confusion between internal fftw tensors and bench_tensor's
9 (which we want to keep separate because the benchmark
10 program tests other routines too)
11 B) despite A), our desire to recycle the libbench verifier.
12 */
13
14 #include <stdio.h>
15 #include "bench-user.h"
16
17 #define CALLING_FFTW /* hack for Windows DLL nonsense */
18 #include "api.h"
19 #include "dft.h"
20 #include "rdft.h"
21
22 extern int paranoid; /* in bench.c */
23 extern X(plan) the_plan; /* in bench.c */
24
25 /*
26 transform an fftw tensor into a bench_tensor.
27 */
28 static bench_tensor *fftw_tensor_to_bench_tensor(tensor *t)
29 {
30 bench_tensor *bt = mktensor(t->rnk);
31
32 if (FINITE_RNK(t->rnk)) {
33 int i;
34 for (i = 0; i < t->rnk; ++i) {
35 /* FIXME: 64-bit unclean because of INT -> int conversion */
36 bt->dims[i].n = t->dims[i].n;
37 bt->dims[i].is = t->dims[i].is;
38 bt->dims[i].os = t->dims[i].os;
39 BENCH_ASSERT(bt->dims[i].n == t->dims[i].n);
40 BENCH_ASSERT(bt->dims[i].is == t->dims[i].is);
41 BENCH_ASSERT(bt->dims[i].os == t->dims[i].os);
42 }
43 }
44 return bt;
45 }
46
47 /*
48 transform an fftw problem into a bench_problem.
49 */
50 static bench_problem *fftw_problem_to_bench_problem(planner *plnr,
51 const problem *p_)
52 {
53 bench_problem *bp = 0;
54 switch (p_->adt->problem_kind) {
55 case PROBLEM_DFT:
56 {
57 const problem_dft *p = (const problem_dft *) p_;
58
59 if (!p->ri || !p->ii)
60 abort();
61
62 bp = (bench_problem *) bench_malloc(sizeof(bench_problem));
63
64 bp->kind = PROBLEM_COMPLEX;
65 bp->sign = FFT_SIGN;
66 bp->split = 1; /* tensor strides are in R's, not C's */
67 bp->in = UNTAINT(p->ri);
68 bp->out = UNTAINT(p->ro);
69 bp->ini = UNTAINT(p->ii);
70 bp->outi = UNTAINT(p->io);
71 bp->inphys = bp->outphys = 0;
72 bp->iphyssz = bp->ophyssz = 0;
73 bp->in_place = p->ri == p->ro;
74 bp->sz = fftw_tensor_to_bench_tensor(p->sz);
75 bp->vecsz = fftw_tensor_to_bench_tensor(p->vecsz);
76 bp->k = 0;
77 break;
78 }
79 case PROBLEM_RDFT:
80 {
81 const problem_rdft *p = (const problem_rdft *) p_;
82 int i;
83
84 if (!p->I || !p->O)
85 abort();
86
87 for (i = 0; i < p->sz->rnk; ++i)
88 switch (p->kind[i]) {
89 case R2HC01:
90 case R2HC10:
91 case R2HC11:
92 case HC2R01:
93 case HC2R10:
94 case HC2R11:
95 return bp;
96 default:
97 ;
98 }
99
100 bp = (bench_problem *) bench_malloc(sizeof(bench_problem));
101
102 bp->kind = PROBLEM_R2R;
103 bp->sign = FFT_SIGN;
104 bp->split = 0;
105 bp->in = UNTAINT(p->I);
106 bp->out = UNTAINT(p->O);
107 bp->ini = bp->outi = 0;
108 bp->inphys = bp->outphys = 0;
109 bp->iphyssz = bp->ophyssz = 0;
110 bp->in_place = p->I == p->O;
111 bp->sz = fftw_tensor_to_bench_tensor(p->sz);
112 bp->vecsz = fftw_tensor_to_bench_tensor(p->vecsz);
113 bp->k = (r2r_kind_t *) bench_malloc(sizeof(r2r_kind_t) * p->sz->rnk);
114 for (i = 0; i < p->sz->rnk; ++i)
115 switch (p->kind[i]) {
116 case R2HC: bp->k[i] = R2R_R2HC; break;
117 case HC2R: bp->k[i] = R2R_HC2R; break;
118 case DHT: bp->k[i] = R2R_DHT; break;
119 case REDFT00: bp->k[i] = R2R_REDFT00; break;
120 case REDFT01: bp->k[i] = R2R_REDFT01; break;
121 case REDFT10: bp->k[i] = R2R_REDFT10; break;
122 case REDFT11: bp->k[i] = R2R_REDFT11; break;
123 case RODFT00: bp->k[i] = R2R_RODFT00; break;
124 case RODFT01: bp->k[i] = R2R_RODFT01; break;
125 case RODFT10: bp->k[i] = R2R_RODFT10; break;
126 case RODFT11: bp->k[i] = R2R_RODFT11; break;
127 default: CK(0);
128 }
129 break;
130 }
131 case PROBLEM_RDFT2:
132 {
133 const problem_rdft2 *p = (const problem_rdft2 *) p_;
134 int rnk = p->sz->rnk;
135
136 if (!p->r0 || !p->r1 || !p->cr || !p->ci)
137 abort();
138
139 /* give up verifying rdft2 R2HCII */
140 if (p->kind != R2HC && p->kind != HC2R)
141 return bp;
142
143 if (rnk > 0) {
144 /* can't verify separate even/odd arrays for now */
145 if (2 * (p->r1 - p->r0) !=
146 ((p->kind == R2HC) ?
147 p->sz->dims[rnk-1].is : p->sz->dims[rnk-1].os))
148 return bp;
149 }
150
151 bp = (bench_problem *) bench_malloc(sizeof(bench_problem));
152
153 bp->kind = PROBLEM_REAL;
154 bp->sign = p->kind == R2HC ? FFT_SIGN : -FFT_SIGN;
155 bp->split = 1; /* tensor strides are in R's, not C's */
156 if (p->kind == R2HC) {
157 bp->sign = FFT_SIGN;
158 bp->in = UNTAINT(p->r0);
159 bp->out = UNTAINT(p->cr);
160 bp->ini = 0;
161 bp->outi = UNTAINT(p->ci);
162 }
163 else {
164 bp->sign = -FFT_SIGN;
165 bp->out = UNTAINT(p->r0);
166 bp->in = UNTAINT(p->cr);
167 bp->outi = 0;
168 bp->ini = UNTAINT(p->ci);
169 }
170 bp->inphys = bp->outphys = 0;
171 bp->iphyssz = bp->ophyssz = 0;
172 bp->in_place = p->r0 == p->cr;
173 bp->sz = fftw_tensor_to_bench_tensor(p->sz);
174 if (rnk > 0) {
175 if (p->kind == R2HC)
176 bp->sz->dims[rnk-1].is /= 2;
177 else
178 bp->sz->dims[rnk-1].os /= 2;
179 }
180 bp->vecsz = fftw_tensor_to_bench_tensor(p->vecsz);
181 bp->k = 0;
182 break;
183 }
184 default:
185 abort();
186 }
187
188 bp->userinfo = 0;
189 bp->pstring = 0;
190 bp->destroy_input = !NO_DESTROY_INPUTP(plnr);
191
192 return bp;
193 }
194
195 static void hook(planner *plnr, plan *pln, const problem *p_, int optimalp)
196 {
197 int rounds = 5;
198 double tol = SINGLE_PRECISION ? 1.0e-3 : 1.0e-10;
199 UNUSED(optimalp);
200
201 if (verbose > 5) {
202 printer *pr = X(mkprinter_file)(stdout);
203 pr->print(pr, "%P:%(%p%)\n", p_, pln);
204 X(printer_destroy)(pr);
205 printf("cost %g \n\n", pln->pcost);
206 }
207
208 if (paranoid) {
209 bench_problem *bp;
210
211 bp = fftw_problem_to_bench_problem(plnr, p_);
212 if (bp) {
213 X(plan) the_plan_save = the_plan;
214
215 the_plan = (apiplan *) MALLOC(sizeof(apiplan), PLANS);
216 the_plan->pln = pln;
217 the_plan->prb = (problem *) p_;
218
219 X(plan_awake)(pln, AWAKE_SQRTN_TABLE);
220 verify_problem(bp, rounds, tol);
221 X(plan_awake)(pln, SLEEPY);
222
223 X(ifree)(the_plan);
224 the_plan = the_plan_save;
225
226 problem_destroy(bp);
227 }
228
229 }
230 }
231
232 static void paranoid_checks(void)
233 {
234 /* FIXME: assumes char = 8 bits, which is false on at least one
235 DSP I know of. */
236 #if 0
237 /* if flags_t is not 64 bits i want to know it. */
238 CK(sizeof(flags_t) == 8);
239
240 CK(sizeof(md5uint) >= 4);
241 #endif
242
243 CK(sizeof(uintptr_t) >= sizeof(R *));
244
245 CK(sizeof(INT) >= sizeof(R *));
246 }
247
248 void install_hook(void)
249 {
250 planner *plnr = X(the_planner)();
251 plnr->hook = hook;
252 paranoid_checks();
253 }
254
255 void uninstall_hook(void)
256 {
257 planner *plnr = X(the_planner)();
258 plnr->hook = 0;
259 }