annotate src/fftw-3.3.8/tools/fftw-wisdom.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 /* Re-use libbench2 and the test program, but override bench_main so that
cannam@167 2 we can have different command-line syntax. */
cannam@167 3 #include "libbench2/my-getopt.h"
cannam@167 4 #include "libbench2/bench.h"
cannam@167 5
cannam@167 6 #include <stdio.h>
cannam@167 7 #include <stdlib.h>
cannam@167 8 #include <ctype.h>
cannam@167 9 #include "api/fftw3.h"
cannam@167 10 #include <string.h>
cannam@167 11 #include <time.h>
cannam@167 12
cannam@167 13 #if defined(HAVE_THREADS) || defined(HAVE_OPENMP)
cannam@167 14 # define HAVE_SMP
cannam@167 15 extern int threads_ok;
cannam@167 16 #endif
cannam@167 17
cannam@167 18 #define CONCAT(prefix, name) prefix ## name
cannam@167 19 #if defined(BENCHFFT_SINGLE)
cannam@167 20 #define FFTW(x) CONCAT(fftwf_, x)
cannam@167 21 #elif defined(BENCHFFT_LDOUBLE)
cannam@167 22 #define FFTW(x) CONCAT(fftwl_, x)
cannam@167 23 #elif defined(BENCHFFT_QUAD)
cannam@167 24 #define FFTW(x) CONCAT(fftwq_, x)
cannam@167 25 #else
cannam@167 26 #define FFTW(x) CONCAT(fftw_, x)
cannam@167 27 #endif
cannam@167 28
cannam@167 29 /* from bench.c: */
cannam@167 30 extern unsigned the_flags;
cannam@167 31 extern int usewisdom;
cannam@167 32 extern int nthreads;
cannam@167 33
cannam@167 34 /* dummy routines to replace those in hook.c */
cannam@167 35 void install_hook(void) {}
cannam@167 36 void uninstall_hook(void) {}
cannam@167 37
cannam@167 38 int verbose;
cannam@167 39
cannam@167 40 static void do_problem(bench_problem *p)
cannam@167 41 {
cannam@167 42 if (verbose)
cannam@167 43 printf("Planning transform: %s\n", p->pstring);
cannam@167 44 /* BENCH_ASSERT(can_do(p)); */
cannam@167 45 problem_alloc(p);
cannam@167 46 setup(p);
cannam@167 47 done(p);
cannam@167 48 }
cannam@167 49
cannam@167 50 static void add_problem(const char *pstring,
cannam@167 51 bench_problem ***p, int *ip, int *np)
cannam@167 52 {
cannam@167 53 if (*ip >= *np) {
cannam@167 54 *np = *np * 2 + 1;
cannam@167 55 *p = (bench_problem **) realloc(*p, sizeof(bench_problem *) * *np);
cannam@167 56 }
cannam@167 57 (*p)[(*ip)++] = problem_parse(pstring);
cannam@167 58 }
cannam@167 59
cannam@167 60 static int sz(const bench_problem *p)
cannam@167 61 {
cannam@167 62 return tensor_sz(p->sz) * tensor_sz(p->vecsz);
cannam@167 63 }
cannam@167 64
cannam@167 65 static int prob_size_cmp(const void *p1_, const void *p2_)
cannam@167 66 {
cannam@167 67 const bench_problem * const *p1 = (const bench_problem * const *) p1_;
cannam@167 68 const bench_problem * const *p2 = (const bench_problem * const *) p2_;
cannam@167 69 return (sz(*p1) - sz(*p2));
cannam@167 70 }
cannam@167 71
cannam@167 72 static struct my_option options[] =
cannam@167 73 {
cannam@167 74 {"help", NOARG, 'h'},
cannam@167 75 {"version", NOARG, 'V'},
cannam@167 76 {"verbose", NOARG, 'v'},
cannam@167 77
cannam@167 78 {"canonical", NOARG, 'c'},
cannam@167 79 {"time-limit", REQARG, 't'},
cannam@167 80
cannam@167 81 {"output-file", REQARG, 'o'},
cannam@167 82
cannam@167 83 {"impatient", NOARG, 'i'},
cannam@167 84 {"measure", NOARG, 'm'},
cannam@167 85 {"estimate", NOARG, 'e'},
cannam@167 86 {"exhaustive", NOARG, 'x'},
cannam@167 87
cannam@167 88 {"no-system-wisdom", NOARG, 'n'},
cannam@167 89 {"wisdom-file", REQARG, 'w'},
cannam@167 90
cannam@167 91 #ifdef HAVE_SMP
cannam@167 92 {"threads", REQARG, 'T'},
cannam@167 93 #endif
cannam@167 94
cannam@167 95 /* options to restrict configuration to rdft-only, etcetera? */
cannam@167 96
cannam@167 97 {0, NOARG, 0}
cannam@167 98 };
cannam@167 99
cannam@167 100 static void help(FILE *f, const char *program_name)
cannam@167 101 {
cannam@167 102 fprintf(
cannam@167 103 f,
cannam@167 104 "Usage: %s [options] [sizes]\n"
cannam@167 105 " Create wisdom (pre-planned/optimized transforms) for specified sizes,\n"
cannam@167 106 " writing wisdom to stdout (or to a file, using -o).\n"
cannam@167 107 "\nOptions:\n"
cannam@167 108 " -h, --help: print this help\n"
cannam@167 109 " -V, --version: print version/copyright info\n"
cannam@167 110 " -v, --verbose: verbose output\n"
cannam@167 111 " -c, --canonical: plan/optimize canonical set of sizes\n"
cannam@167 112 " -t <h>, --time-limit=<h>: time limit in hours (default: 0, no limit)\n"
cannam@167 113 " -o FILE, --output-file=FILE: output to FILE instead of stdout\n"
cannam@167 114 " -m, --measure: plan in MEASURE mode (PATIENT is default)\n"
cannam@167 115 " -e, --estimate: plan in ESTIMATE mode (not recommended)\n"
cannam@167 116 " -x, --exhaustive: plan in EXHAUSTIVE mode (may be slow)\n"
cannam@167 117 " -n, --no-system-wisdom: don't read /etc/fftw/ system wisdom file\n"
cannam@167 118 " -w FILE, --wisdom-file=FILE: read wisdom from FILE (stdin if -)\n"
cannam@167 119 #ifdef HAVE_SMP
cannam@167 120 " -T N, --threads=N: plan with N threads\n"
cannam@167 121 #endif
cannam@167 122 "\nSize syntax: <type><inplace><direction><geometry>\n"
cannam@167 123 " <type> = c/r/k for complex/real(r2c,c2r)/r2r\n"
cannam@167 124 " <inplace> = i/o for in/out-of place\n"
cannam@167 125 " <direction> = f/b for forward/backward, omitted for k transforms\n"
cannam@167 126 " <geometry> = <n1>[x<n2>[x...]], e.g. 10x12x14\n"
cannam@167 127 " -- for k transforms, after each dimension is a <kind>:\n"
cannam@167 128 " <kind> = f/b/h/e00/e01/e10/e11/o00/o01/o10/o11\n"
cannam@167 129 " for R2HC/HC2R/DHT/REDFT00/.../RODFT11\n"
cannam@167 130 , program_name);
cannam@167 131 }
cannam@167 132
cannam@167 133 /* powers of two and ten up to 2^20, for now */
cannam@167 134 static char canonical_sizes[][32] = {
cannam@167 135 "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024",
cannam@167 136 "2048", "4096", "8192", "16384", "32768", "65536", "131072",
cannam@167 137 "262144", "524288", "1048576",
cannam@167 138
cannam@167 139 "10", "100", "1000", "10000", "100000", "1000000",
cannam@167 140
cannam@167 141 "2x2", "4x4", "8x8", "10x10", "16x16", "32x32", "64x64", "100x100",
cannam@167 142 "128x128", "256x256", "512x512", "1000x1000", "1024x1024",
cannam@167 143
cannam@167 144 "2x2x2", "4x4x4", "8x8x8", "10x10x10", "16x16x16", "32x32x32",
cannam@167 145 "64x64x64", "100x100x100"
cannam@167 146 };
cannam@167 147
cannam@167 148 #define NELEM(array)(sizeof(array) / sizeof((array)[0]))
cannam@167 149
cannam@167 150 int bench_main(int argc, char *argv[])
cannam@167 151 {
cannam@167 152 int c;
cannam@167 153 unsigned i;
cannam@167 154 int impatient = 0;
cannam@167 155 int system_wisdom = 1;
cannam@167 156 int canonical = 0;
cannam@167 157 double hours = 0;
cannam@167 158 FILE *output_file;
cannam@167 159 char *output_fname = 0;
cannam@167 160 bench_problem **problems = 0;
cannam@167 161 int nproblems = 0, iproblem = 0;
cannam@167 162 time_t begin;
cannam@167 163
cannam@167 164 verbose = 0;
cannam@167 165 usewisdom = 0;
cannam@167 166
cannam@167 167 bench_srand(1);
cannam@167 168 #ifdef HAVE_SMP
cannam@167 169 /* do not configure FFTW with threads, unless the
cannam@167 170 user requests -T */
cannam@167 171 threads_ok = 0;
cannam@167 172 #endif
cannam@167 173
cannam@167 174 while ((c = my_getopt(argc, argv, options)) != -1) {
cannam@167 175 switch (c) {
cannam@167 176 case 'h':
cannam@167 177 help(stdout, argv[0]);
cannam@167 178 exit(EXIT_SUCCESS);
cannam@167 179 break;
cannam@167 180
cannam@167 181 case 'V':
cannam@167 182 printf("fftw-wisdom tool for FFTW version " VERSION ".\n");
cannam@167 183 printf(
cannam@167 184 "\n"
cannam@167 185 "Copyright (c) 2003, 2007-14 Matteo Frigo\n"
cannam@167 186 "Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology\n"
cannam@167 187 "\n"
cannam@167 188 "This program is free software; you can redistribute it and/or modify\n"
cannam@167 189 "it under the terms of the GNU General Public License as published by\n"
cannam@167 190 "the Free Software Foundation; either version 2 of the License, or\n"
cannam@167 191 "(at your option) any later version.\n"
cannam@167 192 "\n"
cannam@167 193 "This program is distributed in the hope that it will be useful,\n"
cannam@167 194 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
cannam@167 195 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
cannam@167 196 "GNU General Public License for more details.\n"
cannam@167 197 "\n"
cannam@167 198 "You should have received a copy of the GNU General Public License\n"
cannam@167 199 "along with this program; if not, write to the Free Software\n"
cannam@167 200 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
cannam@167 201 );
cannam@167 202 exit(EXIT_SUCCESS);
cannam@167 203 break;
cannam@167 204
cannam@167 205 case 'v':
cannam@167 206 verbose = 1;
cannam@167 207 break;
cannam@167 208
cannam@167 209 case 'c':
cannam@167 210 canonical = 1;
cannam@167 211 break;
cannam@167 212
cannam@167 213 case 't':
cannam@167 214 hours = atof(my_optarg);
cannam@167 215 break;
cannam@167 216
cannam@167 217 case 'o':
cannam@167 218 if (output_fname)
cannam@167 219 bench_free(output_fname);
cannam@167 220
cannam@167 221 if (!strcmp(my_optarg, "-"))
cannam@167 222 output_fname = 0;
cannam@167 223 else {
cannam@167 224 output_fname = (char *) bench_malloc(sizeof(char) *
cannam@167 225 (strlen(my_optarg) + 1));
cannam@167 226 strcpy(output_fname, my_optarg);
cannam@167 227 }
cannam@167 228 break;
cannam@167 229
cannam@167 230 case 'm':
cannam@167 231 case 'i':
cannam@167 232 impatient = 1;
cannam@167 233 break;
cannam@167 234
cannam@167 235 case 'e':
cannam@167 236 the_flags |= FFTW_ESTIMATE;
cannam@167 237 break;
cannam@167 238
cannam@167 239 case 'x':
cannam@167 240 the_flags |= FFTW_EXHAUSTIVE;
cannam@167 241 break;
cannam@167 242
cannam@167 243 case 'n':
cannam@167 244 system_wisdom = 0;
cannam@167 245 break;
cannam@167 246
cannam@167 247 case 'w': {
cannam@167 248 FILE *w = stdin;
cannam@167 249 if (strcmp(my_optarg, "-") && !(w = fopen(my_optarg, "r"))) {
cannam@167 250 fprintf(stderr,
cannam@167 251 "fftw-wisdom: error opening \"%s\": ", my_optarg);
cannam@167 252 perror("");
cannam@167 253 exit(EXIT_FAILURE);
cannam@167 254 }
cannam@167 255 if (!FFTW(import_wisdom_from_file)(w)) {
cannam@167 256 fprintf(stderr, "fftw_wisdom: error reading wisdom "
cannam@167 257 "from \"%s\"\n", my_optarg);
cannam@167 258 exit(EXIT_FAILURE);
cannam@167 259 }
cannam@167 260 if (w != stdin)
cannam@167 261 fclose(w);
cannam@167 262 break;
cannam@167 263 }
cannam@167 264
cannam@167 265 #ifdef HAVE_SMP
cannam@167 266 case 'T':
cannam@167 267 nthreads = atoi(my_optarg);
cannam@167 268 if (nthreads < 1) nthreads = 1;
cannam@167 269 threads_ok = 1;
cannam@167 270 BENCH_ASSERT(FFTW(init_threads)());
cannam@167 271 break;
cannam@167 272 #endif
cannam@167 273
cannam@167 274 case '?':
cannam@167 275 /* `my_getopt' already printed an error message. */
cannam@167 276 cleanup();
cannam@167 277 return EXIT_FAILURE;
cannam@167 278
cannam@167 279 default:
cannam@167 280 abort ();
cannam@167 281 }
cannam@167 282 }
cannam@167 283
cannam@167 284 if (!impatient)
cannam@167 285 the_flags |= FFTW_PATIENT;
cannam@167 286
cannam@167 287 if (system_wisdom)
cannam@167 288 if (!FFTW(import_system_wisdom)() && verbose)
cannam@167 289 fprintf(stderr, "fftw-wisdom: system-wisdom import failed\n");
cannam@167 290
cannam@167 291 if (canonical) {
cannam@167 292 for (i = 0; i < NELEM(canonical_sizes); ++i) {
cannam@167 293 unsigned j;
cannam@167 294 char types[][8] = {
cannam@167 295 "cof", "cob", "cif", "cib", "rof", "rob", "rif", "rib"
cannam@167 296 };
cannam@167 297
cannam@167 298 for (j = 0; j < NELEM(types); ++j) {
cannam@167 299 char ps[64];
cannam@167 300 if (!strchr(canonical_sizes[i],'x')
cannam@167 301 || !strchr(types[j],'o')) {
cannam@167 302 #ifdef HAVE_SNPRINTF
cannam@167 303 snprintf(ps, sizeof(ps), "%s%s", types[j], canonical_sizes[i]);
cannam@167 304 #else
cannam@167 305 sprintf(ps, "%s%s", types[j], canonical_sizes[i]);
cannam@167 306 #endif
cannam@167 307 add_problem(ps, &problems, &iproblem, &nproblems);
cannam@167 308 }
cannam@167 309 }
cannam@167 310 }
cannam@167 311 }
cannam@167 312
cannam@167 313 while (my_optind < argc) {
cannam@167 314 if (!strcmp(argv[my_optind], "-")) {
cannam@167 315 char s[1025];
cannam@167 316 while (1 == fscanf(stdin, "%1024s", s))
cannam@167 317 add_problem(s, &problems, &iproblem, &nproblems);
cannam@167 318 }
cannam@167 319 else
cannam@167 320 add_problem(argv[my_optind], &problems, &iproblem, &nproblems);
cannam@167 321 ++my_optind;
cannam@167 322 }
cannam@167 323
cannam@167 324 nproblems = iproblem;
cannam@167 325 qsort(problems, nproblems, sizeof(bench_problem *), prob_size_cmp);
cannam@167 326
cannam@167 327 if (!output_fname)
cannam@167 328 output_file = stdout;
cannam@167 329 else
cannam@167 330 if (!(output_file = fopen(output_fname, "w"))) {
cannam@167 331 fprintf(stderr,
cannam@167 332 "fftw-wisdom: error creating \"%s\"", output_fname);
cannam@167 333 perror("");
cannam@167 334 exit(EXIT_FAILURE);
cannam@167 335 }
cannam@167 336
cannam@167 337 begin = time((time_t*)0);
cannam@167 338 for (iproblem = 0; iproblem < nproblems; ++iproblem) {
cannam@167 339 if (hours <= 0
cannam@167 340 || hours > (time((time_t*)0) - begin) / 3600.0)
cannam@167 341 do_problem(problems[iproblem]);
cannam@167 342 problem_destroy(problems[iproblem]);
cannam@167 343
cannam@167 344 }
cannam@167 345 free(problems);
cannam@167 346
cannam@167 347 if (verbose && hours > 0
cannam@167 348 && hours < (time((time_t*)0) - begin) / 3600.0)
cannam@167 349 fprintf(stderr, "EXCEEDED TIME LIMIT OF %g HOURS.\n", hours);
cannam@167 350
cannam@167 351 FFTW(export_wisdom_to_file)(output_file);
cannam@167 352 if (output_file != stdout)
cannam@167 353 fclose(output_file);
cannam@167 354 if (output_fname)
cannam@167 355 bench_free(output_fname);
cannam@167 356
cannam@167 357 cleanup();
cannam@167 358
cannam@167 359 return EXIT_SUCCESS;
cannam@167 360 }