12b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This file is part of Eigen, a lightweight C++ template library 22b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for linear algebra. 32b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 52b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 62b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This Source Code Form is subject to the terms of the Mozilla 72b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Public License v. 2.0. If a copy of the MPL was not distributed 82b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 92b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H 112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H 122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen { 142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \class TensorReshaping 162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \ingroup CXX11_Tensor_Module 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \brief Tensor reshaping class. 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename XprType> 242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorReshapingOp<NewDimensions, XprType> > : public traits<XprType> 252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef traits<XprType> XprTraits; 282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::StorageKind StorageKind; 292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::Index Index; 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Nested Nested; 312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename remove_reference<Nested>::type _Nested; 322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDimensions = array_size<NewDimensions>::value; 332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int Layout = XprTraits::Layout; 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename XprType> 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorReshapingOp<NewDimensions, XprType>, Eigen::Dense> 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const TensorReshapingOp<NewDimensions, XprType>& type; 402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename XprType> 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorReshapingOp<NewDimensions, XprType>, 1, typename eval<TensorReshapingOp<NewDimensions, XprType> >::type> 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorReshapingOp<NewDimensions, XprType> type; 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename XprType> 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorReshapingOp : public TensorBase<TensorReshapingOp<NewDimensions, XprType>, WriteAccessors> 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorReshapingOp>::Scalar Scalar; 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType; 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::nested<TensorReshapingOp>::type Nested; 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorReshapingOp>::StorageKind StorageKind; 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorReshapingOp>::Index Index; 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorReshapingOp(const XprType& expr, const NewDimensions& dims) 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_xpr(expr), m_dims(dims) {} 642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const NewDimensions& dimensions() const { return m_dims; } 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const typename internal::remove_all<typename XprType::Nested>::type& 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang expression() const { return m_xpr; } 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorReshapingOp& operator = (const TensorReshapingOp& other) 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorReshapingOp, const TensorReshapingOp> Assign; 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice()); 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename OtherDerived> 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorReshapingOp& operator = (const OtherDerived& other) 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorReshapingOp, const OtherDerived> Assign; 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice()); 882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename XprType::Nested m_xpr; 932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const NewDimensions m_dims; 942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as rvalue 982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename ArgType, typename Device> 992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct TensorEvaluator<const TensorReshapingOp<NewDimensions, ArgType>, Device> 1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorReshapingOp<NewDimensions, ArgType> XprType; 1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef NewDimensions Dimensions; 1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = TensorEvaluator<ArgType, Device>::IsAligned, 1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess, 1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoordAccess = false, // to be implemented 1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = TensorEvaluator<ArgType, Device>::RawAccess 1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_impl(op.expression(), device), m_dimensions(op.dimensions()) 1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // The total size of the reshaped tensor must be equal to the total size 1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // of the input tensor. 1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(internal::array_prod(m_impl.dimensions()) == internal::array_prod(op.dimensions())); 1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } 1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType* data) { 1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.evalSubExprsIfNeeded(data); 1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { 1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_impl.cleanup(); 1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const 1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.coeff(index); 1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<int LoadMode> 1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const 1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.template packet<LoadMode>(index); 1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const { 1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.costPerCoeff(vectorized); 1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC Scalar* data() const { return const_cast<Scalar*>(m_impl.data()); } 1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; } 1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang TensorEvaluator<ArgType, Device> m_impl; 1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang NewDimensions m_dimensions; 1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as lvalue 1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NewDimensions, typename ArgType, typename Device> 1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct TensorEvaluator<TensorReshapingOp<NewDimensions, ArgType>, Device> 1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : public TensorEvaluator<const TensorReshapingOp<NewDimensions, ArgType>, Device> 1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorEvaluator<const TensorReshapingOp<NewDimensions, ArgType>, Device> Base; 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorReshapingOp<NewDimensions, ArgType> XprType; 1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef NewDimensions Dimensions; 1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = TensorEvaluator<ArgType, Device>::IsAligned, 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess, 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoordAccess = false, // to be implemented 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = TensorEvaluator<ArgType, Device>::RawAccess 1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : Base(op, device) 1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { } 1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index) 1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return this->m_impl.coeffRef(index); 1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template <int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang void writePacket(Index index, const PacketReturnType& x) 1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->m_impl.template writePacket<StoreMode>(index, x); 1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \class TensorSlicing 1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \ingroup CXX11_Tensor_Module 2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \brief Tensor slicing class. 2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename XprType> 2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorSlicingOp<StartIndices, Sizes, XprType> > : public traits<XprType> 2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef traits<XprType> XprTraits; 2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::StorageKind StorageKind; 2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::Index Index; 2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Nested Nested; 2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename remove_reference<Nested>::type _Nested; 2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDimensions = array_size<StartIndices>::value; 2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int Layout = XprTraits::Layout; 2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename XprType> 2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorSlicingOp<StartIndices, Sizes, XprType>, Eigen::Dense> 2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const TensorSlicingOp<StartIndices, Sizes, XprType>& type; 2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename XprType> 2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorSlicingOp<StartIndices, Sizes, XprType>, 1, typename eval<TensorSlicingOp<StartIndices, Sizes, XprType> >::type> 2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorSlicingOp<StartIndices, Sizes, XprType> type; 2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename XprType> 2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorSlicingOp : public TensorBase<TensorSlicingOp<StartIndices, Sizes, XprType> > 2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorSlicingOp>::Scalar Scalar; 2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::nested<TensorSlicingOp>::type Nested; 2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorSlicingOp>::StorageKind StorageKind; 2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Eigen::internal::traits<TensorSlicingOp>::Index Index; 2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorSlicingOp(const XprType& expr, const StartIndices& indices, const Sizes& sizes) 2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_xpr(expr), m_indices(indices), m_sizes(sizes) {} 2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices& startIndices() const { return m_indices; } 2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Sizes& sizes() const { return m_sizes; } 2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const typename internal::remove_all<typename XprType::Nested>::type& 2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang expression() const { return m_xpr; } 2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename OtherDerived> 2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorSlicingOp& operator = (const OtherDerived& other) 2602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorSlicingOp, const OtherDerived> Assign; 2622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 2632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice()); 2642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 2652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorSlicingOp& operator = (const TensorSlicingOp& other) 2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorSlicingOp, const TensorSlicingOp> Assign; 2712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 2722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice()); 2732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 2742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 2752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename XprType::Nested m_xpr; 2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices m_indices; 2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Sizes m_sizes; 2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Fixme: figure out the exact threshold 2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace { 2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Index, typename Device> struct MemcpyTriggerForSlicing { 2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC MemcpyTriggerForSlicing(const Device& device) : threshold_(2 * device.numThreads()) { } 2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC bool operator ()(Index val) const { return val > threshold_; } 2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang private: 2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index threshold_; 2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// It is very expensive to start the memcpy kernel on GPU: we therefore only 2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// use it for large copies. 2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifdef EIGEN_USE_GPU 2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Index> struct MemcpyTriggerForSlicing<Index, GpuDevice> { 2982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC MemcpyTriggerForSlicing(const GpuDevice&) { } 2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC bool operator ()(Index val) const { return val > 4*1024*1024; } 3002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 3012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif 3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 3032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as rvalue 3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename ArgType, typename Device> 3062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device> 3072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 3082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorSlicingOp<StartIndices, Sizes, ArgType> XprType; 3092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDims = internal::array_size<Sizes>::value; 3102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 3122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Alignment can't be guaranteed at compile time since it depends on the 3132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // slice offsets and sizes. 3142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = /*TensorEvaluator<ArgType, Device>::IsAligned*/false, 3152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess, 3162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 3172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoordAccess = false, 3182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = false 3192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 3202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 3222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_impl(op.expression(), device), m_device(device), m_dimensions(op.sizes()), m_offsets(op.startIndices()) 3232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 3242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (std::size_t i = 0; i < internal::array_size<Dimensions>::value; ++i) { 3252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(m_impl.dimensions()[i] >= op.sizes()[i] + op.startIndices()[i]); 3262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions(); 3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Sizes& output_dims = op.sizes(); 3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[0] = 1; 3322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < NumDims; ++i) { 3332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[i] = m_inputStrides[i-1] * input_dims[i-1]; 3342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Don't initialize m_fastOutputStrides[0] since it won't ever be accessed. 3372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[0] = 1; 3382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < NumDims; ++i) { 3392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[i] = m_outputStrides[i-1] * output_dims[i-1]; 3402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]); 3412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 3432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[NumDims-1] = 1; 3442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 2; i >= 0; --i) { 3452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[i] = m_inputStrides[i+1] * input_dims[i+1]; 3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Don't initialize m_fastOutputStrides[NumDims-1] since it won't ever be accessed. 3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[NumDims-1] = 1; 3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 2; i >= 0; --i) { 3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[i] = m_outputStrides[i+1] * output_dims[i+1]; 3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]); 3532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 3582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 3592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 3602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 3612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Sizes Dimensions; 3622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } 3642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType* data) { 3672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_impl.evalSubExprsIfNeeded(NULL); 3682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (!NumTraits<typename internal::remove_const<Scalar>::type>::RequireInitialization && data && m_impl.data()) { 3692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index contiguous_values = 1; 3702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 3712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims; ++i) { 3722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang contiguous_values *= dimensions()[i]; 3732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (dimensions()[i] != m_impl.dimensions()[i]) { 3742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 3752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 3782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims-1; i >= 0; --i) { 3792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang contiguous_values *= dimensions()[i]; 3802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (dimensions()[i] != m_impl.dimensions()[i]) { 3812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 3822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Use memcpy if it's going to be faster than using the regular evaluation. 3862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const MemcpyTriggerForSlicing<Index, Device> trigger(m_device); 3872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (trigger(contiguous_values)) { 3882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar* src = (Scalar*)m_impl.data(); 3892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < internal::array_prod(dimensions()); i += contiguous_values) { 3902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index offset = srcCoeff(i); 3912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_device.memcpy((void*)(data+i), src+offset, contiguous_values * sizeof(Scalar)); 3922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return false; 3942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return true; 3972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 3982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { 4002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_impl.cleanup(); 4012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const 4042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 4052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.coeff(srcCoeff(index)); 4062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<int LoadMode> 4092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const 4102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 4112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const int packetSize = internal::unpacket_traits<PacketReturnType>::size; 4122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STATIC_ASSERT((packetSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE) 4132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(index+packetSize-1 < internal::array_prod(dimensions())); 4142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index inputIndices[] = {0, 0}; 4162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index indices[] = {index, index + packetSize - 1}; 4172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 4182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 1; i > 0; --i) { 4192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx0 = indices[0] / m_fastOutputStrides[i]; 4202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx1 = indices[1] / m_fastOutputStrides[i]; 4212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (idx0 + m_offsets[i]) * m_inputStrides[i]; 4222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (idx1 + m_offsets[i]) * m_inputStrides[i]; 4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[0] -= idx0 * m_outputStrides[i]; 4242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[1] -= idx1 * m_outputStrides[i]; 4252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (indices[0] + m_offsets[0]); 4272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (indices[1] + m_offsets[0]); 4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 4292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims - 1; ++i) { 4302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx0 = indices[0] / m_fastOutputStrides[i]; 4312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx1 = indices[1] / m_fastOutputStrides[i]; 4322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (idx0 + m_offsets[i]) * m_inputStrides[i]; 4332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (idx1 + m_offsets[i]) * m_inputStrides[i]; 4342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[0] -= idx0 * m_outputStrides[i]; 4352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[1] -= idx1 * m_outputStrides[i]; 4362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (indices[0] + m_offsets[NumDims-1]); 4382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (indices[1] + m_offsets[NumDims-1]); 4392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (inputIndices[1] - inputIndices[0] == packetSize - 1) { 4412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketReturnType rslt = m_impl.template packet<Unaligned>(inputIndices[0]); 4422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return rslt; 4432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else { 4452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_ALIGN_MAX typename internal::remove_const<CoeffReturnType>::type values[packetSize]; 4462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang values[0] = m_impl.coeff(inputIndices[0]); 4472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang values[packetSize-1] = m_impl.coeff(inputIndices[1]); 4482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < packetSize-1; ++i) { 4492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang values[i] = coeff(index+i); 4502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketReturnType rslt = internal::pload<PacketReturnType>(values); 4522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return rslt; 4532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const { 4572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, 0, NumDims); 4582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() const { 4622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar* result = m_impl.data(); 4632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (result) { 4642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index offset = 0; 4652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 4662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims; ++i) { 4672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_dimensions[i] != m_impl.dimensions()[i]) { 4682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang offset += m_offsets[i] * m_inputStrides[i]; 4692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int j = i+1; j < NumDims; ++j) { 4702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_dimensions[j] > 1) { 4712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return NULL; 4722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang offset += m_offsets[j] * m_inputStrides[j]; 4742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 4762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 4792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 1; i >= 0; --i) { 4802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_dimensions[i] != m_impl.dimensions()[i]) { 4812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang offset += m_offsets[i] * m_inputStrides[i]; 4822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int j = i-1; j >= 0; --j) { 4832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (m_dimensions[j] > 1) { 4842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return NULL; 4852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang offset += m_offsets[j] * m_inputStrides[j]; 4872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang break; 4892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return result + offset; 4932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return NULL; 4952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 4962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 4982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const 4992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 5002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index inputIndex = 0; 5012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 5022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 1; i > 0; --i) { 5032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx = index / m_fastOutputStrides[i]; 5042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += (idx + m_offsets[i]) * m_inputStrides[i]; 5052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang index -= idx * m_outputStrides[i]; 5062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += (index + m_offsets[0]); 5082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 5092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims - 1; ++i) { 5102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx = index / m_fastOutputStrides[i]; 5112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += (idx + m_offsets[i]) * m_inputStrides[i]; 5122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang index -= idx * m_outputStrides[i]; 5132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += (index + m_offsets[NumDims-1]); 5152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return inputIndex; 5172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<Index, NumDims> m_outputStrides; 5202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<internal::TensorIntDivisor<Index>, NumDims> m_fastOutputStrides; 5212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<Index, NumDims> m_inputStrides; 5222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang TensorEvaluator<ArgType, Device> m_impl; 5232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Device& m_device; 5242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Dimensions m_dimensions; 5252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices m_offsets; 5262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 5272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as lvalue 5302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename Sizes, typename ArgType, typename Device> 5312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct TensorEvaluator<TensorSlicingOp<StartIndices, Sizes, ArgType>, Device> 5322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : public TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device> 5332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 5342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device> Base; 5352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorSlicingOp<StartIndices, Sizes, ArgType> XprType; 5362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDims = internal::array_size<Sizes>::value; 5372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 5392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = /*TensorEvaluator<ArgType, Device>::IsAligned*/false, 5402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess, 5412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 5422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoordAccess = false, 5432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = false 5442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 5452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 5472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : Base(op, device) 5482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { } 5492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 5512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 5522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 5532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 5542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Sizes Dimensions; 5552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index) 5572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 5582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return this->m_impl.coeffRef(this->srcCoeff(index)); 5592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template <int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 5622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang void writePacket(Index index, const PacketReturnType& x) 5632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 5642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const int packetSize = internal::unpacket_traits<PacketReturnType>::size; 5652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index inputIndices[] = {0, 0}; 5662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index indices[] = {index, index + packetSize - 1}; 5672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 5682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 1; i > 0; --i) { 5692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx0 = indices[0] / this->m_fastOutputStrides[i]; 5702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx1 = indices[1] / this->m_fastOutputStrides[i]; 5712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (idx0 + this->m_offsets[i]) * this->m_inputStrides[i]; 5722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (idx1 + this->m_offsets[i]) * this->m_inputStrides[i]; 5732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[0] -= idx0 * this->m_outputStrides[i]; 5742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[1] -= idx1 * this->m_outputStrides[i]; 5752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (indices[0] + this->m_offsets[0]); 5772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (indices[1] + this->m_offsets[0]); 5782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 5792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims - 1; ++i) { 5802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx0 = indices[0] / this->m_fastOutputStrides[i]; 5812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx1 = indices[1] / this->m_fastOutputStrides[i]; 5822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (idx0 + this->m_offsets[i]) * this->m_inputStrides[i]; 5832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (idx1 + this->m_offsets[i]) * this->m_inputStrides[i]; 5842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[0] -= idx0 * this->m_outputStrides[i]; 5852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang indices[1] -= idx1 * this->m_outputStrides[i]; 5862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[0] += (indices[0] + this->m_offsets[NumDims-1]); 5882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndices[1] += (indices[1] + this->m_offsets[NumDims-1]); 5892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (inputIndices[1] - inputIndices[0] == packetSize - 1) { 5912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->m_impl.template writePacket<StoreMode>(inputIndices[0], x); 5922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 5932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else { 5942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_ALIGN_MAX CoeffReturnType values[packetSize]; 5952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::pstore<CoeffReturnType, PacketReturnType>(values, x); 5962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->m_impl.coeffRef(inputIndices[0]) = values[0]; 5972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->m_impl.coeffRef(inputIndices[1]) = values[packetSize-1]; 5982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < packetSize-1; ++i) { 5992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->coeffRef(index+i) = values[i]; 6002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 6012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 6022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 6032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 6082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename XprType> 6092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> > : public traits<XprType> 6102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 6122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef traits<XprType> XprTraits; 6132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::StorageKind StorageKind; 6142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprTraits::Index Index; 6152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Nested Nested; 6162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename remove_reference<Nested>::type _Nested; 6172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDimensions = array_size<StartIndices>::value; 6182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int Layout = XprTraits::Layout; 6192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename XprType> 6222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Eigen::Dense> 6232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>& type; 6252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename XprType> 6282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, 1, typename eval<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> >::type> 6292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> type; 6312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 6342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename XprType> 6372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorStridingSlicingOp : public TensorBase<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> > 6382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 6402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::traits<TensorStridingSlicingOp>::Scalar Scalar; 6412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 6422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::nested<TensorStridingSlicingOp>::type Nested; 6432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::traits<TensorStridingSlicingOp>::StorageKind StorageKind; 6442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::traits<TensorStridingSlicingOp>::Index Index; 6452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorStridingSlicingOp( 6472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const XprType& expr, const StartIndices& startIndices, 6482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StopIndices& stopIndices, const Strides& strides) 6492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_xpr(expr), m_startIndices(startIndices), m_stopIndices(stopIndices), 6502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_strides(strides) {} 6512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices& startIndices() const { return m_startIndices; } 6542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices& stopIndices() const { return m_stopIndices; } 6562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices& strides() const { return m_strides; } 6582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const typename internal::remove_all<typename XprType::Nested>::type& 6612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang expression() const { return m_xpr; } 6622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorStridingSlicingOp& operator = (const TensorStridingSlicingOp& other) 6652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 6662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorStridingSlicingOp, const TensorStridingSlicingOp> Assign; 6672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 6682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run( 6692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang assign, DefaultDevice()); 6702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 6712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 6722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename OtherDerived> 6742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 6752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE TensorStridingSlicingOp& operator = (const OtherDerived& other) 6762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 6772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorAssignOp<TensorStridingSlicingOp, const OtherDerived> Assign; 6782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Assign assign(*this, other); 6792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::TensorExecutor<const Assign, DefaultDevice>::run( 6802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang assign, DefaultDevice()); 6812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 6822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 6832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 6852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename XprType::Nested m_xpr; 6862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StartIndices m_startIndices; 6872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const StopIndices m_stopIndices; 6882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Strides m_strides; 6892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as rvalue 6922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename ArgType, typename Device> 6932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device> 6942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType> XprType; 6962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDims = internal::array_size<Strides>::value; 6972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 6992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Alignment can't be guaranteed at compile time since it depends on the 7002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // slice offsets and sizes. 7012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = false, 7022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = false, 7032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang BlockAccess = false, 7042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 7052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = false 7062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 7072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 7092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : m_impl(op.expression(), device), m_device(device), m_strides(op.strides()) 7102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 7112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Handle degenerate intervals by gracefully clamping and allowing m_dimensions to be zero 7122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang DSizes<Index,NumDims> startIndicesClamped, stopIndicesClamped; 7132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (size_t i = 0; i < internal::array_size<Dimensions>::value; ++i) { 7142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(m_strides[i] != 0 && "0 stride is invalid"); 7152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(m_strides[i]>0){ 7162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang startIndicesClamped[i] = clamp(op.startIndices()[i], 0, m_impl.dimensions()[i]); 7172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang stopIndicesClamped[i] = clamp(op.stopIndices()[i], 0, m_impl.dimensions()[i]); 7182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }else{ 7192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* implies m_strides[i]<0 by assert */ 7202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang startIndicesClamped[i] = clamp(op.startIndices()[i], -1, m_impl.dimensions()[i] - 1); 7212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang stopIndicesClamped[i] = clamp(op.stopIndices()[i], -1, m_impl.dimensions()[i] - 1); 7222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_startIndices[i] = startIndicesClamped[i]; 7242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions(); 7272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // check for degenerate intervals and compute output tensor shape 7292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool degenerate = false;; 7302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for(int i = 0; i < NumDims; i++){ 7312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index interval = stopIndicesClamped[i] - startIndicesClamped[i]; 7322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(interval == 0 || ((interval<0) != (m_strides[i]<0))){ 7332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_dimensions[i] = 0; 7342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang degenerate = true; 7352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }else{ 7362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_dimensions[i] = interval / m_strides[i] 7372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang + (interval % m_strides[i] != 0 ? 1 : 0); 7382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(m_dimensions[i] >= 0); 7392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Strides output_dims = m_dimensions; 7422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 7442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[0] = m_strides[0]; 7452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_offsets[0] = startIndicesClamped[0]; 7462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index previousDimProduct = 1; 7472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < NumDims; ++i) { 7482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang previousDimProduct *= input_dims[i-1]; 7492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[i] = previousDimProduct * m_strides[i]; 7502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_offsets[i] = startIndicesClamped[i] * previousDimProduct; 7512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Don't initialize m_fastOutputStrides[0] since it won't ever be accessed. 7542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[0] = 1; 7552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 1; i < NumDims; ++i) { 7562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[i] = m_outputStrides[i-1] * output_dims[i-1]; 7572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // NOTE: if tensor is degenerate, we send 1 to prevent TensorIntDivisor constructor crash 7582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]); 7592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 7612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[NumDims-1] = m_strides[NumDims-1]; 7622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_offsets[NumDims-1] = startIndicesClamped[NumDims-1]; 7632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index previousDimProduct = 1; 7642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 2; i >= 0; --i) { 7652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang previousDimProduct *= input_dims[i+1]; 7662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_inputStrides[i] = previousDimProduct * m_strides[i]; 7672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_offsets[i] = startIndicesClamped[i] * previousDimProduct; 7682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[NumDims-1] = 1; 7712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 2; i >= 0; --i) { 7722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_outputStrides[i] = m_outputStrides[i+1] * output_dims[i+1]; 7732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // NOTE: if tensor is degenerate, we send 1 to prevent TensorIntDivisor constructor crash 7742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]); 7752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_block_total_size_max = numext::maxi(static_cast<std::size_t>(1), 7782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang device.lastLevelCacheSize() / 7792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang sizeof(Scalar)); 7802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 7832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 7842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::remove_const<Scalar>::type ScalarNonConst; 7852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 7862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 7872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Strides Dimensions; 7882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } 7902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType*) { 7932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_impl.evalSubExprsIfNeeded(NULL); 7942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return true; 7952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 7962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { 7982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_impl.cleanup(); 7992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const 8022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 8032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.coeff(srcCoeff(index)); 8042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const { 8072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, 0, NumDims); 8082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() const { 8112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return NULL; 8122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 8152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const 8162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 8172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index inputIndex = 0; 8182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { 8192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = NumDims - 1; i >= 0; --i) { 8202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx = index / m_fastOutputStrides[i]; 8212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += idx * m_inputStrides[i] + m_offsets[i]; 8222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang index -= idx * m_outputStrides[i]; 8232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } else { 8252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang for (int i = 0; i < NumDims; ++i) { 8262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Index idx = index / m_fastOutputStrides[i]; 8272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inputIndex += idx * m_inputStrides[i] + m_offsets[i]; 8282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang index -= idx * m_outputStrides[i]; 8292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return inputIndex; 8322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static EIGEN_STRONG_INLINE Index clamp(Index value, Index min, Index max) { 8352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return numext::maxi(min, numext::mini(max,value)); 8362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<Index, NumDims> m_outputStrides; 8392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<internal::TensorIntDivisor<Index>, NumDims> m_fastOutputStrides; 8402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang array<Index, NumDims> m_inputStrides; 8412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang TensorEvaluator<ArgType, Device> m_impl; 8422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Device& m_device; 8432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang DSizes<Index, NumDims> m_startIndices; // clamped startIndices 8442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang DSizes<Index, NumDims> m_dimensions; 8452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang DSizes<Index, NumDims> m_offsets; // offset in a flattened shape 8462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const Strides m_strides; 8472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::size_t m_block_total_size_max; 8482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 8492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eval as lvalue 8512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename StartIndices, typename StopIndices, typename Strides, typename ArgType, typename Device> 8522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct TensorEvaluator<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device> 8532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : public TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device> 8542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 8552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device> Base; 8562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType> XprType; 8572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static const int NumDims = internal::array_size<Strides>::value; 8582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 8602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang IsAligned = false, 8612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang PacketAccess = false, 8622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang BlockAccess = false, 8632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Layout = TensorEvaluator<ArgType, Device>::Layout, 8642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoordAccess = TensorEvaluator<ArgType, Device>::CoordAccess, 8652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RawAccess = false 8662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 8672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device) 8692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : Base(op, device) 8702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { } 8712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Index Index; 8732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 8742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::remove_const<Scalar>::type ScalarNonConst; 8752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::CoeffReturnType CoeffReturnType; 8762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType; 8772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Strides Dimensions; 8782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index) 8802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 8812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return this->m_impl.coeffRef(this->srcCoeff(index)); 8822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 8832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 8842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace Eigen 8872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H 889