![]() |
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) 2015 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_GENERATOR_H 00011 #define EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H 00012 00013 namespace Eigen { 00014 00022 namespace internal { 00023 template<typename Generator, typename XprType> 00024 struct traits<TensorGeneratorOp<Generator, XprType> > : public traits<XprType> 00025 { 00026 typedef typename XprType::Scalar Scalar; 00027 typedef traits<XprType> XprTraits; 00028 typedef typename XprTraits::StorageKind StorageKind; 00029 typedef typename XprTraits::Index Index; 00030 typedef typename XprType::Nested Nested; 00031 typedef typename remove_reference<Nested>::type _Nested; 00032 static const int NumDimensions = XprTraits::NumDimensions; 00033 static const int Layout = XprTraits::Layout; 00034 }; 00035 00036 template<typename Generator, typename XprType> 00037 struct eval<TensorGeneratorOp<Generator, XprType>, Eigen::Dense> 00038 { 00039 typedef const TensorGeneratorOp<Generator, XprType>& type; 00040 }; 00041 00042 template<typename Generator, typename XprType> 00043 struct nested<TensorGeneratorOp<Generator, XprType>, 1, typename eval<TensorGeneratorOp<Generator, XprType> >::type> 00044 { 00045 typedef TensorGeneratorOp<Generator, XprType> type; 00046 }; 00047 00048 } // end namespace internal 00049 00050 00051 00052 template<typename Generator, typename XprType> 00053 class TensorGeneratorOp : public TensorBase<TensorGeneratorOp<Generator, XprType>, ReadOnlyAccessors> 00054 { 00055 public: 00056 typedef typename Eigen::internal::traits<TensorGeneratorOp>::Scalar Scalar; 00057 typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; 00058 typedef typename XprType::CoeffReturnType CoeffReturnType; 00059 typedef typename Eigen::internal::nested<TensorGeneratorOp>::type Nested; 00060 typedef typename Eigen::internal::traits<TensorGeneratorOp>::StorageKind StorageKind; 00061 typedef typename Eigen::internal::traits<TensorGeneratorOp>::Index Index; 00062 00063 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorGeneratorOp(const XprType& expr, const Generator& generator) 00064 : m_xpr(expr), m_generator(generator) {} 00065 00066 EIGEN_DEVICE_FUNC 00067 const Generator& generator() const { return m_generator; } 00068 00069 EIGEN_DEVICE_FUNC 00070 const typename internal::remove_all<typename XprType::Nested>::type& 00071 expression() const { return m_xpr; } 00072 00073 protected: 00074 typename XprType::Nested m_xpr; 00075 const Generator m_generator; 00076 }; 00077 00078 00079 // Eval as rvalue 00080 template<typename Generator, typename ArgType, typename Device> 00081 struct TensorEvaluator<const TensorGeneratorOp<Generator, ArgType>, Device> 00082 { 00083 typedef TensorGeneratorOp<Generator, ArgType> XprType; 00084 typedef typename XprType::Index Index; 00085 typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions; 00086 static const int NumDims = internal::array_size<Dimensions>::value; 00087 typedef typename XprType::Scalar Scalar; 00088 typedef typename XprType::CoeffReturnType CoeffReturnType; 00089 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 00090 enum { 00091 IsAligned = false, 00092 PacketAccess = (internal::unpacket_traits<PacketReturnType>::size > 1), 00093 BlockAccess = false, 00094 Layout = TensorEvaluator<ArgType, Device>::Layout, 00095 CoordAccess = false, // to be implemented 00096 RawAccess = false 00097 }; 00098 00099 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 00100 : m_generator(op.generator()) 00101 { 00102 TensorEvaluator<ArgType, Device> impl(op.expression(), device); 00103 m_dimensions = impl.dimensions(); 00104 00105 if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 00106 m_strides[0] = 1; 00107 for (int i = 1; i < NumDims; ++i) { 00108 m_strides[i] = m_strides[i - 1] * m_dimensions[i - 1]; 00109 } 00110 } else { 00111 m_strides[NumDims - 1] = 1; 00112 for (int i = NumDims - 2; i >= 0; --i) { 00113 m_strides[i] = m_strides[i + 1] * m_dimensions[i + 1]; 00114 } 00115 } 00116 } 00117 00118 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } 00119 00120 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* /*data*/) { 00121 return true; 00122 } 00123 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { 00124 } 00125 00126 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const 00127 { 00128 array<Index, NumDims> coords; 00129 extract_coordinates(index, coords); 00130 return m_generator(coords); 00131 } 00132 00133 template<int LoadMode> 00134 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const 00135 { 00136 const int packetSize = internal::unpacket_traits<PacketReturnType>::size; 00137 EIGEN_STATIC_ASSERT((packetSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE) 00138 eigen_assert(index+packetSize-1 < dimensions().TotalSize()); 00139 00140 EIGEN_ALIGN_MAX typename internal::remove_const<CoeffReturnType>::type values[packetSize]; 00141 for (int i = 0; i < packetSize; ++i) { 00142 values[i] = coeff(index+i); 00143 } 00144 PacketReturnType rslt = internal::pload<PacketReturnType>(values); 00145 return rslt; 00146 } 00147 00148 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost 00149 costPerCoeff(bool) const { 00150 // TODO(rmlarsen): This is just a placeholder. Define interface to make 00151 // generators return their cost. 00152 return TensorOpCost(0, 0, TensorOpCost::AddCost<Scalar>() + 00153 TensorOpCost::MulCost<Scalar>()); 00154 } 00155 00156 EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; } 00157 00158 protected: 00159 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 00160 void extract_coordinates(Index index, array<Index, NumDims>& coords) const { 00161 if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 00162 for (int i = NumDims - 1; i > 0; --i) { 00163 const Index idx = index / m_strides[i]; 00164 index -= idx * m_strides[i]; 00165 coords[i] = idx; 00166 } 00167 coords[0] = index; 00168 } else { 00169 for (int i = 0; i < NumDims - 1; ++i) { 00170 const Index idx = index / m_strides[i]; 00171 index -= idx * m_strides[i]; 00172 coords[i] = idx; 00173 } 00174 coords[NumDims-1] = index; 00175 } 00176 } 00177 00178 Dimensions m_dimensions; 00179 array<Index, NumDims> m_strides; 00180 Generator m_generator; 00181 }; 00182 00183 } // end namespace Eigen 00184 00185 #endif // EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H