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