/src/fftw3/kernel/tensor4.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2003, 2007-14 Matteo Frigo |
3 | | * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology |
4 | | * |
5 | | * This program is free software; you can redistribute it and/or modify |
6 | | * it under the terms of the GNU General Public License as published by |
7 | | * the Free Software Foundation; either version 2 of the License, or |
8 | | * (at your option) any later version. |
9 | | * |
10 | | * This program is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | * GNU General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU General Public License |
16 | | * along with this program; if not, write to the Free Software |
17 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | | * |
19 | | */ |
20 | | |
21 | | |
22 | | #include "kernel/ifftw.h" |
23 | | |
24 | | INT X(tensor_max_index)(const tensor *sz) |
25 | 0 | { |
26 | 0 | int i; |
27 | 0 | INT ni = 0, no = 0; |
28 | |
|
29 | 0 | A(FINITE_RNK(sz->rnk)); |
30 | 0 | for (i = 0; i < sz->rnk; ++i) { |
31 | 0 | const iodim *p = sz->dims + i; |
32 | 0 | ni += (p->n - 1) * X(iabs)(p->is); |
33 | 0 | no += (p->n - 1) * X(iabs)(p->os); |
34 | 0 | } |
35 | 0 | return X(imax)(ni, no); |
36 | 0 | } |
37 | | |
38 | 876 | #define tensor_min_xstride(sz, xs) { \ |
39 | 876 | A(FINITE_RNK(sz->rnk)); \ |
40 | 876 | if (sz->rnk == 0) return 0; \ |
41 | 876 | else { \ |
42 | 876 | int i; \ |
43 | 876 | INT s = X(iabs)(sz->dims[0].xs); \ |
44 | 876 | for (i = 1; i < sz->rnk; ++i) \ |
45 | 876 | s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \ |
46 | 876 | return s; \ |
47 | 876 | } \ |
48 | 876 | } Line | Count | Source | 38 | 470 | #define tensor_min_xstride(sz, xs) { \ | 39 | 470 | A(FINITE_RNK(sz->rnk)); \ | 40 | 470 | if (sz->rnk == 0) return 0; \ | 41 | 470 | else { \ | 42 | 470 | int i; \ | 43 | 470 | INT s = X(iabs)(sz->dims[0].xs); \ | 44 | 470 | for (i = 1; i < sz->rnk; ++i) \ | 45 | 470 | s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \ | 46 | 470 | return s; \ | 47 | 470 | } \ | 48 | 470 | } |
Line | Count | Source | 38 | 406 | #define tensor_min_xstride(sz, xs) { \ | 39 | 406 | A(FINITE_RNK(sz->rnk)); \ | 40 | 406 | if (sz->rnk == 0) return 0; \ | 41 | 406 | else { \ | 42 | 406 | int i; \ | 43 | 406 | INT s = X(iabs)(sz->dims[0].xs); \ | 44 | 406 | for (i = 1; i < sz->rnk; ++i) \ | 45 | 406 | s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \ | 46 | 406 | return s; \ | 47 | 406 | } \ | 48 | 406 | } |
|
49 | | |
50 | | INT X(tensor_min_istride)(const tensor *sz) tensor_min_xstride(sz, is) |
51 | | INT X(tensor_min_ostride)(const tensor *sz) tensor_min_xstride(sz, os) |
52 | | |
53 | | INT X(tensor_min_stride)(const tensor *sz) |
54 | 0 | { |
55 | 0 | return X(imin)(X(tensor_min_istride)(sz), X(tensor_min_ostride)(sz)); |
56 | 0 | } |
57 | | |
58 | | int X(tensor_inplace_strides)(const tensor *sz) |
59 | 2.94k | { |
60 | 2.94k | int i; |
61 | 2.94k | A(FINITE_RNK(sz->rnk)); |
62 | 3.51k | for (i = 0; i < sz->rnk; ++i) { |
63 | 2.77k | const iodim *p = sz->dims + i; |
64 | 2.77k | if (p->is != p->os) |
65 | 2.19k | return 0; |
66 | 2.77k | } |
67 | 745 | return 1; |
68 | 2.94k | } |
69 | | |
70 | | int X(tensor_inplace_strides2)(const tensor *a, const tensor *b) |
71 | 2.00k | { |
72 | 2.00k | return X(tensor_inplace_strides(a)) && X(tensor_inplace_strides(b)); |
73 | 2.00k | } |
74 | | |
75 | | /* return true (1) iff *any* strides of sz decrease when we |
76 | | tensor_inplace_copy(sz, k). */ |
77 | | static int tensor_strides_decrease(const tensor *sz, inplace_kind k) |
78 | 334 | { |
79 | 334 | if (FINITE_RNK(sz->rnk)) { |
80 | 334 | int i; |
81 | 501 | for (i = 0; i < sz->rnk; ++i) |
82 | 334 | if ((sz->dims[i].os - sz->dims[i].is) |
83 | 334 | * (k == INPLACE_OS ? (INT)1 : (INT)-1) < 0) |
84 | 167 | return 1; |
85 | 334 | } |
86 | 167 | return 0; |
87 | 334 | } |
88 | | |
89 | | /* Return true (1) iff *any* strides of sz decrease when we |
90 | | tensor_inplace_copy(k) *or* if *all* strides of sz are unchanged |
91 | | but *any* strides of vecsz decrease. This is used in indirect.c |
92 | | to determine whether to use INPLACE_IS or INPLACE_OS. |
93 | | |
94 | | Note: X(tensor_strides_decrease)(sz, vecsz, INPLACE_IS) |
95 | | || X(tensor_strides_decrease)(sz, vecsz, INPLACE_OS) |
96 | | || X(tensor_inplace_strides2)(p->sz, p->vecsz) |
97 | | must always be true. */ |
98 | | int X(tensor_strides_decrease)(const tensor *sz, const tensor *vecsz, |
99 | | inplace_kind k) |
100 | 334 | { |
101 | 334 | return(tensor_strides_decrease(sz, k) |
102 | 334 | || (X(tensor_inplace_strides)(sz) |
103 | 167 | && tensor_strides_decrease(vecsz, k))); |
104 | 334 | } |