![]() |
Eigen-unsupported
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_TRAITS_H 00011 #define EIGEN_CXX11_TENSOR_TENSOR_TRAITS_H 00012 00013 namespace Eigen { 00014 namespace internal { 00015 00016 00017 template<typename Scalar, int Options> 00018 class compute_tensor_flags 00019 { 00020 enum { 00021 is_dynamic_size_storage = 1, 00022 00023 is_aligned = 00024 ( 00025 ((Options&DontAlign)==0) && ( 00026 #if EIGEN_MAX_STATIC_ALIGN_BYTES>0 00027 (!is_dynamic_size_storage) 00028 #else 00029 0 00030 #endif 00031 | 00032 #if EIGEN_MAX_ALIGN_BYTES>0 00033 is_dynamic_size_storage 00034 #else 00035 0 00036 #endif 00037 ) 00038 ), 00039 packet_access_bit = packet_traits<Scalar>::Vectorizable && is_aligned ? PacketAccessBit : 0 00040 }; 00041 00042 public: 00043 enum { ret = packet_access_bit }; 00044 }; 00045 00046 00047 template<typename Scalar_, int NumIndices_, int Options_, typename IndexType_> 00048 struct traits<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > 00049 { 00050 typedef Scalar_ Scalar; 00051 typedef Dense StorageKind; 00052 typedef IndexType_ Index; 00053 static const int NumDimensions = NumIndices_; 00054 static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor; 00055 enum { 00056 Options = Options_, 00057 Flags = compute_tensor_flags<Scalar_, Options_>::ret | (is_const<Scalar_>::value ? 0 : LvalueBit) 00058 }; 00059 template <typename T> struct MakePointer { 00060 typedef T* Type; 00061 }; 00062 }; 00063 00064 00065 template<typename Scalar_, typename Dimensions, int Options_, typename IndexType_> 00066 struct traits<TensorFixedSize<Scalar_, Dimensions, Options_, IndexType_> > 00067 { 00068 typedef Scalar_ Scalar; 00069 typedef Dense StorageKind; 00070 typedef IndexType_ Index; 00071 static const int NumDimensions = array_size<Dimensions>::value; 00072 static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor; 00073 enum { 00074 Options = Options_, 00075 Flags = compute_tensor_flags<Scalar_, Options_>::ret | (is_const<Scalar_>::value ? 0: LvalueBit) 00076 }; 00077 template <typename T> struct MakePointer { 00078 typedef T* Type; 00079 }; 00080 }; 00081 00082 00083 template<typename PlainObjectType, int Options_, template <class> class MakePointer_> 00084 struct traits<TensorMap<PlainObjectType, Options_, MakePointer_> > 00085 : public traits<PlainObjectType> 00086 { 00087 typedef traits<PlainObjectType> BaseTraits; 00088 typedef typename BaseTraits::Scalar Scalar; 00089 typedef typename BaseTraits::StorageKind StorageKind; 00090 typedef typename BaseTraits::Index Index; 00091 static const int NumDimensions = BaseTraits::NumDimensions; 00092 static const int Layout = BaseTraits::Layout; 00093 enum { 00094 Options = Options_, 00095 Flags = BaseTraits::Flags 00096 }; 00097 template <class T> struct MakePointer { 00098 // Intermediate typedef to workaround MSVC issue. 00099 typedef MakePointer_<T> MakePointerT; 00100 typedef typename MakePointerT::Type Type; 00101 }; 00102 }; 00103 00104 template<typename PlainObjectType> 00105 struct traits<TensorRef<PlainObjectType> > 00106 : public traits<PlainObjectType> 00107 { 00108 typedef traits<PlainObjectType> BaseTraits; 00109 typedef typename BaseTraits::Scalar Scalar; 00110 typedef typename BaseTraits::StorageKind StorageKind; 00111 typedef typename BaseTraits::Index Index; 00112 static const int NumDimensions = BaseTraits::NumDimensions; 00113 static const int Layout = BaseTraits::Layout; 00114 enum { 00115 Options = BaseTraits::Options, 00116 Flags = BaseTraits::Flags 00117 }; 00118 }; 00119 00120 00121 template<typename _Scalar, int NumIndices_, int Options, typename IndexType_> 00122 struct eval<Tensor<_Scalar, NumIndices_, Options, IndexType_>, Eigen::Dense> 00123 { 00124 typedef const Tensor<_Scalar, NumIndices_, Options, IndexType_>& type; 00125 }; 00126 00127 template<typename _Scalar, int NumIndices_, int Options, typename IndexType_> 00128 struct eval<const Tensor<_Scalar, NumIndices_, Options, IndexType_>, Eigen::Dense> 00129 { 00130 typedef const Tensor<_Scalar, NumIndices_, Options, IndexType_>& type; 00131 }; 00132 00133 template<typename Scalar_, typename Dimensions, int Options, typename IndexType_> 00134 struct eval<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense> 00135 { 00136 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type; 00137 }; 00138 00139 template<typename Scalar_, typename Dimensions, int Options, typename IndexType_> 00140 struct eval<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense> 00141 { 00142 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type; 00143 }; 00144 00145 template<typename PlainObjectType, int Options, template <class> class MakePointer> 00146 struct eval<TensorMap<PlainObjectType, Options, MakePointer>, Eigen::Dense> 00147 { 00148 typedef const TensorMap<PlainObjectType, Options, MakePointer>& type; 00149 }; 00150 00151 template<typename PlainObjectType, int Options, template <class> class MakePointer> 00152 struct eval<const TensorMap<PlainObjectType, Options, MakePointer>, Eigen::Dense> 00153 { 00154 typedef const TensorMap<PlainObjectType, Options, MakePointer>& type; 00155 }; 00156 00157 template<typename PlainObjectType> 00158 struct eval<TensorRef<PlainObjectType>, Eigen::Dense> 00159 { 00160 typedef const TensorRef<PlainObjectType>& type; 00161 }; 00162 00163 template<typename PlainObjectType> 00164 struct eval<const TensorRef<PlainObjectType>, Eigen::Dense> 00165 { 00166 typedef const TensorRef<PlainObjectType>& type; 00167 }; 00168 00169 // TODO nested<> does not exist anymore in Eigen/Core, and it thus has to be removed in favor of ref_selector. 00170 template<typename T, int n=1, typename PlainObject = void> struct nested 00171 { 00172 typedef typename ref_selector<T>::type type; 00173 }; 00174 00175 template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_> 00176 struct nested<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > 00177 { 00178 typedef const Tensor<Scalar_, NumIndices_, Options_, IndexType_>& type; 00179 }; 00180 00181 template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_> 00182 struct nested<const Tensor<Scalar_, NumIndices_, Options_, IndexType_> > 00183 { 00184 typedef const Tensor<Scalar_, NumIndices_, Options_, IndexType_>& type; 00185 }; 00186 00187 template <typename Scalar_, typename Dimensions, int Options, typename IndexType_> 00188 struct nested<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> > 00189 { 00190 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type; 00191 }; 00192 00193 template <typename Scalar_, typename Dimensions, int Options, typename IndexType_> 00194 struct nested<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> > 00195 { 00196 typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type; 00197 }; 00198 00199 00200 template <typename PlainObjectType, int Options, template <class> class MakePointer> 00201 struct nested<TensorMap<PlainObjectType, Options, MakePointer> > 00202 { 00203 typedef const TensorMap<PlainObjectType, Options, MakePointer>& type; 00204 }; 00205 00206 template <typename PlainObjectType, int Options, template <class> class MakePointer> 00207 struct nested<const TensorMap<PlainObjectType, Options, MakePointer> > 00208 { 00209 typedef const TensorMap<PlainObjectType, Options, MakePointer>& type; 00210 }; 00211 00212 template <typename PlainObjectType> 00213 struct nested<TensorRef<PlainObjectType> > 00214 { 00215 typedef const TensorRef<PlainObjectType>& type; 00216 }; 00217 00218 template <typename PlainObjectType> 00219 struct nested<const TensorRef<PlainObjectType> > 00220 { 00221 typedef const TensorRef<PlainObjectType>& type; 00222 }; 00223 00224 } // end namespace internal 00225 00226 // Convolutional layers take in an input tensor of shape (D, R, C, B), or (D, C, 00227 // R, B), and convolve it with a set of filters, which can also be presented as 00228 // a tensor (D, K, K, M), where M is the number of filters, K is the filter 00229 // size, and each 3-dimensional tensor of size (D, K, K) is a filter. For 00230 // simplicity we assume that we always use square filters (which is usually the 00231 // case in images), hence the two Ks in the tensor dimension. It also takes in 00232 // a few additional parameters: 00233 // Stride (S): The convolution stride is the offset between locations where we 00234 // apply the filters. A larger stride means that the output will be 00235 // spatially smaller. 00236 // Padding (P): The padding we apply to the input tensor along the R and C 00237 // dimensions. This is usually used to make sure that the spatial 00238 // dimensions of the output matches our intention. 00239 // 00240 // Two types of padding are often used: 00241 // SAME: The pad value is computed so that the output will have size 00242 // R/S and C/S. 00243 // VALID: no padding is carried out. 00244 // When we do padding, the padded values at the padded locations are usually 00245 // zero. 00246 // 00247 // The output dimensions for convolution, when given all the parameters above, 00248 // are as follows: 00249 // When Padding = SAME: the output size is (B, R', C', M), where 00250 // R' = ceil(float(R) / float(S)) 00251 // C' = ceil(float(C) / float(S)) 00252 // where ceil is the ceiling function. The input tensor is padded with 0 as 00253 // needed. The number of padded rows and columns are computed as: 00254 // Pr = ((R' - 1) * S + K - R) / 2 00255 // Pc = ((C' - 1) * S + K - C) / 2 00256 // when the stride is 1, we have the simplified case R'=R, C'=C, Pr=Pc=(K-1)/2. 00257 // This is where SAME comes from - the output has the same size as the input has. 00258 // When Padding = VALID: the output size is computed as 00259 // R' = ceil(float(R - K + 1) / float(S)) 00260 // C' = ceil(float(C - K + 1) / float(S)) 00261 // and the number of padded rows and columns are computed in the same way as in 00262 // the SAME case. 00263 // When the stride is 1, we have the simplified case R'=R-K+1, C'=C-K+1, Pr=0, 00264 // Pc=0. 00265 typedef enum { 00266 PADDING_VALID = 1, 00267 PADDING_SAME = 2 00268 } PaddingType; 00269 00270 } // end namespace Eigen 00271 00272 #endif // EIGEN_CXX11_TENSOR_TENSOR_TRAITS_H