Coverage Report

Created: 2025-08-26 06:35

/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
892
#define tensor_min_xstride(sz, xs) {     \
39
892
     A(FINITE_RNK(sz->rnk));        \
40
892
     if (sz->rnk == 0) return 0;     \
41
892
     else {           \
42
892
          int i;          \
43
892
          INT s = X(iabs)(sz->dims[0].xs);   \
44
892
          for (i = 1; i < sz->rnk; ++i)     \
45
892
               s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \
46
892
          return s;         \
47
892
     }              \
48
892
}
fftw_tensor_min_istride
Line
Count
Source
38
478
#define tensor_min_xstride(sz, xs) {     \
39
478
     A(FINITE_RNK(sz->rnk));        \
40
478
     if (sz->rnk == 0) return 0;     \
41
478
     else {           \
42
478
          int i;          \
43
478
          INT s = X(iabs)(sz->dims[0].xs);   \
44
478
          for (i = 1; i < sz->rnk; ++i)     \
45
478
               s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \
46
478
          return s;         \
47
478
     }              \
48
478
}
fftw_tensor_min_ostride
Line
Count
Source
38
414
#define tensor_min_xstride(sz, xs) {     \
39
414
     A(FINITE_RNK(sz->rnk));        \
40
414
     if (sz->rnk == 0) return 0;     \
41
414
     else {           \
42
414
          int i;          \
43
414
          INT s = X(iabs)(sz->dims[0].xs);   \
44
414
          for (i = 1; i < sz->rnk; ++i)     \
45
414
               s = X(imin)(s, X(iabs)(sz->dims[i].xs)); \
46
414
          return s;         \
47
414
     }              \
48
414
}
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.98k
{
60
2.98k
     int i;
61
2.98k
     A(FINITE_RNK(sz->rnk));
62
3.56k
     for (i = 0; i < sz->rnk; ++i) {
63
2.81k
          const iodim *p = sz->dims + i;
64
2.81k
          if (p->is != p->os)
65
2.23k
               return 0;
66
2.81k
     }
67
750
     return 1;
68
2.98k
}
69
70
int X(tensor_inplace_strides2)(const tensor *a, const tensor *b)
71
2.03k
{
72
2.03k
     return X(tensor_inplace_strides(a)) && X(tensor_inplace_strides(b));
73
2.03k
}
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
340
{
79
340
     if (FINITE_RNK(sz->rnk)) {
80
340
          int i;
81
510
          for (i = 0; i < sz->rnk; ++i)
82
340
               if ((sz->dims[i].os - sz->dims[i].is)
83
340
                   * (k == INPLACE_OS ? (INT)1 : (INT)-1) < 0)
84
170
                    return 1;
85
340
     }
86
170
     return 0;
87
340
}
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
340
{
101
340
     return(tensor_strides_decrease(sz, k)
102
340
      || (X(tensor_inplace_strides)(sz)
103
170
    && tensor_strides_decrease(vecsz, k)));
104
340
}