annotate src/fftw-3.3.8/libbench2/problem.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 d0c2a83c1364
children
rev   line source
Chris@82 1 /*
Chris@82 2 * Copyright (c) 2001 Matteo Frigo
Chris@82 3 * Copyright (c) 2001 Massachusetts Institute of Technology
Chris@82 4 *
Chris@82 5 * This program is free software; you can redistribute it and/or modify
Chris@82 6 * it under the terms of the GNU General Public License as published by
Chris@82 7 * the Free Software Foundation; either version 2 of the License, or
Chris@82 8 * (at your option) any later version.
Chris@82 9 *
Chris@82 10 * This program is distributed in the hope that it will be useful,
Chris@82 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@82 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@82 13 * GNU General Public License for more details.
Chris@82 14 *
Chris@82 15 * You should have received a copy of the GNU General Public License
Chris@82 16 * along with this program; if not, write to the Free Software
Chris@82 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@82 18 *
Chris@82 19 */
Chris@82 20
Chris@82 21
Chris@82 22 #include "config.h"
Chris@82 23 #include "libbench2/bench.h"
Chris@82 24 #include <stdio.h>
Chris@82 25 #include <stdlib.h>
Chris@82 26 #include <string.h>
Chris@82 27 #include <ctype.h>
Chris@82 28
Chris@82 29 int always_pad_real = 0; /* by default, only pad in-place case */
Chris@82 30
Chris@82 31 typedef enum {
Chris@82 32 SAME, PADDED, HALFISH
Chris@82 33 } n_transform;
Chris@82 34
Chris@82 35 /* funny transformations for last dimension of PROBLEM_REAL */
Chris@82 36 static int transform_n(int n, n_transform nt)
Chris@82 37 {
Chris@82 38 switch (nt) {
Chris@82 39 case SAME: return n;
Chris@82 40 case PADDED: return 2*(n/2+1);
Chris@82 41 case HALFISH: return (n/2+1);
Chris@82 42 default: BENCH_ASSERT(0); return 0;
Chris@82 43 }
Chris@82 44 }
Chris@82 45
Chris@82 46 /* do what I mean */
Chris@82 47 static bench_tensor *dwim(bench_tensor *t, bench_iodim **last_iodim,
Chris@82 48 n_transform nti, n_transform nto,
Chris@82 49 bench_iodim *dt)
Chris@82 50 {
Chris@82 51 int i;
Chris@82 52 bench_iodim *d, *d1;
Chris@82 53
Chris@82 54 if (!BENCH_FINITE_RNK(t->rnk) || t->rnk < 1)
Chris@82 55 return t;
Chris@82 56
Chris@82 57 i = t->rnk;
Chris@82 58 d1 = *last_iodim;
Chris@82 59
Chris@82 60 while (--i >= 0) {
Chris@82 61 d = t->dims + i;
Chris@82 62 if (!d->is)
Chris@82 63 d->is = d1->is * transform_n(d1->n, d1==dt ? nti : SAME);
Chris@82 64 if (!d->os)
Chris@82 65 d->os = d1->os * transform_n(d1->n, d1==dt ? nto : SAME);
Chris@82 66 d1 = d;
Chris@82 67 }
Chris@82 68
Chris@82 69 *last_iodim = d1;
Chris@82 70 return t;
Chris@82 71 }
Chris@82 72
Chris@82 73 static void transpose_tensor(bench_tensor *t)
Chris@82 74 {
Chris@82 75 if (!BENCH_FINITE_RNK(t->rnk) || t->rnk < 2)
Chris@82 76 return;
Chris@82 77
Chris@82 78 t->dims[0].os = t->dims[1].os;
Chris@82 79 t->dims[1].os = t->dims[0].os * t->dims[0].n;
Chris@82 80 }
Chris@82 81
Chris@82 82 static const char *parseint(const char *s, int *n)
Chris@82 83 {
Chris@82 84 int sign = 1;
Chris@82 85
Chris@82 86 *n = 0;
Chris@82 87
Chris@82 88 if (*s == '-') {
Chris@82 89 sign = -1;
Chris@82 90 ++s;
Chris@82 91 } else if (*s == '+') {
Chris@82 92 sign = +1;
Chris@82 93 ++s;
Chris@82 94 }
Chris@82 95
Chris@82 96 BENCH_ASSERT(isdigit(*s));
Chris@82 97 while (isdigit(*s)) {
Chris@82 98 *n = *n * 10 + (*s - '0');
Chris@82 99 ++s;
Chris@82 100 }
Chris@82 101
Chris@82 102 *n *= sign;
Chris@82 103
Chris@82 104 if (*s == 'k' || *s == 'K') {
Chris@82 105 *n *= 1024;
Chris@82 106 ++s;
Chris@82 107 }
Chris@82 108
Chris@82 109 if (*s == 'm' || *s == 'M') {
Chris@82 110 *n *= 1024 * 1024;
Chris@82 111 ++s;
Chris@82 112 }
Chris@82 113
Chris@82 114 return s;
Chris@82 115 }
Chris@82 116
Chris@82 117 struct dimlist { bench_iodim car; r2r_kind_t k; struct dimlist *cdr; };
Chris@82 118
Chris@82 119 static const char *parsetensor(const char *s, bench_tensor **tp,
Chris@82 120 r2r_kind_t **k)
Chris@82 121 {
Chris@82 122 struct dimlist *l = 0, *m;
Chris@82 123 bench_tensor *t;
Chris@82 124 int rnk = 0;
Chris@82 125
Chris@82 126 L1:
Chris@82 127 m = (struct dimlist *)bench_malloc(sizeof(struct dimlist));
Chris@82 128 /* nconc onto l */
Chris@82 129 m->cdr = l; l = m;
Chris@82 130 ++rnk;
Chris@82 131
Chris@82 132 s = parseint(s, &m->car.n);
Chris@82 133
Chris@82 134 if (*s == ':') {
Chris@82 135 /* read input stride */
Chris@82 136 ++s;
Chris@82 137 s = parseint(s, &m->car.is);
Chris@82 138 if (*s == ':') {
Chris@82 139 /* read output stride */
Chris@82 140 ++s;
Chris@82 141 s = parseint(s, &m->car.os);
Chris@82 142 } else {
Chris@82 143 /* default */
Chris@82 144 m->car.os = m->car.is;
Chris@82 145 }
Chris@82 146 } else {
Chris@82 147 m->car.is = 0;
Chris@82 148 m->car.os = 0;
Chris@82 149 }
Chris@82 150
Chris@82 151 if (*s == 'f' || *s == 'F') {
Chris@82 152 m->k = R2R_R2HC;
Chris@82 153 ++s;
Chris@82 154 }
Chris@82 155 else if (*s == 'b' || *s == 'B') {
Chris@82 156 m->k = R2R_HC2R;
Chris@82 157 ++s;
Chris@82 158 }
Chris@82 159 else if (*s == 'h' || *s == 'H') {
Chris@82 160 m->k = R2R_DHT;
Chris@82 161 ++s;
Chris@82 162 }
Chris@82 163 else if (*s == 'e' || *s == 'E' || *s == 'o' || *s == 'O') {
Chris@82 164 char c = *(s++);
Chris@82 165 int ab;
Chris@82 166
Chris@82 167 s = parseint(s, &ab);
Chris@82 168
Chris@82 169 if (c == 'e' || c == 'E') {
Chris@82 170 if (ab == 0)
Chris@82 171 m->k = R2R_REDFT00;
Chris@82 172 else if (ab == 1)
Chris@82 173 m->k = R2R_REDFT01;
Chris@82 174 else if (ab == 10)
Chris@82 175 m->k = R2R_REDFT10;
Chris@82 176 else if (ab == 11)
Chris@82 177 m->k = R2R_REDFT11;
Chris@82 178 else
Chris@82 179 BENCH_ASSERT(0);
Chris@82 180 }
Chris@82 181 else {
Chris@82 182 if (ab == 0)
Chris@82 183 m->k = R2R_RODFT00;
Chris@82 184 else if (ab == 1)
Chris@82 185 m->k = R2R_RODFT01;
Chris@82 186 else if (ab == 10)
Chris@82 187 m->k = R2R_RODFT10;
Chris@82 188 else if (ab == 11)
Chris@82 189 m->k = R2R_RODFT11;
Chris@82 190 else
Chris@82 191 BENCH_ASSERT(0);
Chris@82 192 }
Chris@82 193 }
Chris@82 194 else
Chris@82 195 m->k = R2R_R2HC;
Chris@82 196
Chris@82 197 if (*s == 'x' || *s == 'X') {
Chris@82 198 ++s;
Chris@82 199 goto L1;
Chris@82 200 }
Chris@82 201
Chris@82 202 /* now we have a dimlist. Build bench_tensor, etc. */
Chris@82 203
Chris@82 204 if (k && rnk > 0) {
Chris@82 205 int i;
Chris@82 206 *k = (r2r_kind_t *) bench_malloc(sizeof(r2r_kind_t) * rnk);
Chris@82 207 for (m = l, i = rnk - 1; i >= 0; --i, m = m->cdr) {
Chris@82 208 BENCH_ASSERT(m);
Chris@82 209 (*k)[i] = m->k;
Chris@82 210 }
Chris@82 211 }
Chris@82 212
Chris@82 213 t = mktensor(rnk);
Chris@82 214 while (--rnk >= 0) {
Chris@82 215 bench_iodim *d = t->dims + rnk;
Chris@82 216 BENCH_ASSERT(l);
Chris@82 217 m = l; l = m->cdr;
Chris@82 218 d->n = m->car.n;
Chris@82 219 d->is = m->car.is;
Chris@82 220 d->os = m->car.os;
Chris@82 221 bench_free(m);
Chris@82 222 }
Chris@82 223
Chris@82 224 *tp = t;
Chris@82 225 return s;
Chris@82 226 }
Chris@82 227
Chris@82 228 /* parse a problem description, return a problem */
Chris@82 229 bench_problem *problem_parse(const char *s)
Chris@82 230 {
Chris@82 231 bench_problem *p;
Chris@82 232 bench_iodim last_iodim0 = {1,1,1}, *last_iodim = &last_iodim0;
Chris@82 233 bench_iodim *sz_last_iodim;
Chris@82 234 bench_tensor *sz;
Chris@82 235 n_transform nti = SAME, nto = SAME;
Chris@82 236 int transpose = 0;
Chris@82 237
Chris@82 238 p = (bench_problem *) bench_malloc(sizeof(bench_problem));
Chris@82 239 p->kind = PROBLEM_COMPLEX;
Chris@82 240 p->k = 0;
Chris@82 241 p->sign = -1;
Chris@82 242 p->in = p->out = 0;
Chris@82 243 p->inphys = p->outphys = 0;
Chris@82 244 p->iphyssz = p->ophyssz = 0;
Chris@82 245 p->in_place = 0;
Chris@82 246 p->destroy_input = 0;
Chris@82 247 p->split = 0;
Chris@82 248 p->userinfo = 0;
Chris@82 249 p->scrambled_in = p->scrambled_out = 0;
Chris@82 250 p->sz = p->vecsz = 0;
Chris@82 251 p->ini = p->outi = 0;
Chris@82 252 p->pstring = (char *) bench_malloc(sizeof(char) * (strlen(s) + 1));
Chris@82 253 strcpy(p->pstring, s);
Chris@82 254
Chris@82 255 L1:
Chris@82 256 switch (tolower(*s)) {
Chris@82 257 case 'i': p->in_place = 1; ++s; goto L1;
Chris@82 258 case 'o': p->in_place = 0; ++s; goto L1;
Chris@82 259 case 'd': p->destroy_input = 1; ++s; goto L1;
Chris@82 260 case '/': p->split = 1; ++s; goto L1;
Chris@82 261 case 'f':
Chris@82 262 case '-': p->sign = -1; ++s; goto L1;
Chris@82 263 case 'b':
Chris@82 264 case '+': p->sign = 1; ++s; goto L1;
Chris@82 265 case 'r': p->kind = PROBLEM_REAL; ++s; goto L1;
Chris@82 266 case 'c': p->kind = PROBLEM_COMPLEX; ++s; goto L1;
Chris@82 267 case 'k': p->kind = PROBLEM_R2R; ++s; goto L1;
Chris@82 268 case 't': transpose = 1; ++s; goto L1;
Chris@82 269
Chris@82 270 /* hack for MPI: */
Chris@82 271 case '[': p->scrambled_in = 1; ++s; goto L1;
Chris@82 272 case ']': p->scrambled_out = 1; ++s; goto L1;
Chris@82 273
Chris@82 274 default : ;
Chris@82 275 }
Chris@82 276
Chris@82 277 s = parsetensor(s, &sz, p->kind == PROBLEM_R2R ? &p->k : 0);
Chris@82 278
Chris@82 279 if (p->kind == PROBLEM_REAL) {
Chris@82 280 if (p->sign < 0) {
Chris@82 281 nti = p->in_place || always_pad_real ? PADDED : SAME;
Chris@82 282 nto = HALFISH;
Chris@82 283 }
Chris@82 284 else {
Chris@82 285 nti = HALFISH;
Chris@82 286 nto = p->in_place || always_pad_real ? PADDED : SAME;
Chris@82 287 }
Chris@82 288 }
Chris@82 289
Chris@82 290 sz_last_iodim = sz->dims + sz->rnk - 1;
Chris@82 291 if (*s == '*') { /* "external" vector */
Chris@82 292 ++s;
Chris@82 293 p->sz = dwim(sz, &last_iodim, nti, nto, sz_last_iodim);
Chris@82 294 s = parsetensor(s, &sz, 0);
Chris@82 295 p->vecsz = dwim(sz, &last_iodim, nti, nto, sz_last_iodim);
Chris@82 296 } else if (*s == 'v' || *s == 'V') { /* "internal" vector */
Chris@82 297 bench_tensor *vecsz;
Chris@82 298 ++s;
Chris@82 299 s = parsetensor(s, &vecsz, 0);
Chris@82 300 p->vecsz = dwim(vecsz, &last_iodim, nti, nto, sz_last_iodim);
Chris@82 301 p->sz = dwim(sz, &last_iodim, nti, nto, sz_last_iodim);
Chris@82 302 } else {
Chris@82 303 p->sz = dwim(sz, &last_iodim, nti, nto, sz_last_iodim);
Chris@82 304 p->vecsz = mktensor(0);
Chris@82 305 }
Chris@82 306
Chris@82 307 if (transpose) {
Chris@82 308 transpose_tensor(p->sz);
Chris@82 309 transpose_tensor(p->vecsz);
Chris@82 310 }
Chris@82 311
Chris@82 312 if (!p->in_place)
Chris@82 313 p->out = ((bench_real *) p->in) + (1 << 20); /* whatever */
Chris@82 314
Chris@82 315 BENCH_ASSERT(p->sz && p->vecsz);
Chris@82 316 BENCH_ASSERT(!*s);
Chris@82 317 return p;
Chris@82 318 }
Chris@82 319
Chris@82 320 void problem_destroy(bench_problem *p)
Chris@82 321 {
Chris@82 322 BENCH_ASSERT(p);
Chris@82 323 problem_free(p);
Chris@82 324 bench_free0(p->k);
Chris@82 325 bench_free0(p->pstring);
Chris@82 326 bench_free(p);
Chris@82 327 }
Chris@82 328