annotate src/fftw-3.3.8/libbench2/tensor.c @ 82:d0c2a83c1364

Add FFTW 3.3.8 source, and a Linux build
author Chris Cannam
date Tue, 19 Nov 2019 14:52:55 +0000
parents
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 }