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