annotate src/fftw-3.3.8/tests/hook.c @ 169:223a55898ab9 tip default

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