Eigen  5.0.1
 
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_ASSIGNMENT_FUNCTORS_H
12#define EIGEN_ASSIGNMENT_FUNCTORS_H
13
14// IWYU pragma: private
15#include "../InternalHeaderCheck.h"
16
17namespace Eigen {
18
19namespace internal {
20
25template <typename DstScalar, typename SrcScalar>
26struct assign_op {
27 EIGEN_DEVICE_FUNC constexpr void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
28
29 template <int Alignment, typename Packet>
30 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
31 pstoret<DstScalar, Packet, Alignment>(a, b);
32 }
33
34 template <int Alignment, typename Packet>
35 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacketSegment(DstScalar* a, const Packet& b, Index begin,
36 Index count) const {
37 pstoretSegment<DstScalar, Packet, Alignment>(a, b, begin, count);
38 }
39};
40
41// Empty overload for void type (used by PermutationMatrix)
42template <typename DstScalar>
43struct assign_op<DstScalar, void> {};
44
45template <typename DstScalar, typename SrcScalar>
46struct functor_traits<assign_op<DstScalar, SrcScalar>> {
47 enum {
48 Cost = NumTraits<DstScalar>::ReadCost,
49 PacketAccess = std::is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::Vectorizable &&
50 packet_traits<SrcScalar>::Vectorizable
51 };
52};
53
58template <typename DstScalar, typename SrcScalar, typename Func>
59struct compound_assign_op {
60 using traits = functor_traits<compound_assign_op<DstScalar, SrcScalar, Func>>;
61 EIGEN_DEVICE_FUNC constexpr void assignCoeff(DstScalar& a, const SrcScalar& b) const {
62 assign_op<DstScalar, DstScalar>().assignCoeff(a, Func().operator()(a, b));
63 }
64
65 template <int Alignment, typename Packet>
66 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
67 assign_op<DstScalar, DstScalar>().template assignPacket<Alignment, Packet>(
68 a, Func().packetOp(ploadt<Packet, Alignment>(a), b));
69 }
70
71 template <int Alignment, typename Packet>
72 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacketSegment(DstScalar* a, const Packet& b, Index begin,
73 Index count) const {
74 assign_op<DstScalar, DstScalar>().template assignPacketSegment<Alignment, Packet>(
75 a, Func().packetOp(ploadtSegment<Packet, Alignment>(a, begin, count), b), begin, count);
76 }
77};
78
79template <typename DstScalar, typename SrcScalar, typename Func>
80struct functor_traits<compound_assign_op<DstScalar, SrcScalar, Func>> {
81 enum {
82 Cost = int(functor_traits<assign_op<DstScalar, DstScalar>>::Cost) + int(functor_traits<Func>::Cost),
83 PacketAccess = functor_traits<assign_op<DstScalar, DstScalar>>::PacketAccess && functor_traits<Func>::PacketAccess
84 };
85};
86
91template <typename DstScalar, typename SrcScalar = DstScalar>
92struct add_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_sum_op<DstScalar, SrcScalar>> {};
93
94template <typename DstScalar, typename SrcScalar>
95struct functor_traits<add_assign_op<DstScalar, SrcScalar>> : add_assign_op<DstScalar, SrcScalar>::traits {};
96
101template <typename DstScalar, typename SrcScalar = DstScalar>
102struct sub_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_difference_op<DstScalar, SrcScalar>> {
103 // Inner and matrix-vector products can bypass scalar_difference_op.
104 EIGEN_STATIC_ASSERT((!std::is_same<DstScalar, bool>::value || !std::is_same<SrcScalar, bool>::value),
105 BOOLEAN_SUBTRACTION_IS_NOT_SUPPORTED__CAST_TO_A_SIGNED_INTEGER_TYPE)
106};
107
108template <typename DstScalar, typename SrcScalar>
109struct functor_traits<sub_assign_op<DstScalar, SrcScalar>> : sub_assign_op<DstScalar, SrcScalar>::traits {};
110
115template <typename DstScalar, typename SrcScalar = DstScalar>
116struct mul_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_product_op<DstScalar, SrcScalar>> {};
117
118template <typename DstScalar, typename SrcScalar>
119struct functor_traits<mul_assign_op<DstScalar, SrcScalar>> : mul_assign_op<DstScalar, SrcScalar>::traits {};
120
125template <typename DstScalar, typename SrcScalar = DstScalar>
126struct div_assign_op : compound_assign_op<DstScalar, SrcScalar, scalar_quotient_op<DstScalar, SrcScalar>> {};
127
128template <typename DstScalar, typename SrcScalar>
129struct functor_traits<div_assign_op<DstScalar, SrcScalar>> : div_assign_op<DstScalar, SrcScalar>::traits {};
130
146template <typename Scalar>
147struct swap_assign_op {
148 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const {
149#ifdef EIGEN_GPUCC
150 // FIXME: check whether cuda::swap exists.
151 Scalar t = b;
152 const_cast<Scalar&>(b) = a;
153 a = t;
154#else
155 using std::swap;
156 swap(a, const_cast<Scalar&>(b));
157#endif
158 }
159};
160template <typename Scalar>
161struct functor_traits<swap_assign_op<Scalar>> {
162 enum {
163 Cost = 3 * NumTraits<Scalar>::ReadCost,
164 PacketAccess =
165#if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8, 0, 0) || EIGEN_COMP_CLANGAPPLE)
166 // This is a partial workaround for a bug in clang generating bad code
167 // when mixing 256/512 bits loads and 128 bits moves.
168 // See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
169 // https://bugs.llvm.org/show_bug.cgi?id=40815
170 0
171#else
172 packet_traits<Scalar>::Vectorizable
173#endif
174 };
175};
176
177} // namespace internal
178
179} // namespace Eigen
180
181#endif // EIGEN_ASSIGNMENT_FUNCTORS_H