annotate fft/fftw/fftw-3.3.4/tests/bench.c @ 40:223f770b5341 kissfft-double tip

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