TensorLayoutSwap.h
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_LAYOUT_SWAP_H
00011 #define EIGEN_CXX11_TENSOR_TENSOR_LAYOUT_SWAP_H
00012 
00013 namespace Eigen {
00014 
00037 namespace internal {
00038 template<typename XprType>
00039 struct traits<TensorLayoutSwapOp<XprType> > : public traits<XprType>
00040 {
00041   typedef typename XprType::Scalar Scalar;
00042   typedef traits<XprType> XprTraits;
00043   typedef typename XprTraits::StorageKind StorageKind;
00044   typedef typename XprTraits::Index Index;
00045   typedef typename XprType::Nested Nested;
00046   typedef typename remove_reference<Nested>::type _Nested;
00047   static const int NumDimensions = traits<XprType>::NumDimensions;
00048   static const int Layout = (traits<XprType>::Layout == ColMajor) ? RowMajor : ColMajor;
00049 };
00050 
00051 template<typename XprType>
00052 struct eval<TensorLayoutSwapOp<XprType>, Eigen::Dense>
00053 {
00054   typedef const TensorLayoutSwapOp<XprType>& type;
00055 };
00056 
00057 template<typename XprType>
00058 struct nested<TensorLayoutSwapOp<XprType>, 1, typename eval<TensorLayoutSwapOp<XprType> >::type>
00059 {
00060   typedef TensorLayoutSwapOp<XprType> type;
00061 };
00062 
00063 }  // end namespace internal
00064 
00065 
00066 
00067 template<typename XprType>
00068 class TensorLayoutSwapOp : public TensorBase<TensorLayoutSwapOp<XprType>, WriteAccessors>
00069 {
00070   public:
00071   typedef typename Eigen::internal::traits<TensorLayoutSwapOp>::Scalar Scalar;
00072   typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
00073   typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
00074   typedef typename Eigen::internal::nested<TensorLayoutSwapOp>::type Nested;
00075   typedef typename Eigen::internal::traits<TensorLayoutSwapOp>::StorageKind StorageKind;
00076   typedef typename Eigen::internal::traits<TensorLayoutSwapOp>::Index Index;
00077 
00078   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorLayoutSwapOp(const XprType& expr)
00079       : m_xpr(expr) {}
00080 
00081     EIGEN_DEVICE_FUNC
00082     const typename internal::remove_all<typename XprType::Nested>::type&
00083     expression() const { return m_xpr; }
00084 
00085     EIGEN_DEVICE_FUNC
00086     EIGEN_STRONG_INLINE TensorLayoutSwapOp& operator = (const TensorLayoutSwapOp& other)
00087     {
00088       typedef TensorAssignOp<TensorLayoutSwapOp, const TensorLayoutSwapOp> Assign;
00089       Assign assign(*this, other);
00090       internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
00091       return *this;
00092     }
00093 
00094     template<typename OtherDerived>
00095     EIGEN_DEVICE_FUNC
00096     EIGEN_STRONG_INLINE TensorLayoutSwapOp& operator = (const OtherDerived& other)
00097     {
00098       typedef TensorAssignOp<TensorLayoutSwapOp, const OtherDerived> Assign;
00099       Assign assign(*this, other);
00100       internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
00101       return *this;
00102     }
00103 
00104   protected:
00105     typename XprType::Nested m_xpr;
00106 };
00107 
00108 
00109 // Eval as rvalue
00110 template<typename ArgType, typename Device>
00111 struct TensorEvaluator<const TensorLayoutSwapOp<ArgType>, Device>
00112 {
00113   typedef TensorLayoutSwapOp<ArgType> XprType;
00114   typedef typename XprType::Index Index;
00115   static const int NumDims = internal::array_size<typename TensorEvaluator<ArgType, Device>::Dimensions>::value;
00116   typedef DSizes<Index, NumDims> Dimensions;
00117 
00118   enum {
00119     IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
00120     PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
00121     Layout = (static_cast<int>(TensorEvaluator<ArgType, Device>::Layout) == static_cast<int>(ColMajor)) ? RowMajor : ColMajor,
00122     CoordAccess = false,  // to be implemented
00123     RawAccess = TensorEvaluator<ArgType, Device>::RawAccess
00124   };
00125 
00126   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
00127       : m_impl(op.expression(), device)
00128   {
00129     for(int i = 0; i < NumDims; ++i) {
00130       m_dimensions[i] = m_impl.dimensions()[NumDims-1-i];
00131     }
00132   }
00133 
00134   typedef typename XprType::Scalar Scalar;
00135   typedef typename XprType::CoeffReturnType CoeffReturnType;
00136   typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
00137 
00138   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
00139 
00140   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType* data) {
00141     return m_impl.evalSubExprsIfNeeded(data);
00142   }
00143   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
00144     m_impl.cleanup();
00145   }
00146 
00147   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
00148   {
00149     return m_impl.coeff(index);
00150   }
00151 
00152   template<int LoadMode>
00153   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00154   {
00155     return m_impl.template packet<LoadMode>(index);
00156   }
00157 
00158   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
00159     return m_impl.costPerCoeff(vectorized);
00160   }
00161 
00162   EIGEN_DEVICE_FUNC Scalar* data() const { return m_impl.data(); }
00163 
00164   const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
00165 
00166  protected:
00167   TensorEvaluator<ArgType, Device> m_impl;
00168   Dimensions m_dimensions;
00169 };
00170 
00171 
00172 // Eval as lvalue
00173 template<typename ArgType, typename Device>
00174   struct TensorEvaluator<TensorLayoutSwapOp<ArgType>, Device>
00175   : public TensorEvaluator<const TensorLayoutSwapOp<ArgType>, Device>
00176 {
00177   typedef TensorEvaluator<const TensorLayoutSwapOp<ArgType>, Device> Base;
00178   typedef TensorLayoutSwapOp<ArgType> XprType;
00179 
00180   enum {
00181     IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
00182     PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
00183     Layout = (static_cast<int>(TensorEvaluator<ArgType, Device>::Layout) == static_cast<int>(ColMajor)) ? RowMajor : ColMajor,
00184     CoordAccess = false  // to be implemented
00185   };
00186 
00187   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
00188     : Base(op, device)
00189   { }
00190 
00191   typedef typename XprType::Index Index;
00192   typedef typename XprType::Scalar Scalar;
00193   typedef typename XprType::CoeffReturnType CoeffReturnType;
00194   typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
00195 
00196   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index)
00197   {
00198     return this->m_impl.coeffRef(index);
00199   }
00200   template <int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00201   void writePacket(Index index, const PacketReturnType& x)
00202   {
00203     this->m_impl.template writePacket<StoreMode>(index, x);
00204   }
00205 };
00206 
00207 } // end namespace Eigen
00208 
00209 #endif // EIGEN_CXX11_TENSOR_TENSOR_LAYOUT_SWAP_H
 All Classes Functions Variables Typedefs Enumerator