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