TensorEvalTo.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
12 
13 namespace Eigen {
14 
22 namespace internal {
23 template<typename XprType>
24 struct traits<TensorEvalToOp<XprType> >
25 {
26  // Type promotion to handle the case where the types of the lhs and the rhs are different.
27  typedef typename XprType::Scalar Scalar;
28  typedef traits<XprType> XprTraits;
29  typedef typename XprTraits::StorageKind StorageKind;
30  typedef typename XprTraits::Index Index;
31  typedef typename XprType::Nested Nested;
32  typedef typename remove_reference<Nested>::type _Nested;
33  static const int NumDimensions = XprTraits::NumDimensions;
34  static const int Layout = XprTraits::Layout;
35 
36  enum {
37  Flags = 0
38  };
39 };
40 
41 template<typename XprType>
42 struct eval<TensorEvalToOp<XprType>, Eigen::Dense>
43 {
44  typedef const TensorEvalToOp<XprType>& type;
45 };
46 
47 template<typename XprType>
48 struct nested<TensorEvalToOp<XprType>, 1, typename eval<TensorEvalToOp<XprType> >::type>
49 {
50  typedef TensorEvalToOp<XprType> type;
51 };
52 
53 } // end namespace internal
54 
55 
56 
57 
58 template<typename XprType>
59 class TensorEvalToOp : public TensorBase<TensorEvalToOp<XprType>, ReadOnlyAccessors>
60 {
61  public:
62  typedef typename Eigen::internal::traits<TensorEvalToOp>::Scalar Scalar;
63  typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
64  typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
65  typedef typename Eigen::internal::nested<TensorEvalToOp>::type Nested;
66  typedef typename Eigen::internal::traits<TensorEvalToOp>::StorageKind StorageKind;
67  typedef typename Eigen::internal::traits<TensorEvalToOp>::Index Index;
68 
69  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvalToOp(CoeffReturnType* buffer, const XprType& expr)
70  : m_xpr(expr), m_buffer(buffer) {}
71 
72  EIGEN_DEVICE_FUNC
73  const typename internal::remove_all<typename XprType::Nested>::type&
74  expression() const { return m_xpr; }
75 
76  EIGEN_DEVICE_FUNC CoeffReturnType* buffer() const { return m_buffer; }
77 
78  protected:
79  typename XprType::Nested m_xpr;
80  CoeffReturnType* m_buffer;
81 };
82 
83 
84 
85 template<typename ArgType, typename Device>
86 struct TensorEvaluator<const TensorEvalToOp<ArgType>, Device>
87 {
88  typedef TensorEvalToOp<ArgType> XprType;
89  typedef typename ArgType::Scalar Scalar;
90  typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
91  typedef typename XprType::Index Index;
92  typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
93  typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
94  static const int PacketSize = internal::unpacket_traits<PacketReturnType>::size;
95 
96  enum {
97  IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
98  PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
99  Layout = TensorEvaluator<ArgType, Device>::Layout,
100  CoordAccess = false, // to be implemented
101  RawAccess = true
102  };
103 
104  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
105  : m_impl(op.expression(), device), m_device(device), m_buffer(op.buffer())
106  { }
107 
108  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~TensorEvaluator() {
109  }
110 
111  EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_impl.dimensions(); }
112 
113  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(CoeffReturnType* scalar) {
114  EIGEN_UNUSED_VARIABLE(scalar);
115  eigen_assert(scalar == NULL);
116  return m_impl.evalSubExprsIfNeeded(m_buffer);
117  }
118 
119  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalScalar(Index i) {
120  m_buffer[i] = m_impl.coeff(i);
121  }
122  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalPacket(Index i) {
123  internal::pstoret<CoeffReturnType, PacketReturnType, Aligned>(m_buffer + i, m_impl.template packet<TensorEvaluator<ArgType, Device>::IsAligned ? Aligned : Unaligned>(i));
124  }
125 
126  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
127  m_impl.cleanup();
128  }
129 
130  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
131  {
132  return m_buffer[index];
133  }
134 
135  template<int LoadMode>
136  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
137  {
138  return internal::ploadt<PacketReturnType, LoadMode>(m_buffer + index);
139  }
140 
141  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
142  // We assume that evalPacket or evalScalar is called to perform the
143  // assignment and account for the cost of the write here.
144  return m_impl.costPerCoeff(vectorized) +
145  TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
146  }
147 
148  EIGEN_DEVICE_FUNC CoeffReturnType* data() const { return m_buffer; }
149 
150  private:
151  TensorEvaluator<ArgType, Device> m_impl;
152  const Device& m_device;
153  CoeffReturnType* m_buffer;
154 };
155 
156 
157 } // end namespace Eigen
158 
159 #endif // EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
Namespace containing all symbols from the Eigen library.
Definition: AdolcForward:45