TensorConversion.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) 2015 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_CONVERSION_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_CONVERSION_H
12 
13 namespace Eigen {
14 
22 namespace internal {
23 template<typename TargetType, typename XprType>
24 struct traits<TensorConversionOp<TargetType, XprType> >
25 {
26  // Type promotion to handle the case where the types of the lhs and the rhs are different.
27  typedef TargetType Scalar;
29  typedef typename traits<XprType>::Index Index;
30  typedef typename XprType::Nested Nested;
32  static const int NumDimensions = traits<XprType>::NumDimensions;
33  static const int Layout = traits<XprType>::Layout;
34  enum { Flags = 0 };
36 };
37 
38 template<typename TargetType, typename XprType>
39 struct eval<TensorConversionOp<TargetType, XprType>, Eigen::Dense>
40 {
42 };
43 
44 template<typename TargetType, typename XprType>
45 struct nested<TensorConversionOp<TargetType, XprType>, 1, typename eval<TensorConversionOp<TargetType, XprType> >::type>
46 {
48 };
49 
50 } // end namespace internal
51 
52 
53 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket, int SrcCoeffRatio, int TgtCoeffRatio>
55 
56 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket>
57 struct PacketConverter<TensorEvaluator, SrcPacket, TgtPacket, 1, 1> {
60  : m_impl(impl) {}
61 
62  template<int LoadMode, typename Index>
64  return internal::pcast<SrcPacket, TgtPacket>(m_impl.template packet<LoadMode>(index));
65  }
66 
67  private:
69 };
70 
71 
72 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket>
73 struct PacketConverter<TensorEvaluator, SrcPacket, TgtPacket, 2, 1> {
76  : m_impl(impl) {}
77 
78  template<int LoadMode, typename Index>
80  const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size;
81 
82  SrcPacket src1 = m_impl.template packet<LoadMode>(index);
83  SrcPacket src2 = m_impl.template packet<LoadMode>(index + SrcPacketSize);
84  TgtPacket result = internal::pcast<SrcPacket, TgtPacket>(src1, src2);
85  return result;
86  }
87 
88  private:
90 };
91 
92 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket>
93 struct PacketConverter<TensorEvaluator, SrcPacket, TgtPacket, 4, 1> {
96  : m_impl(impl) {}
97 
98  template<int LoadMode, typename Index>
100  const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size;
101 
102  SrcPacket src1 = m_impl.template packet<LoadMode>(index);
103  SrcPacket src2 = m_impl.template packet<LoadMode>(index + SrcPacketSize);
104  SrcPacket src3 = m_impl.template packet<LoadMode>(index + 2 * SrcPacketSize);
105  SrcPacket src4 = m_impl.template packet<LoadMode>(index + 3 * SrcPacketSize);
106  TgtPacket result = internal::pcast<SrcPacket, TgtPacket>(src1, src2, src3, src4);
107  return result;
108  }
109 
110  private:
112 };
113 
114 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket>
115 struct PacketConverter<TensorEvaluator, SrcPacket, TgtPacket, 8, 1> {
118  : m_impl(impl) {}
119 
120  template<int LoadMode, typename Index>
122  const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size;
123 
124  SrcPacket src1 = m_impl.template packet<LoadMode>(index);
125  SrcPacket src2 = m_impl.template packet<LoadMode>(index + 1 * SrcPacketSize);
126  SrcPacket src3 = m_impl.template packet<LoadMode>(index + 2 * SrcPacketSize);
127  SrcPacket src4 = m_impl.template packet<LoadMode>(index + 3 * SrcPacketSize);
128  SrcPacket src5 = m_impl.template packet<LoadMode>(index + 4 * SrcPacketSize);
129  SrcPacket src6 = m_impl.template packet<LoadMode>(index + 5 * SrcPacketSize);
130  SrcPacket src7 = m_impl.template packet<LoadMode>(index + 6 * SrcPacketSize);
131  SrcPacket src8 = m_impl.template packet<LoadMode>(index + 7 * SrcPacketSize);
132  TgtPacket result = internal::pcast<SrcPacket, TgtPacket>(src1, src2, src3, src4, src5, src6, src7, src8);
133  return result;
134  }
135 
136  private:
138 };
139 
140 template <typename TensorEvaluator, typename SrcPacket, typename TgtPacket, int TgtCoeffRatio>
141 struct PacketConverter<TensorEvaluator, SrcPacket, TgtPacket, 1, TgtCoeffRatio> {
144  : m_impl(impl), m_maxIndex(impl.dimensions().TotalSize()) {}
145 
146  template<int LoadMode, typename Index>
148  const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size;
149  // Only call m_impl.packet() when we have direct access to the underlying data. This
150  // ensures that we don't compute the subexpression twice. We may however load some
151  // coefficients twice, but in practice this doesn't negatively impact performance.
152  if (m_impl.data() && (index + SrcPacketSize < m_maxIndex)) {
153  // Force unaligned memory loads since we can't ensure alignment anymore
154  return internal::pcast<SrcPacket, TgtPacket>(m_impl.template packet<Unaligned>(index));
155  } else {
156  const int TgtPacketSize = internal::unpacket_traits<TgtPacket>::size;
157  typedef typename internal::unpacket_traits<SrcPacket>::type SrcType;
158  typedef typename internal::unpacket_traits<TgtPacket>::type TgtType;
162  for (int i = 0; i < TgtPacketSize; ++i) {
163  values[i] = converter(m_impl.coeff(index+i));
164  }
165  TgtPacket rslt = internal::pload<TgtPacket>(values);
166  return rslt;
167  }
168  }
169 
170  private:
173 };
174 
175 template<typename TargetType, typename XprType>
176 class TensorConversionOp : public TensorBase<TensorConversionOp<TargetType, XprType>, ReadOnlyAccessors>
177 {
178  public:
183  typedef Scalar CoeffReturnType;
185 
187  : m_xpr(xpr) {}
188 
191  expression() const { return m_xpr; }
192 
193  protected:
194  typename XprType::Nested m_xpr;
195 };
196 
197 template <bool SameType, typename Eval, typename EvalPointerType> struct ConversionSubExprEval {
198  static EIGEN_STRONG_INLINE bool run(Eval& impl, EvalPointerType) {
199  impl.evalSubExprsIfNeeded(NULL);
200  return true;
201  }
202 };
203 
204 template <typename Eval, typename EvalPointerType> struct ConversionSubExprEval<true, Eval, EvalPointerType> {
205  static EIGEN_STRONG_INLINE bool run(Eval& impl, EvalPointerType data) {
206  return impl.evalSubExprsIfNeeded(data);
207  }
208 };
209 
210 #ifdef EIGEN_USE_THREADS
211 template <bool SameType, typename Eval, typename EvalPointerType,
212  typename EvalSubExprsCallback>
213 struct ConversionSubExprEvalAsync {
214  static EIGEN_STRONG_INLINE void run(Eval& impl, EvalPointerType, EvalSubExprsCallback done) {
215  impl.evalSubExprsIfNeededAsync(nullptr, std::move(done));
216  }
217 };
218 
219 template <typename Eval, typename EvalPointerType,
220  typename EvalSubExprsCallback>
221 struct ConversionSubExprEvalAsync<true, Eval, EvalPointerType,
222  EvalSubExprsCallback> {
223  static EIGEN_STRONG_INLINE void run(Eval& impl, EvalPointerType data, EvalSubExprsCallback done) {
224  impl.evalSubExprsIfNeededAsync(data, std::move(done));
225  }
226 };
227 #endif
228 
229 namespace internal {
230 
231 template <typename SrcType, typename TargetType, bool IsSameT>
232 struct CoeffConv {
233  template <typename ArgType, typename Device>
236  return converter(impl.coeff(index));
237  }
238 };
239 
240 template <typename SrcType, typename TargetType>
241 struct CoeffConv<SrcType, TargetType, true> {
242  template <typename ArgType, typename Device>
244  return impl.coeff(index);
245  }
246 };
247 
248 template <typename SrcPacket, typename TargetPacket, int LoadMode, bool ActuallyVectorize, bool IsSameT>
249 struct PacketConv {
252 
253  static const int PacketSize = internal::unpacket_traits<TargetPacket>::size;
254 
255  template <typename ArgType, typename Device>
260  for (int i = 0; i < PacketSize; ++i) {
261  values[i] = converter(impl.coeff(index+i));
262  }
263  TargetPacket rslt = internal::pload<TargetPacket>(values);
264  return rslt;
265  }
266 };
267 
268 template <typename SrcPacket, typename TargetPacket, int LoadMode, bool IsSameT>
269 struct PacketConv<SrcPacket, TargetPacket, LoadMode, true, IsSameT> {
272 
273  template <typename ArgType, typename Device>
277  PacketConverter<TensorEvaluator<ArgType, Device>, SrcPacket, TargetPacket,
278  SrcCoeffRatio, TgtCoeffRatio> converter(impl);
279  return converter.template packet<LoadMode>(index);
280  }
281 };
282 
283 template <typename SrcPacket, typename TargetPacket, int LoadMode>
284 struct PacketConv<SrcPacket, TargetPacket, LoadMode, /*ActuallyVectorize=*/false, /*IsSameT=*/true> {
286  static const int PacketSize = internal::unpacket_traits<TargetPacket>::size;
287 
288  template <typename ArgType, typename Device>
291  for (int i = 0; i < PacketSize; ++i) values[i] = impl.coeff(index+i);
292  return internal::pload<TargetPacket>(values);
293  }
294 };
295 
296 template <typename SrcPacket, typename TargetPacket, int LoadMode>
297 struct PacketConv<SrcPacket, TargetPacket, LoadMode, /*ActuallyVectorize=*/true, /*IsSameT=*/true> {
298  template <typename ArgType, typename Device>
300  return impl.template packet<LoadMode>(index);
301  }
302 };
303 
304 } // namespace internal
305 
306 // Eval as rvalue
307 template<typename TargetType, typename ArgType, typename Device>
308 struct TensorEvaluator<const TensorConversionOp<TargetType, ArgType>, Device>
309 {
311  typedef typename XprType::Index Index;
313  typedef TargetType Scalar;
314  typedef TargetType CoeffReturnType;
318  static const int PacketSize = PacketType<CoeffReturnType, Device>::size;
319  static const bool IsSameType = internal::is_same<TargetType, SrcType>::value;
322 
323  enum {
324  IsAligned = false,
325  PacketAccess =
326  #ifndef EIGEN_USE_SYCL
327  true,
328  #else
331  #endif
335  RawAccess = false
336  };
337 
338  static const int NumDims = internal::array_size<Dimensions>::value;
339 
340  //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
343 
346 
347  struct TensorConversionOpBlockFactory {
348  template <typename ArgXprType>
349  struct XprType {
351  };
352 
353  template <typename ArgXprType>
354  typename XprType<ArgXprType>::type expr(const ArgXprType& expr) const {
355  return typename XprType<ArgXprType>::type(expr);
356  }
357  };
358 
359  typedef internal::TensorUnaryExprBlock<TensorConversionOpBlockFactory,
362  //===--------------------------------------------------------------------===//
363 
364  EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
365  : m_impl(op.expression(), device)
366  {
367  }
368 
369  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_impl.dimensions(); }
370 
371  EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType data)
372  {
373  return ConversionSubExprEval<IsSameType, TensorEvaluator<ArgType, Device>, EvaluatorPointerType>::run(m_impl, data);
374  }
375 
376 #ifdef EIGEN_USE_THREADS
377  template <typename EvalSubExprsCallback>
378  EIGEN_STRONG_INLINE void evalSubExprsIfNeededAsync(
379  EvaluatorPointerType data, EvalSubExprsCallback done) {
380  ConversionSubExprEvalAsync<IsSameType, TensorEvaluator<ArgType, Device>,
381  EvaluatorPointerType,
382  EvalSubExprsCallback>::run(m_impl, data, std::move(done));
383  }
384 #endif
385 
387  {
388  m_impl.cleanup();
389  }
390 
391  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
392  {
394  }
395 
396  template<int LoadMode>
397  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType
398  packet(Index index) const {
399  // If we are not going to do the cast, we just need to check that base
400  // TensorEvaluator has packet access. Otherwise we also need to make sure,
401  // that we have an implementation of vectorized cast.
402  const bool Vectorizable =
403  IsSameType
407 
408  return internal::PacketConv<PacketSourceType, PacketReturnType, LoadMode,
409  Vectorizable, IsSameType>::run(m_impl, index);
410  }
411 
413  costPerCoeff(bool vectorized) const {
414  const double cast_cost = TensorOpCost::CastCost<SrcType, TargetType>();
415  if (vectorized) {
416  const double SrcCoeffRatio =
418  const double TgtCoeffRatio =
420  return m_impl.costPerCoeff(vectorized) * (SrcCoeffRatio / PacketSize) +
421  TensorOpCost(0, 0, TgtCoeffRatio * (cast_cost / PacketSize));
422  } else {
423  return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, 0, cast_cost);
424  }
425  }
426 
429  return m_impl.getResourceRequirements();
430  }
431 
433  block(TensorBlockDesc& desc, TensorBlockScratch& scratch,
434  bool /*root_of_expr_ast*/ = false) const {
435  return TensorBlock(m_impl.block(desc, scratch),
436  TensorConversionOpBlockFactory());
437  }
438 
439  EIGEN_DEVICE_FUNC EvaluatorPointerType data() const { return NULL; }
440 
442  const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
443 #ifdef EIGEN_USE_SYCL
444  // binding placeholder accessors to a command group handler for SYCL
445  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void bind(cl::sycl::handler &cgh) const {
446  m_impl.bind(cgh);
447  }
448 #endif
449 
450  protected:
452 };
453 
454 } // end namespace Eigen
455 
456 #endif // EIGEN_CXX11_TENSOR_TENSOR_CONVERSION_H
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const
#define EIGEN_STRONG_INLINE
Definition: Macros.h:917
const TensorEvaluator< ArgType, Device > & impl() const
required by sycl in order to extract the sycl accessor
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetPacket run(const TensorEvaluator< ArgType, Device > &impl, Index index)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket packet(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorConversionOp(const XprType &xpr)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket packet(Index index) const
internal::unpacket_traits< TargetPacket >::type TargetType
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetPacket run(const TensorEvaluator< ArgType, Device > &impl, Index index)
leaf::MyValues values
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
A cost model used to limit the number of threads used for evaluating tensor expression.
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetType run(const TensorEvaluator< ArgType, Device > &impl, Index index)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
#define EIGEN_ALIGN_MAX
internal::nested< TensorConversionOp >::type Nested
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorBlock block(TensorBlockDesc &desc, TensorBlockScratch &scratch, bool=false) const
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetType run(const TensorEvaluator< ArgType, Device > &impl, Index index)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketConverter(const TensorEvaluator &impl)
internal::remove_all< typename internal::traits< ArgType >::Scalar >::type SrcType
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition: CwiseBinaryOp.h:77
internal::TensorUnaryExprBlock< TensorConversionOpBlockFactory, ArgTensorBlock > TensorBlock
TensorEvaluator< const ArgType, Device >::TensorBlock ArgTensorBlock
NumTraits< Scalar >::Real RealScalar
Values result
internal::traits< TensorConversionOp >::StorageKind StorageKind
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketConverter(const TensorEvaluator &impl)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
int data[]
Tensor conversion class. This class makes it possible to vectorize type casting operations when the n...
internal::traits< TensorConversionOp >::Scalar Scalar
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketConverter(const TensorEvaluator &impl)
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType data)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
#define NULL
Definition: ccolamd.c:609
internal::traits< TensorConversionOp >::Index Index
TypeConversion< Scalar, typename traits< XprType >::PointerType >::type PointerType
The tensor base class.
Definition: TensorBase.h:973
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:976
static EIGEN_STRONG_INLINE bool run(Eval &impl, EvalPointerType data)
static EIGEN_STRONG_INLINE bool run(Eval &impl, EvalPointerType)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket packet(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE internal::TensorBlockResourceRequirements getResourceRequirements() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:55
EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketConverter(const TensorEvaluator &impl)
EIGEN_DEVICE_FUNC const internal::remove_all< typename XprType::Nested >::type & expression() const
const std::vector< size_t > dimensions
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetPacket run(const TensorEvaluator< ArgType, Device > &impl, Index index)
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TargetPacket run(const TensorEvaluator< ArgType, Device > &impl, Index index)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket packet(Index index) const
Definition: pytypes.h:1370
#define EIGEN_UNROLL_LOOP
Definition: Macros.h:1461
internal::unpacket_traits< SrcPacket >::type SrcType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket packet(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketConverter(const TensorEvaluator &impl)


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:36:48