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