annotate src/fftw-3.3.5/tests/hook.c @ 83:ae30d91d2ffe

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