annotate src/fftw-3.3.3/tests/bench.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 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 }