annotate src/fftw-3.3.8/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 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 #include "libbench2/bench.h"
Chris@82 22 #include <stdlib.h>
Chris@82 23
Chris@82 24 bench_tensor *mktensor(int rnk)
Chris@82 25 {
Chris@82 26 bench_tensor *x;
Chris@82 27
Chris@82 28 BENCH_ASSERT(rnk >= 0);
Chris@82 29
Chris@82 30 x = (bench_tensor *)bench_malloc(sizeof(bench_tensor));
Chris@82 31 if (BENCH_FINITE_RNK(rnk) && rnk > 0)
Chris@82 32 x->dims = (bench_iodim *)bench_malloc(sizeof(bench_iodim) * rnk);
Chris@82 33 else
Chris@82 34 x->dims = 0;
Chris@82 35
Chris@82 36 x->rnk = rnk;
Chris@82 37 return x;
Chris@82 38 }
Chris@82 39
Chris@82 40 void tensor_destroy(bench_tensor *sz)
Chris@82 41 {
Chris@82 42 bench_free0(sz->dims);
Chris@82 43 bench_free(sz);
Chris@82 44 }
Chris@82 45
Chris@82 46 size_t tensor_sz(const bench_tensor *sz)
Chris@82 47 {
Chris@82 48 int i;
Chris@82 49 size_t n = 1;
Chris@82 50
Chris@82 51 if (!BENCH_FINITE_RNK(sz->rnk))
Chris@82 52 return 0;
Chris@82 53
Chris@82 54 for (i = 0; i < sz->rnk; ++i)
Chris@82 55 n *= sz->dims[i].n;
Chris@82 56 return n;
Chris@82 57 }
Chris@82 58
Chris@82 59
Chris@82 60 /* total order among bench_iodim's */
Chris@82 61 static int dimcmp(const bench_iodim *a, const bench_iodim *b)
Chris@82 62 {
Chris@82 63 if (b->is != a->is)
Chris@82 64 return (b->is - a->is); /* shorter strides go later */
Chris@82 65 if (b->os != a->os)
Chris@82 66 return (b->os - a->os); /* shorter strides go later */
Chris@82 67 return (int)(a->n - b->n); /* larger n's go later */
Chris@82 68 }
Chris@82 69
Chris@82 70 bench_tensor *tensor_compress(const bench_tensor *sz)
Chris@82 71 {
Chris@82 72 int i, rnk;
Chris@82 73 bench_tensor *x;
Chris@82 74
Chris@82 75 BENCH_ASSERT(BENCH_FINITE_RNK(sz->rnk));
Chris@82 76 for (i = rnk = 0; i < sz->rnk; ++i) {
Chris@82 77 BENCH_ASSERT(sz->dims[i].n > 0);
Chris@82 78 if (sz->dims[i].n != 1)
Chris@82 79 ++rnk;
Chris@82 80 }
Chris@82 81
Chris@82 82 x = mktensor(rnk);
Chris@82 83 for (i = rnk = 0; i < sz->rnk; ++i) {
Chris@82 84 if (sz->dims[i].n != 1)
Chris@82 85 x->dims[rnk++] = sz->dims[i];
Chris@82 86 }
Chris@82 87
Chris@82 88 if (rnk) {
Chris@82 89 /* God knows how qsort() behaves if n==0 */
Chris@82 90 qsort(x->dims, (size_t)x->rnk, sizeof(bench_iodim),
Chris@82 91 (int (*)(const void *, const void *))dimcmp);
Chris@82 92 }
Chris@82 93
Chris@82 94 return x;
Chris@82 95 }
Chris@82 96
Chris@82 97 int tensor_unitstridep(bench_tensor *t)
Chris@82 98 {
Chris@82 99 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@82 100 return (t->rnk == 0 ||
Chris@82 101 (t->dims[t->rnk - 1].is == 1 && t->dims[t->rnk - 1].os == 1));
Chris@82 102 }
Chris@82 103
Chris@82 104 /* detect screwy real padded rowmajor... ugh */
Chris@82 105 int tensor_real_rowmajorp(bench_tensor *t, int sign, int in_place)
Chris@82 106 {
Chris@82 107 int i;
Chris@82 108
Chris@82 109 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@82 110
Chris@82 111 i = t->rnk - 1;
Chris@82 112
Chris@82 113 if (--i >= 0) {
Chris@82 114 bench_iodim *d = t->dims + i;
Chris@82 115 if (sign < 0) {
Chris@82 116 if (d[0].is != d[1].is * (in_place ? 2*(d[1].n/2 + 1) : d[1].n))
Chris@82 117 return 0;
Chris@82 118 if (d[0].os != d[1].os * (d[1].n/2 + 1))
Chris@82 119 return 0;
Chris@82 120 }
Chris@82 121 else {
Chris@82 122 if (d[0].is != d[1].is * (d[1].n/2 + 1))
Chris@82 123 return 0;
Chris@82 124 if (d[0].os != d[1].os * (in_place ? 2*(d[1].n/2 + 1) : d[1].n))
Chris@82 125 return 0;
Chris@82 126 }
Chris@82 127 }
Chris@82 128
Chris@82 129 while (--i >= 0) {
Chris@82 130 bench_iodim *d = t->dims + i;
Chris@82 131 if (d[0].is != d[1].is * d[1].n)
Chris@82 132 return 0;
Chris@82 133 if (d[0].os != d[1].os * d[1].n)
Chris@82 134 return 0;
Chris@82 135 }
Chris@82 136 return 1;
Chris@82 137 }
Chris@82 138
Chris@82 139 int tensor_rowmajorp(bench_tensor *t)
Chris@82 140 {
Chris@82 141 int i;
Chris@82 142
Chris@82 143 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk));
Chris@82 144
Chris@82 145 i = t->rnk - 1;
Chris@82 146 while (--i >= 0) {
Chris@82 147 bench_iodim *d = t->dims + i;
Chris@82 148 if (d[0].is != d[1].is * d[1].n)
Chris@82 149 return 0;
Chris@82 150 if (d[0].os != d[1].os * d[1].n)
Chris@82 151 return 0;
Chris@82 152 }
Chris@82 153 return 1;
Chris@82 154 }
Chris@82 155
Chris@82 156 static void dimcpy(bench_iodim *dst, const bench_iodim *src, int rnk)
Chris@82 157 {
Chris@82 158 int i;
Chris@82 159 if (BENCH_FINITE_RNK(rnk))
Chris@82 160 for (i = 0; i < rnk; ++i)
Chris@82 161 dst[i] = src[i];
Chris@82 162 }
Chris@82 163
Chris@82 164 bench_tensor *tensor_append(const bench_tensor *a, const bench_tensor *b)
Chris@82 165 {
Chris@82 166 if (!BENCH_FINITE_RNK(a->rnk) || !BENCH_FINITE_RNK(b->rnk)) {
Chris@82 167 return mktensor(BENCH_RNK_MINFTY);
Chris@82 168 } else {
Chris@82 169 bench_tensor *x = mktensor(a->rnk + b->rnk);
Chris@82 170 dimcpy(x->dims, a->dims, a->rnk);
Chris@82 171 dimcpy(x->dims + a->rnk, b->dims, b->rnk);
Chris@82 172 return x;
Chris@82 173 }
Chris@82 174 }
Chris@82 175
Chris@82 176 static int imax(int a, int b)
Chris@82 177 {
Chris@82 178 return (a > b) ? a : b;
Chris@82 179 }
Chris@82 180
Chris@82 181 static int imin(int a, int b)
Chris@82 182 {
Chris@82 183 return (a < b) ? a : b;
Chris@82 184 }
Chris@82 185
Chris@82 186 #define DEFBOUNDS(name, xs) \
Chris@82 187 void name(bench_tensor *t, int *lbp, int *ubp) \
Chris@82 188 { \
Chris@82 189 int lb = 0; \
Chris@82 190 int ub = 1; \
Chris@82 191 int i; \
Chris@82 192 \
Chris@82 193 BENCH_ASSERT(BENCH_FINITE_RNK(t->rnk)); \
Chris@82 194 \
Chris@82 195 for (i = 0; i < t->rnk; ++i) { \
Chris@82 196 bench_iodim *d = t->dims + i; \
Chris@82 197 int n = d->n; \
Chris@82 198 int s = d->xs; \
Chris@82 199 lb = imin(lb, lb + s * (n - 1)); \
Chris@82 200 ub = imax(ub, ub + s * (n - 1)); \
Chris@82 201 } \
Chris@82 202 \
Chris@82 203 *lbp = lb; \
Chris@82 204 *ubp = ub; \
Chris@82 205 }
Chris@82 206
Chris@82 207 DEFBOUNDS(tensor_ibounds, is)
Chris@82 208 DEFBOUNDS(tensor_obounds, os)
Chris@82 209
Chris@82 210 bench_tensor *tensor_copy(const bench_tensor *sz)
Chris@82 211 {
Chris@82 212 bench_tensor *x = mktensor(sz->rnk);
Chris@82 213 dimcpy(x->dims, sz->dims, sz->rnk);
Chris@82 214 return x;
Chris@82 215 }
Chris@82 216
Chris@82 217 /* Like tensor_copy, but copy only rnk dimensions starting with start_dim. */
Chris@82 218 bench_tensor *tensor_copy_sub(const bench_tensor *sz, int start_dim, int rnk)
Chris@82 219 {
Chris@82 220 bench_tensor *x;
Chris@82 221
Chris@82 222 BENCH_ASSERT(BENCH_FINITE_RNK(sz->rnk) && start_dim + rnk <= sz->rnk);
Chris@82 223 x = mktensor(rnk);
Chris@82 224 dimcpy(x->dims, sz->dims + start_dim, rnk);
Chris@82 225 return x;
Chris@82 226 }
Chris@82 227
Chris@82 228 bench_tensor *tensor_copy_swapio(const bench_tensor *sz)
Chris@82 229 {
Chris@82 230 bench_tensor *x = tensor_copy(sz);
Chris@82 231 int i;
Chris@82 232 if (BENCH_FINITE_RNK(x->rnk))
Chris@82 233 for (i = 0; i < x->rnk; ++i) {
Chris@82 234 int s;
Chris@82 235 s = x->dims[i].is;
Chris@82 236 x->dims[i].is = x->dims[i].os;
Chris@82 237 x->dims[i].os = s;
Chris@82 238 }
Chris@82 239 return x;
Chris@82 240 }