Coverage Report

Created: 2025-07-23 07:03

/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
}
fftw_tensor_min_istride
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
}
fftw_tensor_min_ostride
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
}