DeviceWrapper.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) 2023 Charlie Schlosser <cs.schlosser@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_DEVICEWRAPPER_H
11 #define EIGEN_DEVICEWRAPPER_H
12 
13 namespace Eigen {
14 template <typename Derived, typename Device>
15 struct DeviceWrapper {
17  using Scalar = typename Derived::Scalar;
18 
21 
22  template <typename OtherDerived>
25  internal::call_assignment(*this, other.derived(), AssignOp());
26  return m_xpr;
27  }
28  template <typename OtherDerived>
31  internal::call_assignment(*this, other.derived(), AddAssignOp());
32  return m_xpr;
33  }
34  template <typename OtherDerived>
37  internal::call_assignment(*this, other.derived(), SubAssignOp());
38  return m_xpr;
39  }
40 
45  }
46 
47  Derived& m_xpr;
48  Device& m_device;
49 };
50 
51 namespace internal {
52 
53 // this is where we differentiate between lazy assignment and specialized kernels (e.g. matrix products)
54 template <typename DstXprType, typename SrcXprType, typename Functor, typename Device,
55  typename Kind = typename AssignmentKind<typename evaluator_traits<DstXprType>::Shape,
57  typename EnableIf = void>
59 
60 // unless otherwise specified, use the default product implementation
61 template <typename DstXprType, typename Lhs, typename Rhs, int Options, typename Functor, typename Device,
62  typename Weak>
63 struct AssignmentWithDevice<DstXprType, Product<Lhs, Rhs, Options>, Functor, Device, Dense2Dense, Weak> {
66  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src, const Functor& func,
67  Device&) {
68  Base::run(dst, src, func);
69  };
70 };
71 
72 // specialization for coeffcient-wise assignment
73 template <typename DstXprType, typename SrcXprType, typename Functor, typename Device, typename Weak>
74 struct AssignmentWithDevice<DstXprType, SrcXprType, Functor, Device, Dense2Dense, Weak> {
75  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src, const Functor& func,
76  Device& device) {
77 #ifndef EIGEN_NO_DEBUG
79 #endif
80 
81  call_dense_assignment_loop(dst, src, func, device);
82  }
83 };
84 
85 // this allows us to use the default evaluation scheme if it is not specialized for the device
86 template <typename Kernel, typename Device, int Traversal = Kernel::AssignmentTraits::Traversal,
87  int Unrolling = Kernel::AssignmentTraits::Unrolling>
90  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel& kernel, Device&) { Base::run(kernel); }
91 };
92 
93 // entry point for a generic expression with device
94 template <typename Dst, typename Src, typename Func, typename Device>
96  const Src& src, const Func& func) {
97  enum {
98  NeedToTranspose = ((int(Dst::RowsAtCompileTime) == 1 && int(Src::ColsAtCompileTime) == 1) ||
99  (int(Dst::ColsAtCompileTime) == 1 && int(Src::RowsAtCompileTime) == 1)) &&
100  int(Dst::SizeAtCompileTime) != 1
101  };
102 
103  using ActualDstTypeCleaned = std::conditional_t<NeedToTranspose, Transpose<Dst>, Dst>;
104  using ActualDstType = std::conditional_t<NeedToTranspose, Transpose<Dst>, Dst&>;
105  ActualDstType actualDst(dst.derived());
106 
107  // TODO check whether this is the right place to perform these checks:
109  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(ActualDstTypeCleaned, Src)
110  EIGEN_CHECK_BINARY_COMPATIBILIY(Func, typename ActualDstTypeCleaned::Scalar, typename Src::Scalar);
111 
112  // this provides a mechanism for specializing simple assignments, matrix products, etc
113  AssignmentWithDevice<ActualDstTypeCleaned, Src, Func, Device>::run(actualDst, src, func, dst.device());
114 }
115 
116 // copy and pasted from AssignEvaluator except forward device to kernel
117 template <typename DstXprType, typename SrcXprType, typename Functor, typename Device>
119  const SrcXprType& src,
120  const Functor& func,
121  Device& device) {
122  using DstEvaluatorType = evaluator<DstXprType>;
123  using SrcEvaluatorType = evaluator<SrcXprType>;
124 
125  SrcEvaluatorType srcEvaluator(src);
126 
127  // NOTE To properly handle A = (A*A.transpose())/s with A rectangular,
128  // we need to resize the destination after the source evaluator has been created.
129  resize_if_allowed(dst, src, func);
130 
131  DstEvaluatorType dstEvaluator(dst);
132 
134 
135  Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
136 
138 }
139 
140 } // namespace internal
141 
142 template <typename Derived>
143 template <typename Device>
145  return DeviceWrapper<Derived, Device>(derived(), device);
146 }
147 
148 template <typename Derived>
149 template <typename Device>
151  Device& device) const {
152  return DeviceWrapper<const Derived, Device>(derived(), device);
153 }
154 } // namespace Eigen
155 #endif
#define EIGEN_CONSTEXPR
Definition: Macros.h:758
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
#define EIGEN_STATIC_ASSERT_LVALUE(Derived)
Definition: StaticAssert.h:87
#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0, TYPE1)
Definition: StaticAssert.h:79
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP, LHS, RHS)
Definition: XprHelper.h:1082
SCALAR Scalar
Definition: bench_gemm.cpp:45
Pseudo expression providing an operator = assuming no aliasing.
Definition: NoAlias.h:34
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:202
Definition: AssignEvaluator.h:585
return int(ret)+1
@ Lhs
Definition: TensorContractionMapper.h:20
@ Rhs
Definition: TensorContractionMapper.h:20
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize_if_allowed(DstXprType &dst, const SrcXprType &src, const Functor &)
Definition: AssignEvaluator.h:703
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_assignment(Dst &dst, const Src &src)
Definition: AssignEvaluator.h:781
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void call_assignment_no_alias(Dst &dst, const Src &src, const Func &func)
Definition: AssignEvaluator.h:812
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void call_dense_assignment_loop(DstXprType &dst, const SrcXprType &src, const Functor &func)
Definition: AssignEvaluator.h:720
EIGEN_DEVICE_FUNC void check_for_aliasing(const Dst &dst, const Src &src)
Definition: Transpose.h:416
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
auto run(Kernel kernel, Args &&... args) -> decltype(kernel(args...))
Definition: gpu_test_helper.h:414
Definition: Eigen_Colamd.h:49
Definition: DeviceWrapper.h:15
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Device & device()
Definition: DeviceWrapper.h:42
typename Derived::Scalar Scalar
Definition: DeviceWrapper.h:17
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & operator-=(const EigenBase< OtherDerived > &other)
Definition: DeviceWrapper.h:35
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE NoAlias< DeviceWrapper, EigenBase > noalias()
Definition: DeviceWrapper.h:43
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & derived()
Definition: DeviceWrapper.h:41
Device & m_device
Definition: DeviceWrapper.h:48
EIGEN_DEVICE_FUNC DeviceWrapper(Base &xpr, Device &device)
Definition: DeviceWrapper.h:19
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & operator=(const EigenBase< OtherDerived > &other)
Definition: DeviceWrapper.h:23
EIGEN_DEVICE_FUNC DeviceWrapper(const Base &xpr, Device &device)
Definition: DeviceWrapper.h:20
Derived & m_xpr
Definition: DeviceWrapper.h:47
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & operator+=(const EigenBase< OtherDerived > &other)
Definition: DeviceWrapper.h:29
Definition: EigenBase.h:33
constexpr EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:49
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper< Derived, Device > device(Device &device)
Definition: DeviceWrapper.h:144
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func, Device &)
Definition: DeviceWrapper.h:66
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func, Device &device)
Definition: DeviceWrapper.h:75
Definition: DeviceWrapper.h:58
Definition: AssignEvaluator.h:773
Definition: AssignEvaluator.h:756
Template functor for scalar/packet assignment with addition.
Definition: AssignmentFunctors.h:52
Template functor for scalar/packet assignment.
Definition: AssignmentFunctors.h:25
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel, Device &)
Definition: DeviceWrapper.h:90
Definition: AssignEvaluator.h:302
storage_kind_to_shape< typename traits< T >::StorageKind >::Shape Shape
Definition: CoreEvaluators.h:90
Definition: CoreEvaluators.h:104
Template functor for scalar/packet assignment with subtraction.
Definition: AssignmentFunctors.h:73
Definition: NonLinearOptimization.cpp:97
Definition: benchGeometry.cpp:21
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317