annotate src/fftw-3.3.3/tests/bench.c @ 36:55ece8862b6d

Merge
author Chris Cannam
date Wed, 11 Mar 2015 13:32:44 +0000
parents 37bf6b4a2645
children
rev   line source
Chris@10 1 /**************************************************************************/
Chris@10 2 /* NOTE to users: this is the FFTW self-test and benchmark program.
Chris@10 3 It is probably NOT a good place to learn FFTW usage, since it has a
Chris@10 4 lot of added complexity in order to exercise and test the full API,
Chris@10 5 etcetera. We suggest reading the manual.
Chris@10 6
Chris@10 7 (Some of the self-test code is split off into fftw-bench.c and
Chris@10 8 hook.c.) */
Chris@10 9 /**************************************************************************/
Chris@10 10
Chris@10 11 #include <math.h>
Chris@10 12 #include <stdio.h>
Chris@10 13 #include <string.h>
Chris@10 14 #include "fftw-bench.h"
Chris@10 15
Chris@10 16 static const char *mkversion(void) { return FFTW(version); }
Chris@10 17 static const char *mkcc(void) { return FFTW(cc); }
Chris@10 18 static const char *mkcodelet_optim(void) { return FFTW(codelet_optim); }
Chris@10 19
Chris@10 20 BEGIN_BENCH_DOC
Chris@10 21 BENCH_DOC("name", "fftw3")
Chris@10 22 BENCH_DOCF("version", mkversion)
Chris@10 23 BENCH_DOCF("cc", mkcc)
Chris@10 24 BENCH_DOCF("codelet-optim", mkcodelet_optim)
Chris@10 25 END_BENCH_DOC
Chris@10 26
Chris@10 27 static FFTW(iodim) *bench_tensor_to_fftw_iodim(bench_tensor *t)
Chris@10 28 {
Chris@10 29 FFTW(iodim) *d;
Chris@10 30 int i;
Chris@10 31
Chris@10 32 BENCH_ASSERT(t->rnk >= 0);
Chris@10 33 if (t->rnk == 0) return 0;
Chris@10 34
Chris@10 35 d = (FFTW(iodim) *)bench_malloc(sizeof(FFTW(iodim)) * t->rnk);
Chris@10 36 for (i = 0; i < t->rnk; ++i) {
Chris@10 37 d[i].n = t->dims[i].n;
Chris@10 38 d[i].is = t->dims[i].is;
Chris@10 39 d[i].os = t->dims[i].os;
Chris@10 40 }
Chris@10 41
Chris@10 42 return d;
Chris@10 43 }
Chris@10 44
Chris@10 45 static void extract_reim_split(int sign, int size, bench_real *p,
Chris@10 46 bench_real **r, bench_real **i)
Chris@10 47 {
Chris@10 48 if (sign == FFTW_FORWARD) {
Chris@10 49 *r = p + 0;
Chris@10 50 *i = p + size;
Chris@10 51 } else {
Chris@10 52 *r = p + size;
Chris@10 53 *i = p + 0;
Chris@10 54 }
Chris@10 55 }
Chris@10 56
Chris@10 57 static int sizeof_problem(bench_problem *p)
Chris@10 58 {
Chris@10 59 return tensor_sz(p->sz) * tensor_sz(p->vecsz);
Chris@10 60 }
Chris@10 61
Chris@10 62 /* ouch */
Chris@10 63 static int expressible_as_api_many(bench_tensor *t)
Chris@10 64 {
Chris@10 65 int i;
Chris@10 66
Chris@10 67 BENCH_ASSERT(FINITE_RNK(t->rnk));
Chris@10 68
Chris@10 69 i = t->rnk - 1;
Chris@10 70 while (--i >= 0) {
Chris@10 71 bench_iodim *d = t->dims + i;
Chris@10 72 if (d[0].is % d[1].is) return 0;
Chris@10 73 if (d[0].os % d[1].os) return 0;
Chris@10 74 }
Chris@10 75 return 1;
Chris@10 76 }
Chris@10 77
Chris@10 78 static int *mkn(bench_tensor *t)
Chris@10 79 {
Chris@10 80 int *n = (int *) bench_malloc(sizeof(int *) * t->rnk);
Chris@10 81 int i;
Chris@10 82 for (i = 0; i < t->rnk; ++i)
Chris@10 83 n[i] = t->dims[i].n;
Chris@10 84 return n;
Chris@10 85 }
Chris@10 86
Chris@10 87 static void mknembed_many(bench_tensor *t, int **inembedp, int **onembedp)
Chris@10 88 {
Chris@10 89 int i;
Chris@10 90 bench_iodim *d;
Chris@10 91 int *inembed = (int *) bench_malloc(sizeof(int *) * t->rnk);
Chris@10 92 int *onembed = (int *) bench_malloc(sizeof(int *) * t->rnk);
Chris@10 93
Chris@10 94 BENCH_ASSERT(FINITE_RNK(t->rnk));
Chris@10 95 *inembedp = inembed; *onembedp = onembed;
Chris@10 96
Chris@10 97 i = t->rnk - 1;
Chris@10 98 while (--i >= 0) {
Chris@10 99 d = t->dims + i;
Chris@10 100 inembed[i+1] = d[0].is / d[1].is;
Chris@10 101 onembed[i+1] = d[0].os / d[1].os;
Chris@10 102 }
Chris@10 103 }
Chris@10 104
Chris@10 105 /* try to use the most appropriate API function. Big mess. */
Chris@10 106
Chris@10 107 static int imax(int a, int b) { return (a > b ? a : b); }
Chris@10 108
Chris@10 109 static int halfish_sizeof_problem(bench_problem *p)
Chris@10 110 {
Chris@10 111 int n2 = sizeof_problem(p);
Chris@10 112 if (FINITE_RNK(p->sz->rnk) && p->sz->rnk > 0)
Chris@10 113 n2 = (n2 / imax(p->sz->dims[p->sz->rnk - 1].n, 1)) *
Chris@10 114 (p->sz->dims[p->sz->rnk - 1].n / 2 + 1);
Chris@10 115 return n2;
Chris@10 116 }
Chris@10 117
Chris@10 118 static FFTW(plan) mkplan_real_split(bench_problem *p, unsigned flags)
Chris@10 119 {
Chris@10 120 FFTW(plan) pln;
Chris@10 121 bench_tensor *sz = p->sz, *vecsz = p->vecsz;
Chris@10 122 FFTW(iodim) *dims, *howmany_dims;
Chris@10 123 bench_real *ri, *ii, *ro, *io;
Chris@10 124 int n2 = halfish_sizeof_problem(p);
Chris@10 125
Chris@10 126 extract_reim_split(FFTW_FORWARD, n2, (bench_real *) p->in, &ri, &ii);
Chris@10 127 extract_reim_split(FFTW_FORWARD, n2, (bench_real *) p->out, &ro, &io);
Chris@10 128
Chris@10 129 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 130 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 131 if (p->sign < 0) {
Chris@10 132 if (verbose > 2) printf("using plan_guru_split_dft_r2c\n");
Chris@10 133 pln = FFTW(plan_guru_split_dft_r2c)(sz->rnk, dims,
Chris@10 134 vecsz->rnk, howmany_dims,
Chris@10 135 ri, ro, io, flags);
Chris@10 136 }
Chris@10 137 else {
Chris@10 138 if (verbose > 2) printf("using plan_guru_split_dft_c2r\n");
Chris@10 139 pln = FFTW(plan_guru_split_dft_c2r)(sz->rnk, dims,
Chris@10 140 vecsz->rnk, howmany_dims,
Chris@10 141 ri, ii, ro, flags);
Chris@10 142 }
Chris@10 143 bench_free(dims);
Chris@10 144 bench_free(howmany_dims);
Chris@10 145 return pln;
Chris@10 146 }
Chris@10 147
Chris@10 148 static FFTW(plan) mkplan_real_interleaved(bench_problem *p, unsigned flags)
Chris@10 149 {
Chris@10 150 FFTW(plan) pln;
Chris@10 151 bench_tensor *sz = p->sz, *vecsz = p->vecsz;
Chris@10 152
Chris@10 153 if (vecsz->rnk == 0 && tensor_unitstridep(sz)
Chris@10 154 && tensor_real_rowmajorp(sz, p->sign, p->in_place))
Chris@10 155 goto api_simple;
Chris@10 156
Chris@10 157 if (vecsz->rnk == 1 && expressible_as_api_many(sz))
Chris@10 158 goto api_many;
Chris@10 159
Chris@10 160 goto api_guru;
Chris@10 161
Chris@10 162 api_simple:
Chris@10 163 switch (sz->rnk) {
Chris@10 164 case 1:
Chris@10 165 if (p->sign < 0) {
Chris@10 166 if (verbose > 2) printf("using plan_dft_r2c_1d\n");
Chris@10 167 return FFTW(plan_dft_r2c_1d)(sz->dims[0].n,
Chris@10 168 (bench_real *) p->in,
Chris@10 169 (bench_complex *) p->out,
Chris@10 170 flags);
Chris@10 171 }
Chris@10 172 else {
Chris@10 173 if (verbose > 2) printf("using plan_dft_c2r_1d\n");
Chris@10 174 return FFTW(plan_dft_c2r_1d)(sz->dims[0].n,
Chris@10 175 (bench_complex *) p->in,
Chris@10 176 (bench_real *) p->out,
Chris@10 177 flags);
Chris@10 178 }
Chris@10 179 break;
Chris@10 180 case 2:
Chris@10 181 if (p->sign < 0) {
Chris@10 182 if (verbose > 2) printf("using plan_dft_r2c_2d\n");
Chris@10 183 return FFTW(plan_dft_r2c_2d)(sz->dims[0].n, sz->dims[1].n,
Chris@10 184 (bench_real *) p->in,
Chris@10 185 (bench_complex *) p->out,
Chris@10 186 flags);
Chris@10 187 }
Chris@10 188 else {
Chris@10 189 if (verbose > 2) printf("using plan_dft_c2r_2d\n");
Chris@10 190 return FFTW(plan_dft_c2r_2d)(sz->dims[0].n, sz->dims[1].n,
Chris@10 191 (bench_complex *) p->in,
Chris@10 192 (bench_real *) p->out,
Chris@10 193 flags);
Chris@10 194 }
Chris@10 195 break;
Chris@10 196 case 3:
Chris@10 197 if (p->sign < 0) {
Chris@10 198 if (verbose > 2) printf("using plan_dft_r2c_3d\n");
Chris@10 199 return FFTW(plan_dft_r2c_3d)(
Chris@10 200 sz->dims[0].n, sz->dims[1].n, sz->dims[2].n,
Chris@10 201 (bench_real *) p->in, (bench_complex *) p->out,
Chris@10 202 flags);
Chris@10 203 }
Chris@10 204 else {
Chris@10 205 if (verbose > 2) printf("using plan_dft_c2r_3d\n");
Chris@10 206 return FFTW(plan_dft_c2r_3d)(
Chris@10 207 sz->dims[0].n, sz->dims[1].n, sz->dims[2].n,
Chris@10 208 (bench_complex *) p->in, (bench_real *) p->out,
Chris@10 209 flags);
Chris@10 210 }
Chris@10 211 break;
Chris@10 212 default: {
Chris@10 213 int *n = mkn(sz);
Chris@10 214 if (p->sign < 0) {
Chris@10 215 if (verbose > 2) printf("using plan_dft_r2c\n");
Chris@10 216 pln = FFTW(plan_dft_r2c)(sz->rnk, n,
Chris@10 217 (bench_real *) p->in,
Chris@10 218 (bench_complex *) p->out,
Chris@10 219 flags);
Chris@10 220 }
Chris@10 221 else {
Chris@10 222 if (verbose > 2) printf("using plan_dft_c2r\n");
Chris@10 223 pln = FFTW(plan_dft_c2r)(sz->rnk, n,
Chris@10 224 (bench_complex *) p->in,
Chris@10 225 (bench_real *) p->out,
Chris@10 226 flags);
Chris@10 227 }
Chris@10 228 bench_free(n);
Chris@10 229 return pln;
Chris@10 230 }
Chris@10 231 }
Chris@10 232
Chris@10 233 api_many:
Chris@10 234 {
Chris@10 235 int *n, *inembed, *onembed;
Chris@10 236 BENCH_ASSERT(vecsz->rnk == 1);
Chris@10 237 n = mkn(sz);
Chris@10 238 mknembed_many(sz, &inembed, &onembed);
Chris@10 239 if (p->sign < 0) {
Chris@10 240 if (verbose > 2) printf("using plan_many_dft_r2c\n");
Chris@10 241 pln = FFTW(plan_many_dft_r2c)(
Chris@10 242 sz->rnk, n, vecsz->dims[0].n,
Chris@10 243 (bench_real *) p->in, inembed,
Chris@10 244 sz->dims[sz->rnk - 1].is, vecsz->dims[0].is,
Chris@10 245 (bench_complex *) p->out, onembed,
Chris@10 246 sz->dims[sz->rnk - 1].os, vecsz->dims[0].os,
Chris@10 247 flags);
Chris@10 248 }
Chris@10 249 else {
Chris@10 250 if (verbose > 2) printf("using plan_many_dft_c2r\n");
Chris@10 251 pln = FFTW(plan_many_dft_c2r)(
Chris@10 252 sz->rnk, n, vecsz->dims[0].n,
Chris@10 253 (bench_complex *) p->in, inembed,
Chris@10 254 sz->dims[sz->rnk - 1].is, vecsz->dims[0].is,
Chris@10 255 (bench_real *) p->out, onembed,
Chris@10 256 sz->dims[sz->rnk - 1].os, vecsz->dims[0].os,
Chris@10 257 flags);
Chris@10 258 }
Chris@10 259 bench_free(n); bench_free(inembed); bench_free(onembed);
Chris@10 260 return pln;
Chris@10 261 }
Chris@10 262
Chris@10 263 api_guru:
Chris@10 264 {
Chris@10 265 FFTW(iodim) *dims, *howmany_dims;
Chris@10 266
Chris@10 267 if (p->sign < 0) {
Chris@10 268 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 269 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 270 if (verbose > 2) printf("using plan_guru_dft_r2c\n");
Chris@10 271 pln = FFTW(plan_guru_dft_r2c)(sz->rnk, dims,
Chris@10 272 vecsz->rnk, howmany_dims,
Chris@10 273 (bench_real *) p->in,
Chris@10 274 (bench_complex *) p->out,
Chris@10 275 flags);
Chris@10 276 }
Chris@10 277 else {
Chris@10 278 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 279 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 280 if (verbose > 2) printf("using plan_guru_dft_c2r\n");
Chris@10 281 pln = FFTW(plan_guru_dft_c2r)(sz->rnk, dims,
Chris@10 282 vecsz->rnk, howmany_dims,
Chris@10 283 (bench_complex *) p->in,
Chris@10 284 (bench_real *) p->out,
Chris@10 285 flags);
Chris@10 286 }
Chris@10 287 bench_free(dims);
Chris@10 288 bench_free(howmany_dims);
Chris@10 289 return pln;
Chris@10 290 }
Chris@10 291 }
Chris@10 292
Chris@10 293 static FFTW(plan) mkplan_real(bench_problem *p, unsigned flags)
Chris@10 294 {
Chris@10 295 if (p->split)
Chris@10 296 return mkplan_real_split(p, flags);
Chris@10 297 else
Chris@10 298 return mkplan_real_interleaved(p, flags);
Chris@10 299 }
Chris@10 300
Chris@10 301 static FFTW(plan) mkplan_complex_split(bench_problem *p, unsigned flags)
Chris@10 302 {
Chris@10 303 FFTW(plan) pln;
Chris@10 304 bench_tensor *sz = p->sz, *vecsz = p->vecsz;
Chris@10 305 FFTW(iodim) *dims, *howmany_dims;
Chris@10 306 bench_real *ri, *ii, *ro, *io;
Chris@10 307
Chris@10 308 extract_reim_split(p->sign, p->iphyssz, (bench_real *) p->in, &ri, &ii);
Chris@10 309 extract_reim_split(p->sign, p->ophyssz, (bench_real *) p->out, &ro, &io);
Chris@10 310
Chris@10 311 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 312 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 313 if (verbose > 2) printf("using plan_guru_split_dft\n");
Chris@10 314 pln = FFTW(plan_guru_split_dft)(sz->rnk, dims,
Chris@10 315 vecsz->rnk, howmany_dims,
Chris@10 316 ri, ii, ro, io, flags);
Chris@10 317 bench_free(dims);
Chris@10 318 bench_free(howmany_dims);
Chris@10 319 return pln;
Chris@10 320 }
Chris@10 321
Chris@10 322 static FFTW(plan) mkplan_complex_interleaved(bench_problem *p, unsigned flags)
Chris@10 323 {
Chris@10 324 FFTW(plan) pln;
Chris@10 325 bench_tensor *sz = p->sz, *vecsz = p->vecsz;
Chris@10 326
Chris@10 327 if (vecsz->rnk == 0 && tensor_unitstridep(sz) && tensor_rowmajorp(sz))
Chris@10 328 goto api_simple;
Chris@10 329
Chris@10 330 if (vecsz->rnk == 1 && expressible_as_api_many(sz))
Chris@10 331 goto api_many;
Chris@10 332
Chris@10 333 goto api_guru;
Chris@10 334
Chris@10 335 api_simple:
Chris@10 336 switch (sz->rnk) {
Chris@10 337 case 1:
Chris@10 338 if (verbose > 2) printf("using plan_dft_1d\n");
Chris@10 339 return FFTW(plan_dft_1d)(sz->dims[0].n,
Chris@10 340 (bench_complex *) p->in,
Chris@10 341 (bench_complex *) p->out,
Chris@10 342 p->sign, flags);
Chris@10 343 break;
Chris@10 344 case 2:
Chris@10 345 if (verbose > 2) printf("using plan_dft_2d\n");
Chris@10 346 return FFTW(plan_dft_2d)(sz->dims[0].n, sz->dims[1].n,
Chris@10 347 (bench_complex *) p->in,
Chris@10 348 (bench_complex *) p->out,
Chris@10 349 p->sign, flags);
Chris@10 350 break;
Chris@10 351 case 3:
Chris@10 352 if (verbose > 2) printf("using plan_dft_3d\n");
Chris@10 353 return FFTW(plan_dft_3d)(
Chris@10 354 sz->dims[0].n, sz->dims[1].n, sz->dims[2].n,
Chris@10 355 (bench_complex *) p->in, (bench_complex *) p->out,
Chris@10 356 p->sign, flags);
Chris@10 357 break;
Chris@10 358 default: {
Chris@10 359 int *n = mkn(sz);
Chris@10 360 if (verbose > 2) printf("using plan_dft\n");
Chris@10 361 pln = FFTW(plan_dft)(sz->rnk, n,
Chris@10 362 (bench_complex *) p->in,
Chris@10 363 (bench_complex *) p->out, p->sign, flags);
Chris@10 364 bench_free(n);
Chris@10 365 return pln;
Chris@10 366 }
Chris@10 367 }
Chris@10 368
Chris@10 369 api_many:
Chris@10 370 {
Chris@10 371 int *n, *inembed, *onembed;
Chris@10 372 BENCH_ASSERT(vecsz->rnk == 1);
Chris@10 373 n = mkn(sz);
Chris@10 374 mknembed_many(sz, &inembed, &onembed);
Chris@10 375 if (verbose > 2) printf("using plan_many_dft\n");
Chris@10 376 pln = FFTW(plan_many_dft)(
Chris@10 377 sz->rnk, n, vecsz->dims[0].n,
Chris@10 378 (bench_complex *) p->in,
Chris@10 379 inembed, sz->dims[sz->rnk - 1].is, vecsz->dims[0].is,
Chris@10 380 (bench_complex *) p->out,
Chris@10 381 onembed, sz->dims[sz->rnk - 1].os, vecsz->dims[0].os,
Chris@10 382 p->sign, flags);
Chris@10 383 bench_free(n); bench_free(inembed); bench_free(onembed);
Chris@10 384 return pln;
Chris@10 385 }
Chris@10 386
Chris@10 387 api_guru:
Chris@10 388 {
Chris@10 389 FFTW(iodim) *dims, *howmany_dims;
Chris@10 390
Chris@10 391 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 392 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 393 if (verbose > 2) printf("using plan_guru_dft\n");
Chris@10 394 pln = FFTW(plan_guru_dft)(sz->rnk, dims,
Chris@10 395 vecsz->rnk, howmany_dims,
Chris@10 396 (bench_complex *) p->in,
Chris@10 397 (bench_complex *) p->out,
Chris@10 398 p->sign, flags);
Chris@10 399 bench_free(dims);
Chris@10 400 bench_free(howmany_dims);
Chris@10 401 return pln;
Chris@10 402 }
Chris@10 403 }
Chris@10 404
Chris@10 405 static FFTW(plan) mkplan_complex(bench_problem *p, unsigned flags)
Chris@10 406 {
Chris@10 407 if (p->split)
Chris@10 408 return mkplan_complex_split(p, flags);
Chris@10 409 else
Chris@10 410 return mkplan_complex_interleaved(p, flags);
Chris@10 411 }
Chris@10 412
Chris@10 413 static FFTW(plan) mkplan_r2r(bench_problem *p, unsigned flags)
Chris@10 414 {
Chris@10 415 FFTW(plan) pln;
Chris@10 416 bench_tensor *sz = p->sz, *vecsz = p->vecsz;
Chris@10 417 FFTW(r2r_kind) *k;
Chris@10 418
Chris@10 419 k = (FFTW(r2r_kind) *) bench_malloc(sizeof(FFTW(r2r_kind)) * sz->rnk);
Chris@10 420 {
Chris@10 421 int i;
Chris@10 422 for (i = 0; i < sz->rnk; ++i)
Chris@10 423 switch (p->k[i]) {
Chris@10 424 case R2R_R2HC: k[i] = FFTW_R2HC; break;
Chris@10 425 case R2R_HC2R: k[i] = FFTW_HC2R; break;
Chris@10 426 case R2R_DHT: k[i] = FFTW_DHT; break;
Chris@10 427 case R2R_REDFT00: k[i] = FFTW_REDFT00; break;
Chris@10 428 case R2R_REDFT01: k[i] = FFTW_REDFT01; break;
Chris@10 429 case R2R_REDFT10: k[i] = FFTW_REDFT10; break;
Chris@10 430 case R2R_REDFT11: k[i] = FFTW_REDFT11; break;
Chris@10 431 case R2R_RODFT00: k[i] = FFTW_RODFT00; break;
Chris@10 432 case R2R_RODFT01: k[i] = FFTW_RODFT01; break;
Chris@10 433 case R2R_RODFT10: k[i] = FFTW_RODFT10; break;
Chris@10 434 case R2R_RODFT11: k[i] = FFTW_RODFT11; break;
Chris@10 435 default: BENCH_ASSERT(0);
Chris@10 436 }
Chris@10 437 }
Chris@10 438
Chris@10 439 if (vecsz->rnk == 0 && tensor_unitstridep(sz) && tensor_rowmajorp(sz))
Chris@10 440 goto api_simple;
Chris@10 441
Chris@10 442 if (vecsz->rnk == 1 && expressible_as_api_many(sz))
Chris@10 443 goto api_many;
Chris@10 444
Chris@10 445 goto api_guru;
Chris@10 446
Chris@10 447 api_simple:
Chris@10 448 switch (sz->rnk) {
Chris@10 449 case 1:
Chris@10 450 if (verbose > 2) printf("using plan_r2r_1d\n");
Chris@10 451 pln = FFTW(plan_r2r_1d)(sz->dims[0].n,
Chris@10 452 (bench_real *) p->in,
Chris@10 453 (bench_real *) p->out,
Chris@10 454 k[0], flags);
Chris@10 455 goto done;
Chris@10 456 case 2:
Chris@10 457 if (verbose > 2) printf("using plan_r2r_2d\n");
Chris@10 458 pln = FFTW(plan_r2r_2d)(sz->dims[0].n, sz->dims[1].n,
Chris@10 459 (bench_real *) p->in,
Chris@10 460 (bench_real *) p->out,
Chris@10 461 k[0], k[1], flags);
Chris@10 462 goto done;
Chris@10 463 case 3:
Chris@10 464 if (verbose > 2) printf("using plan_r2r_3d\n");
Chris@10 465 pln = FFTW(plan_r2r_3d)(
Chris@10 466 sz->dims[0].n, sz->dims[1].n, sz->dims[2].n,
Chris@10 467 (bench_real *) p->in, (bench_real *) p->out,
Chris@10 468 k[0], k[1], k[2], flags);
Chris@10 469 goto done;
Chris@10 470 default: {
Chris@10 471 int *n = mkn(sz);
Chris@10 472 if (verbose > 2) printf("using plan_r2r\n");
Chris@10 473 pln = FFTW(plan_r2r)(sz->rnk, n,
Chris@10 474 (bench_real *) p->in, (bench_real *) p->out,
Chris@10 475 k, flags);
Chris@10 476 bench_free(n);
Chris@10 477 goto done;
Chris@10 478 }
Chris@10 479 }
Chris@10 480
Chris@10 481 api_many:
Chris@10 482 {
Chris@10 483 int *n, *inembed, *onembed;
Chris@10 484 BENCH_ASSERT(vecsz->rnk == 1);
Chris@10 485 n = mkn(sz);
Chris@10 486 mknembed_many(sz, &inembed, &onembed);
Chris@10 487 if (verbose > 2) printf("using plan_many_r2r\n");
Chris@10 488 pln = FFTW(plan_many_r2r)(
Chris@10 489 sz->rnk, n, vecsz->dims[0].n,
Chris@10 490 (bench_real *) p->in,
Chris@10 491 inembed, sz->dims[sz->rnk - 1].is, vecsz->dims[0].is,
Chris@10 492 (bench_real *) p->out,
Chris@10 493 onembed, sz->dims[sz->rnk - 1].os, vecsz->dims[0].os,
Chris@10 494 k, flags);
Chris@10 495 bench_free(n); bench_free(inembed); bench_free(onembed);
Chris@10 496 goto done;
Chris@10 497 }
Chris@10 498
Chris@10 499 api_guru:
Chris@10 500 {
Chris@10 501 FFTW(iodim) *dims, *howmany_dims;
Chris@10 502
Chris@10 503 dims = bench_tensor_to_fftw_iodim(sz);
Chris@10 504 howmany_dims = bench_tensor_to_fftw_iodim(vecsz);
Chris@10 505 if (verbose > 2) printf("using plan_guru_r2r\n");
Chris@10 506 pln = FFTW(plan_guru_r2r)(sz->rnk, dims,
Chris@10 507 vecsz->rnk, howmany_dims,
Chris@10 508 (bench_real *) p->in,
Chris@10 509 (bench_real *) p->out, k, flags);
Chris@10 510 bench_free(dims);
Chris@10 511 bench_free(howmany_dims);
Chris@10 512 goto done;
Chris@10 513 }
Chris@10 514
Chris@10 515 done:
Chris@10 516 bench_free(k);
Chris@10 517 return pln;
Chris@10 518 }
Chris@10 519
Chris@10 520 FFTW(plan) mkplan(bench_problem *p, unsigned flags)
Chris@10 521 {
Chris@10 522 switch (p->kind) {
Chris@10 523 case PROBLEM_COMPLEX: return mkplan_complex(p, flags);
Chris@10 524 case PROBLEM_REAL: return mkplan_real(p, flags);
Chris@10 525 case PROBLEM_R2R: return mkplan_r2r(p, flags);
Chris@10 526 default: BENCH_ASSERT(0); return 0;
Chris@10 527 }
Chris@10 528 }
Chris@10 529
Chris@10 530 void main_init(int *argc, char ***argv)
Chris@10 531 {
Chris@10 532 UNUSED(argc);
Chris@10 533 UNUSED(argv);
Chris@10 534 }
Chris@10 535
Chris@10 536 void initial_cleanup(void)
Chris@10 537 {
Chris@10 538 }
Chris@10 539
Chris@10 540 void final_cleanup(void)
Chris@10 541 {
Chris@10 542 }
Chris@10 543
Chris@10 544 int import_wisdom(FILE *f)
Chris@10 545 {
Chris@10 546 return FFTW(import_wisdom_from_file)(f);
Chris@10 547 }
Chris@10 548
Chris@10 549 void export_wisdom(FILE *f)
Chris@10 550 {
Chris@10 551 FFTW(export_wisdom_to_file)(f);
Chris@10 552 }