annotate src/fftw-3.3.5/libbench2/tensor.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 2cd0e3b3e1fd
children
rev   line source
Chris@42 1 /*
Chris@42 2 * Copyright (c) 2001 Matteo Frigo
Chris@42 3 * Copyright (c) 2001 Massachusetts Institute of Technology
Chris@42 4 *
Chris@42 5 * This program is free software; you can redistribute it and/or modify
Chris@42 6 * it under the terms of the GNU General Public License as published by
Chris@42 7 * the Free Software Foundation; either version 2 of the License, or
Chris@42 8 * (at your option) any later version.
Chris@42 9 *
Chris@42 10 * This program is distributed in the hope that it will be useful,
Chris@42 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@42 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@42 13 * GNU General Public License for more details.
Chris@42 14 *
Chris@42 15 * You should have received a copy of the GNU General Public License
Chris@42 16 * along with this program; if not, write to the Free Software
Chris@42 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@42 18 *
Chris@42 19 */
Chris@42 20
Chris@42 21 #include "bench.h"
Chris@42 22 #include <stdlib.h>
Chris@42 23
Chris@42 24 bench_tensor *mktensor(int rnk)
Chris@42 25 {
Chris@42 26 bench_tensor *x;
Chris@42 27
Chris@42 28 BENCH_ASSERT(rnk >= 0);
Chris@42 29
Chris@42 30 x = (bench_tensor *)bench_malloc(sizeof(bench_tensor));
Chris@42 31 if (BENCH_FINITE_RNK(rnk) && rnk > 0)
Chris@42 32 x->dims = (bench_iodim *)bench_malloc(sizeof(bench_iodim) * rnk);
Chris@42 33 else
Chris@42 34 x->dims = 0;
Chris@42 35
Chris@42 36 x->rnk = rnk;
Chris@42 37 return x;
Chris@42 38 }
Chris@42 39
Chris@42 40 void tensor_destroy(bench_tensor *sz)
Chris@42 41 {
Chris@42 42 bench_free0(sz->dims);
Chris@42 43 bench_free(sz);
Chris@42 44 }
Chris@42 45
Chris@42 46 int tensor_sz(const bench_tensor *sz)
Chris@42 47 {
Chris@42 48 int i, n = 1;
Chris@42 49
Chris@42 50 if (!BENCH_FINITE_RNK(sz->rnk))
Chris@42 51 return 0;
Chris@42 52
Chris@42 53 for (i = 0; i < sz->rnk; ++i)
Chris@42 54 n *= sz->dims[i].n;
Chris@42 55 return n;
Chris@42 56 }
Chris@42 57
Chris@42 58
Chris@42 59 /* total order among bench_iodim's */
Chris@42 60 static int dimcmp(const bench_iodim *a, const bench_iodim *b)
Chris@42 61 {
Chris@42 62 if (b->is != a->is)
Chris@42 63 return (b->is - a->is); /* shorter strides go later */
Chris@42 64 if (b->os != a->os)
Chris@42 65 return (b->os - a->os); /* shorter strides go later */
Chris@42 66 return (int)(a->n - b->n); /* larger n's go later */
Chris@42 67 }
Chris@42 68
Chris@42 69 bench_tensor *tensor_compress(const bench_tensor *sz)
Chris@42 70 {
Chris@42 71 int i, rnk;
Chris@42 72 bench_tensor *x;
Chris@42 73
Chris@42 74 BENCH_ASSERT(BENCH_FINITE_RNK(sz->rnk));
Chris@42 75 for (i = rnk = 0; i < sz->rnk; ++i) {
Chris@42 76 BENCH_ASSERT(sz->dims[i].n > 0);
Chris@42 77 if (sz->dims[i].n != 1)
Chris@42 78 ++rnk;
Chris@42 79 }
Chris@42 80
Chris@42 81 x = mktensor(rnk);
Chris@42 82 for (i = rnk = 0; i < sz->rnk; ++i) {
Chris@42 83 if (sz->dims[i].n != 1)
Chris@42 84 x->dims[rnk++] = sz->dims[i];
Chris@42 85 }
Chris@42 86
Chris@42 87 if (rnk) {
Chris@42 88 /* God knows how qsort() behaves if n==0 */
Chris@42 89 qsort(x->dims, (size_t)x->rnk, sizeof(bench_iodim),
Chris@42 90 (int (*)(const void *, const void *))dimcmp);
Chris@42 91 }
Chris@42 92
Chris@42 93 return x;
Chris@42 94 }
Chris@42 95
Chris@42 96 int tensor_unitstridep(bench_tensor *t)
Chris@42 97 {
Chris@42 98 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@42 99 return (t->rnk == 0 ||
Chris@42 100 (t->dims[t->rnk - 1].is == 1 && t->dims[t->rnk - 1].os == 1));
Chris@42 101 }
Chris@42 102
Chris@42 103 /* detect screwy real padded rowmajor... ugh */
Chris@42 104 int tensor_real_rowmajorp(bench_tensor *t, int sign, int in_place)
Chris@42 105 {
Chris@42 106 int i;
Chris@42 107
Chris@42 108 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@42 109
Chris@42 110 i = t->rnk - 1;
Chris@42 111
Chris@42 112 if (--i >= 0) {
Chris@42 113 bench_iodim *d = t->dims + i;
Chris@42 114 if (sign < 0) {
Chris@42 115 if (d[0].is != d[1].is * (in_place ? 2*(d[1].n/2 + 1) : d[1].n))
Chris@42 116 return 0;
Chris@42 117 if (d[0].os != d[1].os * (d[1].n/2 + 1))
Chris@42 118 return 0;
Chris@42 119 }
Chris@42 120 else {
Chris@42 121 if (d[0].is != d[1].is * (d[1].n/2 + 1))
Chris@42 122 return 0;
Chris@42 123 if (d[0].os != d[1].os * (in_place ? 2*(d[1].n/2 + 1) : d[1].n))
Chris@42 124 return 0;
Chris@42 125 }
Chris@42 126 }
Chris@42 127
Chris@42 128 while (--i >= 0) {
Chris@42 129 bench_iodim *d = t->dims + i;
Chris@42 130 if (d[0].is != d[1].is * d[1].n)
Chris@42 131 return 0;
Chris@42 132 if (d[0].os != d[1].os * d[1].n)
Chris@42 133 return 0;
Chris@42 134 }
Chris@42 135 return 1;
Chris@42 136 }
Chris@42 137
Chris@42 138 int tensor_rowmajorp(bench_tensor *t)
Chris@42 139 {
Chris@42 140 int i;
Chris@42 141
Chris@42 142 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@42 143
Chris@42 144 i = t->rnk - 1;
Chris@42 145 while (--i >= 0) {
Chris@42 146 bench_iodim *d = t->dims + i;
Chris@42 147 if (d[0].is != d[1].is * d[1].n)
Chris@42 148 return 0;
Chris@42 149 if (d[0].os != d[1].os * d[1].n)
Chris@42 150 return 0;
Chris@42 151 }
Chris@42 152 return 1;
Chris@42 153 }
Chris@42 154
Chris@42 155 static void dimcpy(bench_iodim *dst, const bench_iodim *src, int rnk)
Chris@42 156 {
Chris@42 157 int i;
Chris@42 158 if (BENCH_FINITE_RNK(rnk))
Chris@42 159 for (i = 0; i < rnk; ++i)
Chris@42 160 dst[i] = src[i];
Chris@42 161 }
Chris@42 162
Chris@42 163 bench_tensor *tensor_append(const bench_tensor *a, const bench_tensor *b)
Chris@42 164 {
Chris@42 165 if (!BENCH_FINITE_RNK(a->rnk) || !BENCH_FINITE_RNK(b->rnk)) {
Chris@42 166 return mktensor(BENCH_RNK_MINFTY);
Chris@42 167 } else {
Chris@42 168 bench_tensor *x = mktensor(a->rnk + b->rnk);
Chris@42 169 dimcpy(x->dims, a->dims, a->rnk);
Chris@42 170 dimcpy(x->dims + a->rnk, b->dims, b->rnk);
Chris@42 171 return x;
Chris@42 172 }
Chris@42 173 }
Chris@42 174
Chris@42 175 static int imax(int a, int b)
Chris@42 176 {
Chris@42 177 return (a > b) ? a : b;
Chris@42 178 }
Chris@42 179
Chris@42 180 static int imin(int a, int b)
Chris@42 181 {
Chris@42 182 return (a < b) ? a : b;
Chris@42 183 }
Chris@42 184
Chris@42 185 #define DEFBOUNDS(name, xs) \
Chris@42 186 void name(bench_tensor *t, int *lbp, int *ubp) \
Chris@42 187 { \
Chris@42 188 int lb = 0; \
Chris@42 189 int ub = 1; \
Chris@42 190 int i; \
Chris@42 191 \
Chris@42 192 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk)); \
Chris@42 193 \
Chris@42 194 for (i = 0; i < t->rnk; ++i) { \
Chris@42 195 bench_iodim *d = t->dims + i; \
Chris@42 196 int n = d->n; \
Chris@42 197 int s = d->xs; \
Chris@42 198 lb = imin(lb, lb + s * (n - 1)); \
Chris@42 199 ub = imax(ub, ub + s * (n - 1)); \
Chris@42 200 } \
Chris@42 201 \
Chris@42 202 *lbp = lb; \
Chris@42 203 *ubp = ub; \
Chris@42 204 }
Chris@42 205
Chris@42 206 DEFBOUNDS(tensor_ibounds, is)
Chris@42 207 DEFBOUNDS(tensor_obounds, os)
Chris@42 208
Chris@42 209 bench_tensor *tensor_copy(const bench_tensor *sz)
Chris@42 210 {
Chris@42 211 bench_tensor *x = mktensor(sz->rnk);
Chris@42 212 dimcpy(x->dims, sz->dims, sz->rnk);
Chris@42 213 return x;
Chris@42 214 }
Chris@42 215
Chris@42 216 /* Like tensor_copy, but copy only rnk dimensions starting with start_dim. */
Chris@42 217 bench_tensor *tensor_copy_sub(const bench_tensor *sz, int start_dim, int rnk)
Chris@42 218 {
Chris@42 219 bench_tensor *x;
Chris@42 220
Chris@42 221 BENCH_ASSERT(BENCH_FINITE_RNK(sz->rnk) && start_dim + rnk <= sz->rnk);
Chris@42 222 x = mktensor(rnk);
Chris@42 223 dimcpy(x->dims, sz->dims + start_dim, rnk);
Chris@42 224 return x;
Chris@42 225 }
Chris@42 226
Chris@42 227 bench_tensor *tensor_copy_swapio(const bench_tensor *sz)
Chris@42 228 {
Chris@42 229 bench_tensor *x = tensor_copy(sz);
Chris@42 230 int i;
Chris@42 231 if (BENCH_FINITE_RNK(x->rnk))
Chris@42 232 for (i = 0; i < x->rnk; ++i) {
Chris@42 233 int s;
Chris@42 234 s = x->dims[i].is;
Chris@42 235 x->dims[i].is = x->dims[i].os;
Chris@42 236 x->dims[i].os = s;
Chris@42 237 }
Chris@42 238 return x;
Chris@42 239 }