Eigen  5.0.1-dev+60122df6
 
Loading...
Searching...
No Matches
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
16namespace Eigen {
17
18namespace internal {
19
24template <typename DstScalar, typename SrcScalar>
25struct 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)
40template <typename DstScalar>
41struct assign_op<DstScalar, void> {};
42
43template <typename DstScalar, typename SrcScalar>
44struct 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
56template <typename DstScalar, typename SrcScalar, typename Func>
57struct 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
76template <typename DstScalar, typename SrcScalar, typename Func>
77struct 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
88template <typename DstScalar, typename SrcScalar = DstScalar>
89struct add_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_sum_op<DstScalar, SrcScalar>> {};
90
91template <typename DstScalar, typename SrcScalar>
92struct functor_traits<add_assign_op<DstScalar, SrcScalar>> : add_assign_op<DstScalar, SrcScalar>::traits {};
93
98template <typename DstScalar, typename SrcScalar = DstScalar>
99struct sub_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_difference_op<DstScalar, SrcScalar>> {};
100
101template <typename DstScalar, typename SrcScalar>
102struct functor_traits<sub_assign_op<DstScalar, SrcScalar>> : sub_assign_op<DstScalar, SrcScalar>::traits {};
103
108template <typename DstScalar, typename SrcScalar = DstScalar>
109struct mul_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_product_op<DstScalar, SrcScalar>> {};
110
111template <typename DstScalar, typename SrcScalar>
112struct functor_traits<mul_assign_op<DstScalar, SrcScalar>> : mul_assign_op<DstScalar, SrcScalar>::traits {};
113
118template <typename DstScalar, typename SrcScalar = DstScalar>
119struct div_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_quotient_op<DstScalar, SrcScalar>> {};
120
121template <typename DstScalar, typename SrcScalar>
122struct functor_traits<div_assign_op<DstScalar, SrcScalar>> : div_assign_op<DstScalar, SrcScalar>::traits {};
123
139template <typename Scalar>
140struct 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};
153template <typename Scalar>
154struct 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
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
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82