$darkmode
Eigen  5.0.1-dev
AssignmentFunctors.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
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_ASSIGNMENT_FUNCTORS_H
11 #define EIGEN_ASSIGNMENT_FUNCTORS_H
12 
13 // IWYU pragma: private
14 #include "../InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
24 template <typename DstScalar, typename SrcScalar>
25 struct assign_op {
26  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
27 
28  template <int Alignment, typename Packet>
29  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
30  pstoret<DstScalar, Packet, Alignment>(a, b);
31  }
32 
33  template <int Alignment, typename Packet>
34  EIGEN_STRONG_INLINE void assignPacketSegment(DstScalar* a, const Packet& b, Index begin, Index count) const {
35  pstoretSegment<DstScalar, Packet, Alignment>(a, b, begin, count);
36  }
37 };
38 
39 // Empty overload for void type (used by PermutationMatrix)
40 template <typename DstScalar>
41 struct assign_op<DstScalar, void> {};
42 
43 template <typename DstScalar, typename SrcScalar>
44 struct functor_traits<assign_op<DstScalar, SrcScalar>> {
45  enum {
46  Cost = NumTraits<DstScalar>::ReadCost,
47  PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::Vectorizable &&
48  packet_traits<SrcScalar>::Vectorizable
49  };
50 };
51 
56 template <typename DstScalar, typename SrcScalar, typename Func>
57 struct compound_assign_op {
58  using traits = functor_traits<compound_assign_op<DstScalar, SrcScalar, Func>>;
59  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void assignCoeff(DstScalar& a, const SrcScalar& b) const {
60  assign_op<DstScalar, DstScalar>().assignCoeff(a, Func().operator()(a, b));
61  }
62 
63  template <int Alignment, typename Packet>
64  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
65  assign_op<DstScalar, DstScalar>().template assignPacket<Alignment, Packet>(
66  a, Func().packetOp(ploadt<Packet, Alignment>(a), b));
67  }
68 
69  template <int Alignment, typename Packet>
70  EIGEN_STRONG_INLINE void assignPacketSegment(DstScalar* a, const Packet& b, Index begin, Index count) const {
71  assign_op<DstScalar, DstScalar>().template assignPacketSegment<Alignment, Packet>(
72  a, Func().packetOp(ploadtSegment<Packet, Alignment>(a, begin, count), b), begin, count);
73  }
74 };
75 
76 template <typename DstScalar, typename SrcScalar, typename Func>
77 struct functor_traits<compound_assign_op<DstScalar, SrcScalar, Func>> {
78  enum {
79  Cost = int(functor_traits<assign_op<DstScalar, DstScalar>>::Cost) + int(functor_traits<Func>::Cost),
80  PacketAccess = functor_traits<assign_op<DstScalar, DstScalar>>::PacketAccess && functor_traits<Func>::PacketAccess
81  };
82 };
83 
88 template <typename DstScalar, typename SrcScalar = DstScalar>
89 struct add_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_sum_op<DstScalar, SrcScalar>> {};
90 
91 template <typename DstScalar, typename SrcScalar>
92 struct functor_traits<add_assign_op<DstScalar, SrcScalar>> : add_assign_op<DstScalar, SrcScalar>::traits {};
93 
98 template <typename DstScalar, typename SrcScalar = DstScalar>
99 struct sub_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_difference_op<DstScalar, SrcScalar>> {};
100 
101 template <typename DstScalar, typename SrcScalar>
102 struct functor_traits<sub_assign_op<DstScalar, SrcScalar>> : sub_assign_op<DstScalar, SrcScalar>::traits {};
103 
108 template <typename DstScalar, typename SrcScalar = DstScalar>
109 struct mul_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_product_op<DstScalar, SrcScalar>> {};
110 
111 template <typename DstScalar, typename SrcScalar>
112 struct functor_traits<mul_assign_op<DstScalar, SrcScalar>> : mul_assign_op<DstScalar, SrcScalar>::traits {};
113 
118 template <typename DstScalar, typename SrcScalar = DstScalar>
119 struct div_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_quotient_op<DstScalar, SrcScalar>> {};
120 
121 template <typename DstScalar, typename SrcScalar>
122 struct functor_traits<div_assign_op<DstScalar, SrcScalar>> : div_assign_op<DstScalar, SrcScalar>::traits {};
123 
139 template <typename Scalar>
140 struct swap_assign_op {
141  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const {
142 #ifdef EIGEN_GPUCC
143  // FIXME is there some kind of cuda::swap?
144  Scalar t = b;
145  const_cast<Scalar&>(b) = a;
146  a = t;
147 #else
148  using std::swap;
149  swap(a, const_cast<Scalar&>(b));
150 #endif
151  }
152 };
153 template <typename Scalar>
154 struct functor_traits<swap_assign_op<Scalar>> {
155  enum {
156  Cost = 3 * NumTraits<Scalar>::ReadCost,
157  PacketAccess =
158 #if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8, 0, 0) || EIGEN_COMP_CLANGAPPLE)
159  // This is a partial workaround for a bug in clang generating bad code
160  // when mixing 256/512 bits loads and 128 bits moves.
161  // See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
162  // https://bugs.llvm.org/show_bug.cgi?id=40815
163  0
164 #else
165  packet_traits<Scalar>::Vectorizable
166 #endif
167  };
168 };
169 
170 } // namespace internal
171 
172 } // namespace Eigen
173 
174 #endif // EIGEN_ASSIGNMENT_FUNCTORS_H
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
std::enable_if_t< std::is_base_of< DenseBase< std::decay_t< DerivedA > >, std::decay_t< DerivedA > >::value &&std::is_base_of< DenseBase< std::decay_t< DerivedB > >, std::decay_t< DerivedB > >::value, void > swap(DerivedA &&a, DerivedB &&b)
Definition: DenseBase.h:667