TensorCustomOp.h
Go to the documentation of this file.
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_CUSTOM_OP_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_CUSTOM_OP_H
12 
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
24 namespace internal {
25 template<typename CustomUnaryFunc, typename XprType>
26 struct traits<TensorCustomUnaryOp<CustomUnaryFunc, XprType> >
27 {
28  typedef typename XprType::Scalar Scalar;
29  typedef typename XprType::StorageKind StorageKind;
30  typedef typename XprType::Index Index;
31  typedef typename XprType::Nested Nested;
32  typedef std::remove_reference_t<Nested> Nested_;
33  static constexpr int NumDimensions = traits<XprType>::NumDimensions;
34  static constexpr int Layout = traits<XprType>::Layout;
35  typedef typename traits<XprType>::PointerType PointerType;
36 };
37 
38 template<typename CustomUnaryFunc, typename XprType>
39 struct eval<TensorCustomUnaryOp<CustomUnaryFunc, XprType>, Eigen::Dense>
40 {
41  typedef const TensorCustomUnaryOp<CustomUnaryFunc, XprType>EIGEN_DEVICE_REF type;
42 };
43 
44 template<typename CustomUnaryFunc, typename XprType>
45 struct nested<TensorCustomUnaryOp<CustomUnaryFunc, XprType> >
46 {
47  typedef TensorCustomUnaryOp<CustomUnaryFunc, XprType> type;
48 };
49 
50 } // end namespace internal
51 
52 
53 
54 template<typename CustomUnaryFunc, typename XprType>
55 class TensorCustomUnaryOp : public TensorBase<TensorCustomUnaryOp<CustomUnaryFunc, XprType>, ReadOnlyAccessors>
56 {
57  public:
58  typedef typename internal::traits<TensorCustomUnaryOp>::Scalar Scalar;
60  typedef typename XprType::CoeffReturnType CoeffReturnType;
61  typedef typename internal::nested<TensorCustomUnaryOp>::type Nested;
62  typedef typename internal::traits<TensorCustomUnaryOp>::StorageKind StorageKind;
63  typedef typename internal::traits<TensorCustomUnaryOp>::Index Index;
64 
65  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCustomUnaryOp(const XprType& expr, const CustomUnaryFunc& func)
66  : m_expr(expr), m_func(func) {}
67 
69  const CustomUnaryFunc& func() const { return m_func; }
70 
73  expression() const { return m_expr; }
74 
75  protected:
76  typename XprType::Nested m_expr;
77  const CustomUnaryFunc m_func;
78 };
79 
80 
81 // Eval as rvalue
82 template<typename CustomUnaryFunc, typename XprType, typename Device>
83 struct TensorEvaluator<const TensorCustomUnaryOp<CustomUnaryFunc, XprType>, Device>
84 {
86  typedef typename internal::traits<ArgType>::Index Index;
87  static constexpr int NumDims = internal::traits<ArgType>::NumDimensions;
89  typedef std::remove_const_t<typename ArgType::Scalar> Scalar;
90  typedef std::remove_const_t<typename XprType::CoeffReturnType> CoeffReturnType;
93  typedef typename Eigen::internal::traits<XprType>::PointerType TensorPointerType;
96 
98  enum {
99  IsAligned = false,
101  BlockAccess = false,
102  PreferBlockAccess = false,
103  CoordAccess = false, // to be implemented
104  RawAccess = false
105  };
106 
107  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
108  typedef internal::TensorBlockNotImplemented TensorBlock;
109  //===--------------------------------------------------------------------===//
110 
111  EIGEN_STRONG_INLINE TensorEvaluator(const ArgType& op, const Device& device)
112  : m_op(op), m_device(device), m_result(NULL)
113  {
114  m_dimensions = op.func().dimensions(op.expression());
115  }
116 
117  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
118 
119  EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType data) {
120  if (data) {
121  evalTo(data);
122  return false;
123  } else {
124  m_result = static_cast<EvaluatorPointerType>(m_device.get( (CoeffReturnType*)
125  m_device.allocate_temp(dimensions().TotalSize() * sizeof(Scalar))));
126  evalTo(m_result);
127  return true;
128  }
129  }
130 
131  EIGEN_STRONG_INLINE void cleanup() {
132  if (m_result) {
133  m_device.deallocate_temp(m_result);
134  m_result = NULL;
135  }
136  }
137 
138  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
139  return m_result[index];
140  }
141 
142  template<int LoadMode>
144  return internal::ploadt<PacketReturnType, LoadMode>(m_result + index);
145  }
146 
147  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
148  // TODO(rmlarsen): Extend CustomOp API to return its cost estimate.
149  return TensorOpCost(sizeof(CoeffReturnType), 0, 0, vectorized, PacketSize);
150  }
151 
152  EIGEN_DEVICE_FUNC EvaluatorPointerType data() const { return m_result; }
153 
154  protected:
157  m_op.func().eval(m_op.expression(), result, m_device);
158  }
159 
161  const ArgType m_op;
164 };
165 
166 
167 
175 namespace internal {
176 template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType>
177 struct traits<TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType> >
178 {
179  typedef typename internal::promote_storage_type<typename LhsXprType::Scalar,
180  typename RhsXprType::Scalar>::ret Scalar;
181  typedef typename internal::promote_storage_type<typename LhsXprType::CoeffReturnType,
182  typename RhsXprType::CoeffReturnType>::ret CoeffReturnType;
183  typedef typename promote_storage_type<typename traits<LhsXprType>::StorageKind,
184  typename traits<RhsXprType>::StorageKind>::ret StorageKind;
185  typedef typename promote_index_type<typename traits<LhsXprType>::Index,
186  typename traits<RhsXprType>::Index>::type Index;
187  typedef typename LhsXprType::Nested LhsNested;
188  typedef typename RhsXprType::Nested RhsNested;
189  typedef std::remove_reference_t<LhsNested> LhsNested_;
190  typedef std::remove_reference_t<RhsNested> RhsNested_;
191  static constexpr int NumDimensions = traits<LhsXprType>::NumDimensions;
192  static constexpr int Layout = traits<LhsXprType>::Layout;
193  typedef std::conditional_t<Pointer_type_promotion<typename LhsXprType::Scalar, Scalar>::val,
195 };
196 
197 template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType>
198 struct eval<TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType>, Eigen::Dense>
199 {
200  typedef const TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType>& type;
201 };
202 
203 template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType>
204 struct nested<TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType> >
205 {
206  typedef TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType> type;
207 };
208 
209 } // end namespace internal
210 
211 
212 
213 template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType>
214 class TensorCustomBinaryOp : public TensorBase<TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType>, ReadOnlyAccessors>
215 {
216  public:
217  typedef typename internal::traits<TensorCustomBinaryOp>::Scalar Scalar;
219  typedef typename internal::traits<TensorCustomBinaryOp>::CoeffReturnType CoeffReturnType;
220  typedef typename internal::nested<TensorCustomBinaryOp>::type Nested;
221  typedef typename internal::traits<TensorCustomBinaryOp>::StorageKind StorageKind;
222  typedef typename internal::traits<TensorCustomBinaryOp>::Index Index;
223 
224  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCustomBinaryOp(const LhsXprType& lhs, const RhsXprType& rhs, const CustomBinaryFunc& func)
225 
226  : m_lhs_xpr(lhs), m_rhs_xpr(rhs), m_func(func) {}
227 
229  const CustomBinaryFunc& func() const { return m_func; }
230 
233  lhsExpression() const { return m_lhs_xpr; }
234 
237  rhsExpression() const { return m_rhs_xpr; }
238 
239  protected:
240  typename LhsXprType::Nested m_lhs_xpr;
241  typename RhsXprType::Nested m_rhs_xpr;
242  const CustomBinaryFunc m_func;
243 };
244 
245 
246 // Eval as rvalue
247 template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType, typename Device>
248 struct TensorEvaluator<const TensorCustomBinaryOp<CustomBinaryFunc, LhsXprType, RhsXprType>, Device>
249 {
251  typedef typename internal::traits<XprType>::Index Index;
252  static constexpr int NumDims = internal::traits<XprType>::NumDimensions;
254  typedef typename XprType::Scalar Scalar;
255  typedef std::remove_const_t<typename XprType::CoeffReturnType> CoeffReturnType;
258 
259  typedef typename Eigen::internal::traits<XprType>::PointerType TensorPointerType;
262 
264  enum {
265  IsAligned = false,
267  BlockAccess = false,
268  PreferBlockAccess = false,
269  CoordAccess = false, // to be implemented
270  RawAccess = false
271  };
272 
273  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
274  typedef internal::TensorBlockNotImplemented TensorBlock;
275  //===--------------------------------------------------------------------===//
276 
277  EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
278  : m_op(op), m_device(device), m_result(NULL)
279  {
280  m_dimensions = op.func().dimensions(op.lhsExpression(), op.rhsExpression());
281  }
282 
283  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
284 
285  EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType data) {
286  if (data) {
287  evalTo(data);
288  return false;
289  } else {
290  m_result = static_cast<EvaluatorPointerType>(m_device.get( (CoeffReturnType*)
291  m_device.allocate_temp(dimensions().TotalSize() * sizeof(CoeffReturnType))));
292  evalTo(m_result);
293  return true;
294  }
295  }
296 
297  EIGEN_STRONG_INLINE void cleanup() {
298  if (m_result != NULL) {
299  m_device.deallocate_temp(m_result);
300  m_result = NULL;
301  }
302  }
303 
304  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
305  return m_result[index];
306  }
307 
308  template<int LoadMode>
310  return internal::ploadt<PacketReturnType, LoadMode>(m_result + index);
311  }
312 
313  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const {
314  // TODO(rmlarsen): Extend CustomOp API to return its cost estimate.
315  return TensorOpCost(sizeof(CoeffReturnType), 0, 0, vectorized, PacketSize);
316  }
317 
318  EIGEN_DEVICE_FUNC EvaluatorPointerType data() const { return m_result; }
319 
320 
321  protected:
324  m_op.func().eval(m_op.lhsExpression(), m_op.rhsExpression(), result, m_device);
325  }
326 
328  const XprType m_op;
331 };
332 
333 
334 } // end namespace Eigen
335 
336 #endif // EIGEN_CXX11_TENSOR_TENSOR_CUSTOM_OP_H
#define EIGEN_DEVICE_FUNC
#define EIGEN_DEVICE_REF
Definition: TensorMacros.h:36
The tensor base class.
Tensor custom class.
internal::traits< TensorCustomBinaryOp >::StorageKind StorageKind
const CustomBinaryFunc m_func
internal::traits< TensorCustomBinaryOp >::CoeffReturnType CoeffReturnType
internal::traits< TensorCustomBinaryOp >::Index Index
Eigen::NumTraits< Scalar >::Real RealScalar
TensorCustomBinaryOp(const LhsXprType &lhs, const RhsXprType &rhs, const CustomBinaryFunc &func)
const internal::remove_all_t< typename RhsXprType::Nested > & rhsExpression() const
const internal::remove_all_t< typename LhsXprType::Nested > & lhsExpression() const
LhsXprType::Nested m_lhs_xpr
RhsXprType::Nested m_rhs_xpr
internal::nested< TensorCustomBinaryOp >::type Nested
internal::traits< TensorCustomBinaryOp >::Scalar Scalar
const CustomBinaryFunc & func() const
Tensor custom class.
const CustomUnaryFunc & func() const
internal::traits< TensorCustomUnaryOp >::Index Index
Eigen::NumTraits< Scalar >::Real RealScalar
const internal::remove_all_t< typename XprType::Nested > & expression() const
const CustomUnaryFunc m_func
XprType::CoeffReturnType CoeffReturnType
TensorCustomUnaryOp(const XprType &expr, const CustomUnaryFunc &func)
internal::traits< TensorCustomUnaryOp >::StorageKind StorageKind
internal::traits< TensorCustomUnaryOp >::Scalar Scalar
internal::nested< TensorCustomUnaryOp >::type Nested
A tensor expression mapping an existing array of data.
Definition: TensorMap.h:32
typename remove_all< T >::type remove_all_t
: TensorContractionSycl.h, provides various tensor contraction kernel for SYCL backend
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
internal::packet_traits< Scalar >::type type
Definition: TensorMeta.h:55
std::remove_const_t< typename XprType::CoeffReturnType > CoeffReturnType
A cost model used to limit the number of threads used for evaluating tensor expression.
const Dimensions & dimensions() const
static constexpr int Layout
const Device EIGEN_DEVICE_REF m_device
static constexpr int PacketSize
EvaluatorPointerType data() const