Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
TensorTraits.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_TENSOR_TENSOR_TRAITS_H
12#define EIGEN_TENSOR_TENSOR_TRAITS_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18namespace internal {
19
20template <int Options>
21struct tensor_alignment_for_options {
22 enum {
23 is_dynamic_size_storage = 1,
24
25 value = (((Options & DontAlign) == 0) && (
26#if EIGEN_MAX_STATIC_ALIGN_BYTES > 0
27 (!is_dynamic_size_storage)
28#else
29 0
30#endif
31 |
32#if EIGEN_MAX_ALIGN_BYTES > 0
33 is_dynamic_size_storage
34#else
35 0
36#endif
37 ))
38 };
39};
40
41template <typename Scalar, int Options>
42struct compute_tensor_flags
43 : std::integral_constant<int, packet_traits<Scalar>::Vectorizable && tensor_alignment_for_options<Options>::value
44 ? PacketAccessBit
45 : 0> {};
46
47template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
48struct traits<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > {
49 typedef Scalar_ Scalar;
50 typedef Dense StorageKind;
51 typedef IndexType_ Index;
52 static constexpr int NumDimensions = NumIndices_;
53 static constexpr int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
54 enum {
55 Options = Options_,
56 Flags = compute_tensor_flags<Scalar_, Options_>::value | (std::is_const<Scalar_>::value ? 0 : LvalueBit)
57 };
58 template <typename T>
59 struct MakePointer {
60 typedef T* Type;
61 };
62 typedef typename MakePointer<Scalar>::Type PointerType;
63};
64
65template <typename Scalar_, typename Dimensions, int Options_, typename IndexType_>
66struct traits<TensorFixedSize<Scalar_, Dimensions, Options_, IndexType_> > {
67 typedef Scalar_ Scalar;
68 typedef Dense StorageKind;
69 typedef IndexType_ Index;
70 static constexpr int NumDimensions = array_size<Dimensions>::value;
71 static constexpr int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
72 enum {
73 Options = Options_,
74 Flags = compute_tensor_flags<Scalar_, Options_>::value | (std::is_const<Scalar_>::value ? 0 : LvalueBit)
75 };
76 template <typename T>
77 struct MakePointer {
78 typedef T* Type;
79 };
80 typedef typename MakePointer<Scalar>::Type PointerType;
81};
82
83template <typename PlainObjectType, int Options_, template <class> class MakePointer_>
84struct traits<TensorMap<PlainObjectType, Options_, MakePointer_> > : public traits<PlainObjectType> {
85 typedef traits<PlainObjectType> BaseTraits;
86 typedef typename BaseTraits::Scalar Scalar;
87 typedef typename BaseTraits::StorageKind StorageKind;
88 typedef typename BaseTraits::Index Index;
89 static constexpr int NumDimensions = BaseTraits::NumDimensions;
90 static constexpr int Layout = BaseTraits::Layout;
91 enum { Options = Options_, Flags = BaseTraits::Flags };
92 template <class T>
93 struct MakePointer {
94 typedef typename MakePointer_<T>::Type Type;
95 };
96 typedef typename MakePointer<Scalar>::Type PointerType;
97};
98
99template <typename PlainObjectType_>
100struct traits<TensorRef<PlainObjectType_> > : public traits<PlainObjectType_> {
101 typedef PlainObjectType_ PlainObjectType;
102 typedef traits<PlainObjectType> BaseTraits;
103 typedef typename BaseTraits::Scalar Scalar;
104 typedef typename BaseTraits::StorageKind StorageKind;
105 typedef typename BaseTraits::Index Index;
106 static constexpr int NumDimensions = BaseTraits::NumDimensions;
107 static constexpr int Layout = BaseTraits::Layout;
108 enum { Options = BaseTraits::Options, Flags = BaseTraits::Flags };
109 typedef typename BaseTraits::PointerType PointerType;
110};
111
112template <typename Scalar_, int NumIndices_, int Options, typename IndexType_>
113struct eval<Tensor<Scalar_, NumIndices_, Options, IndexType_>, Eigen::Dense> {
114 typedef const Tensor<Scalar_, NumIndices_, Options, IndexType_> EIGEN_DEVICE_REF type;
115};
116
117template <typename Scalar_, int NumIndices_, int Options, typename IndexType_>
118struct eval<const Tensor<Scalar_, NumIndices_, Options, IndexType_>, Eigen::Dense> {
119 typedef const Tensor<Scalar_, NumIndices_, Options, IndexType_> EIGEN_DEVICE_REF type;
120};
121
122template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
123struct eval<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense> {
124 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> EIGEN_DEVICE_REF type;
125};
126
127template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
128struct eval<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense> {
129 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> EIGEN_DEVICE_REF type;
130};
131
132template <typename PlainObjectType, int Options, template <class> class MakePointer>
133struct eval<TensorMap<PlainObjectType, Options, MakePointer>, Eigen::Dense> {
134 typedef const TensorMap<PlainObjectType, Options, MakePointer> EIGEN_DEVICE_REF type;
135};
136
137template <typename PlainObjectType, int Options, template <class> class MakePointer>
138struct eval<const TensorMap<PlainObjectType, Options, MakePointer>, Eigen::Dense> {
139 typedef const TensorMap<PlainObjectType, Options, MakePointer> EIGEN_DEVICE_REF type;
140};
141
142template <typename PlainObjectType>
143struct eval<TensorRef<PlainObjectType>, Eigen::Dense> {
144 typedef const TensorRef<PlainObjectType> EIGEN_DEVICE_REF type;
145};
146
147template <typename PlainObjectType>
148struct eval<const TensorRef<PlainObjectType>, Eigen::Dense> {
149 typedef const TensorRef<PlainObjectType> EIGEN_DEVICE_REF type;
150};
151
152template <typename T>
153struct tensor_ref_selector {
154 typedef const T EIGEN_DEVICE_REF type;
155 typedef T EIGEN_DEVICE_REF non_const_type;
156};
157
158template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
159struct ref_selector<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
160 : tensor_ref_selector<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > {};
161
162template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
163struct ref_selector<const Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
164 : tensor_ref_selector<const Tensor<Scalar_, NumIndices_, Options_, IndexType_> > {};
165
166template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
167struct ref_selector<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> >
168 : tensor_ref_selector<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> > {};
169
170template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
171struct ref_selector<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> >
172 : tensor_ref_selector<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> > {};
173
174template <typename PlainObjectType>
175struct ref_selector<TensorRef<PlainObjectType> > : tensor_ref_selector<TensorRef<PlainObjectType> > {};
176
177template <typename PlainObjectType>
178struct ref_selector<const TensorRef<PlainObjectType> > : tensor_ref_selector<const TensorRef<PlainObjectType> > {};
179
180} // end namespace internal
181
182// Convolutional layers take in an input tensor of shape (D, R, C, B), or (D, C,
183// R, B), and convolve it with a set of filters, which can also be presented as
184// a tensor (D, K, K, M), where M is the number of filters, K is the filter
185// size, and each 3-dimensional tensor of size (D, K, K) is a filter. For
186// simplicity we assume that we always use square filters (which is usually the
187// case in images), hence the two Ks in the tensor dimension. It also takes in
188// a few additional parameters:
189// Stride (S): The convolution stride is the offset between locations where we
190// apply the filters. A larger stride means that the output will be
191// spatially smaller.
192// Padding (P): The padding we apply to the input tensor along the R and C
193// dimensions. This is usually used to make sure that the spatial
194// dimensions of the output matches our intention.
195//
196// Two types of padding are often used:
197// SAME: The pad value is computed so that the output will have size
198// R/S and C/S.
199// VALID: no padding is carried out.
200// When we do padding, the padded values at the padded locations are usually
201// zero.
202//
203// The output dimensions for convolution, when given all the parameters above,
204// are as follows:
205// When Padding = SAME: the output size is (B, R', C', M), where
206// R' = ceil(float(R) / float(S))
207// C' = ceil(float(C) / float(S))
208// where ceil is the ceiling function. The input tensor is padded with 0 as
209// needed. The number of padded rows and columns are computed as:
210// Pr = ((R' - 1) * S + K - R) / 2
211// Pc = ((C' - 1) * S + K - C) / 2
212// When the stride is 1, we have the simplified case R'=R, C'=C, Pr=Pc=(K-1)/2.
213// This is where SAME comes from - the output has the same size as the input has.
214// When Padding = VALID: the output size is computed as
215// R' = ceil(float(R - K + 1) / float(S))
216// C' = ceil(float(C - K + 1) / float(S))
217// and the number of padded rows and columns are computed in the same way as in
218// the SAME case.
219// When the stride is 1, we have the simplified case R'=R-K+1, C'=C-K+1, Pr=0,
220// Pc=0.
221enum PaddingType { PADDING_VALID = 1, PADDING_SAME = 2 };
222
223} // end namespace Eigen
224
225#endif // EIGEN_TENSOR_TENSOR_TRAITS_H
constexpr unsigned int LvalueBit
Namespace containing all symbols from the Eigen library.