11#ifndef EIGEN_GENERIC_PACKET_MATH_H
12#define EIGEN_GENERIC_PACKET_MATH_H
15#include "./InternalHeaderCheck.h"
29#ifndef EIGEN_DEBUG_ALIGNED_LOAD
30#define EIGEN_DEBUG_ALIGNED_LOAD
33#ifndef EIGEN_DEBUG_UNALIGNED_LOAD
34#define EIGEN_DEBUG_UNALIGNED_LOAD
37#ifndef EIGEN_DEBUG_ALIGNED_STORE
38#define EIGEN_DEBUG_ALIGNED_STORE
41#ifndef EIGEN_DEBUG_UNALIGNED_STORE
42#define EIGEN_DEBUG_UNALIGNED_STORE
45struct default_packet_traits {
102 HasGammaSampleDerAlpha = 0,
109struct packet_traits : default_packet_traits {
132struct packet_traits<const T> : packet_traits<T> {};
135struct unpacket_traits {
138 typedef typename numext::get_integer_by_size<
sizeof(T)>::signed_type integer_packet;
141 alignment =
alignof(T),
142 vectorizable =
false,
143 masked_load_available =
false,
144 masked_store_available =
false
149struct unpacket_traits<const T> : unpacket_traits<T> {};
154template <
typename Packet>
156 using Scalar =
typename unpacket_traits<Packet>::type;
157 enum { value = internal::is_same<Packet, Scalar>::value };
164template <
typename SrcPacket,
typename TgtPacket,
165 bool Scalar = is_scalar<SrcPacket>::value && is_scalar<TgtPacket>::value>
166struct is_degenerate_helper : is_same<SrcPacket, TgtPacket> {};
168struct is_degenerate_helper<int8_t, uint8_t, true> : std::true_type {};
170struct is_degenerate_helper<int16_t, uint16_t, true> : std::true_type {};
172struct is_degenerate_helper<int32_t, uint32_t, true> : std::true_type {};
174struct is_degenerate_helper<int64_t, uint64_t, true> : std::true_type {};
176template <
typename SrcPacket,
typename TgtPacket>
177struct is_degenerate_helper<SrcPacket, TgtPacket, false> {
178 using SrcScalar =
typename unpacket_traits<SrcPacket>::type;
179 static constexpr int SrcSize = unpacket_traits<SrcPacket>::size;
180 using TgtScalar =
typename unpacket_traits<TgtPacket>::type;
181 static constexpr int TgtSize = unpacket_traits<TgtPacket>::size;
182 static constexpr bool value = is_degenerate_helper<SrcScalar, TgtScalar, true>::value && (SrcSize == TgtSize);
186template <
typename SrcPacket,
typename TgtPacket>
187struct is_degenerate {
188 static constexpr bool value =
189 is_degenerate_helper<SrcPacket, TgtPacket>::value || is_degenerate_helper<TgtPacket, SrcPacket>::value;
192template <
typename Packet>
194 using Scalar =
typename unpacket_traits<Packet>::type;
195 static constexpr int Size = unpacket_traits<Packet>::size;
196 using DefaultPacket =
typename packet_traits<Scalar>::type;
197 static constexpr int DefaultSize = unpacket_traits<DefaultPacket>::size;
198 static constexpr bool value = Size != 1 && Size < DefaultSize;
201template <
typename Src,
typename Tgt>
202struct type_casting_traits {
205 is_degenerate<Src, Tgt>::value && packet_traits<Src>::Vectorizable && packet_traits<Tgt>::Vectorizable,
212template <
typename Src,
typename Tgt>
213struct vectorized_type_casting_traits {
215 DefaultSrcPacketSize = packet_traits<Src>::size,
216 DefaultTgtPacketSize = packet_traits<Tgt>::size,
218 SrcCoeffRatio = plain_enum_max(DefaultTgtPacketSize / DefaultSrcPacketSize, 1),
219 TgtCoeffRatio = plain_enum_max(DefaultSrcPacketSize / DefaultTgtPacketSize, 1)
225template <
typename T,
int unique_
id = 0>
226struct eigen_packet_wrapper {
227 EIGEN_ALWAYS_INLINE
operator T&() {
return m_val; }
228 EIGEN_ALWAYS_INLINE
operator const T&()
const {
return m_val; }
229 EIGEN_ALWAYS_INLINE eigen_packet_wrapper() =
default;
230 EIGEN_ALWAYS_INLINE eigen_packet_wrapper(
const T& v) : m_val(v) {}
231 EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(
const T& v) {
239template <typename Target, typename Packet, bool IsSame = is_same<Target, Packet>::value>
240struct preinterpret_generic;
242template <
typename Target,
typename Packet>
243struct preinterpret_generic<Target, Packet, false> {
245 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Target run(
const Packet& a) {
246 return numext::bit_cast<Target, Packet>(a);
250template <
typename Packet>
251struct preinterpret_generic<Packet, Packet, true> {
253 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(
const Packet& a) {
return a; }
256template <
typename ComplexPacket>
257struct preinterpret_generic<typename unpacket_traits<ComplexPacket>::as_real, ComplexPacket, false> {
258 using RealPacket =
typename unpacket_traits<ComplexPacket>::as_real;
259 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE RealPacket run(
const ComplexPacket& a) {
return a.v; }
263template <
typename Target,
typename Packet>
264EIGEN_DEVICE_FUNC
inline Target preinterpret(
const Packet& a) {
265 return preinterpret_generic<Target, Packet>::run(a);
268template <typename SrcPacket, typename TgtPacket, bool Degenerate = is_degenerate<SrcPacket, TgtPacket>::value,
269 bool TgtIsHalf = is_half<TgtPacket>::value>
272template <
typename SrcPacket,
typename TgtPacket>
273struct pcast_generic<SrcPacket, TgtPacket, false, false> {
275 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
276 return cast_impl<SrcPacket, TgtPacket>::run(a);
280template <
typename Packet>
281struct pcast_generic<Packet, Packet, true, false> {
283 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(
const Packet& a) {
return a; }
286template <
typename SrcPacket,
typename TgtPacket,
bool TgtIsHalf>
287struct pcast_generic<SrcPacket, TgtPacket, true, TgtIsHalf> {
289 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
return preinterpret<TgtPacket>(a); }
293template <
typename SrcPacket,
typename TgtPacket>
294EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a) {
295 return pcast_generic<SrcPacket, TgtPacket>::run(a);
297template <
typename SrcPacket,
typename TgtPacket>
298EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b) {
299 return pcast_generic<SrcPacket, TgtPacket>::run(a, b);
301template <
typename SrcPacket,
typename TgtPacket>
302EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b,
const SrcPacket& c,
303 const SrcPacket& d) {
304 return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d);
306template <
typename SrcPacket,
typename TgtPacket>
307EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b,
const SrcPacket& c,
const SrcPacket& d,
308 const SrcPacket& e,
const SrcPacket& f,
const SrcPacket& g,
309 const SrcPacket& h) {
310 return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d, e, f, g, h);
313template <
typename SrcPacket,
typename TgtPacket>
314struct pcast_generic<SrcPacket, TgtPacket, false, true> {
317 using DefaultTgtPacket =
typename is_half<TgtPacket>::DefaultPacket;
318 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
319 return preinterpret<TgtPacket>(pcast<SrcPacket, DefaultTgtPacket>(a));
324template <
typename Packet>
325EIGEN_DEVICE_FUNC
inline Packet padd(
const Packet& a,
const Packet& b) {
330EIGEN_DEVICE_FUNC
inline bool padd(
const bool& a,
const bool& b) {
338template <
typename Packet>
339EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_fpops_available, Packet> padd(
340 const Packet& a,
const Packet& b,
typename unpacket_traits<Packet>::mask_t umask);
343template <
typename Packet>
344EIGEN_DEVICE_FUNC
inline Packet psub(
const Packet& a,
const Packet& b) {
349template <
typename Packet>
350EIGEN_DEVICE_FUNC
inline Packet pnegate(
const Packet& a) {
351 EIGEN_STATIC_ASSERT((!is_same<
typename unpacket_traits<Packet>::type,
bool>::value),
352 NEGATE IS NOT DEFINED FOR BOOLEAN TYPES)
353 return numext::negate(a);
357template <
typename Packet>
358EIGEN_DEVICE_FUNC
inline Packet pconj(
const Packet& a) {
359 return numext::conj(a);
363template <
typename Packet>
364EIGEN_DEVICE_FUNC
inline Packet pmul(
const Packet& a,
const Packet& b) {
369EIGEN_DEVICE_FUNC
inline bool pmul(
const bool& a,
const bool& b) {
374template <
typename Packet>
375EIGEN_DEVICE_FUNC
inline Packet pdiv(
const Packet& a,
const Packet& b) {
380EIGEN_DEVICE_FUNC
inline bool pdiv(
const bool& a,
const bool& b) {
385template <
typename Packet,
typename EnableIf =
void>
387 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& ) {
389 memset(
static_cast<void*
>(&b), 0xff,
sizeof(Packet));
395template <
typename Scalar>
396struct ptrue_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value>> {
397 static EIGEN_DEVICE_FUNC
inline Scalar run(
const Scalar&) {
return Scalar(1); }
402struct ptrue_impl<bool, void> {
403 static EIGEN_DEVICE_FUNC
inline bool run(
const bool&) {
return true; }
407template <
typename Packet>
408EIGEN_DEVICE_FUNC
inline Packet ptrue(
const Packet& a) {
409 return ptrue_impl<Packet>::run(a);
413template <
typename Packet,
typename EnableIf =
void>
415 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& ) {
417 memset(
static_cast<void*
>(&b), 0x00,
sizeof(Packet));
425struct pzero_impl<T, std::enable_if_t<is_scalar<T>::value>> {
426 static EIGEN_DEVICE_FUNC
inline T run(
const T& ) {
return T(0); }
430template <
typename Packet>
431EIGEN_DEVICE_FUNC
inline Packet pzero(
const Packet& a) {
432 return pzero_impl<Packet>::run(a);
437 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a & b; }
442 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a | b; }
447 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a ^ b; }
452 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a)
const {
return ~a; }
456struct bit_and<bool> {
457 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a && b; }
462 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a || b; }
466struct bit_xor<bool> {
467 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a != b; }
471struct bit_not<bool> {
472 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a)
const {
return !a; }
477struct operator_bitwise_helper {
478 EIGEN_DEVICE_FUNC
static inline T bitwise_and(
const T& a,
const T& b) {
return bit_and<T>()(a, b); }
479 EIGEN_DEVICE_FUNC
static inline T bitwise_or(
const T& a,
const T& b) {
return bit_or<T>()(a, b); }
480 EIGEN_DEVICE_FUNC
static inline T bitwise_xor(
const T& a,
const T& b) {
return bit_xor<T>()(a, b); }
481 EIGEN_DEVICE_FUNC
static inline T bitwise_not(
const T& a) {
return bit_not<T>()(a); }
486struct bytewise_bitwise_helper {
487 EIGEN_DEVICE_FUNC
static inline T bitwise_and(
const T& a,
const T& b) {
488 return binary(a, b, bit_and<unsigned char>());
490 EIGEN_DEVICE_FUNC
static inline T bitwise_or(
const T& a,
const T& b) {
return binary(a, b, bit_or<unsigned char>()); }
491 EIGEN_DEVICE_FUNC
static inline T bitwise_xor(
const T& a,
const T& b) {
492 return binary(a, b, bit_xor<unsigned char>());
494 EIGEN_DEVICE_FUNC
static inline T bitwise_not(
const T& a) {
return unary(a, bit_not<unsigned char>()); }
497 template <
typename Op>
498 EIGEN_DEVICE_FUNC
static inline T unary(
const T& a, Op op) {
499 const unsigned char* a_ptr =
reinterpret_cast<const unsigned char*
>(&a);
501 unsigned char* c_ptr =
reinterpret_cast<unsigned char*
>(&c);
502 for (
size_t i = 0; i <
sizeof(T); ++i) {
503 *c_ptr++ = op(*a_ptr++);
508 template <
typename Op>
509 EIGEN_DEVICE_FUNC
static inline T binary(
const T& a,
const T& b, Op op) {
510 const unsigned char* a_ptr =
reinterpret_cast<const unsigned char*
>(&a);
511 const unsigned char* b_ptr =
reinterpret_cast<const unsigned char*
>(&b);
513 unsigned char* c_ptr =
reinterpret_cast<unsigned char*
>(&c);
514 for (
size_t i = 0; i <
sizeof(T); ++i) {
515 *c_ptr++ = op(*a_ptr++, *b_ptr++);
522template <
typename T,
typename EnableIf =
void>
523struct bitwise_helper :
public bytewise_bitwise_helper<T> {};
527struct bitwise_helper<T, typename std::enable_if_t<is_scalar<T>::value &&
528 (NumTraits<T>::IsInteger || NumTraits<T>::RequireInitialization)>>
529 :
public operator_bitwise_helper<T> {};
532template <
typename Packet>
533EIGEN_DEVICE_FUNC
inline Packet pand(
const Packet& a,
const Packet& b) {
534 return bitwise_helper<Packet>::bitwise_and(a, b);
538template <
typename Packet>
539EIGEN_DEVICE_FUNC
inline Packet por(
const Packet& a,
const Packet& b) {
540 return bitwise_helper<Packet>::bitwise_or(a, b);
544template <
typename Packet>
545EIGEN_DEVICE_FUNC
inline Packet pxor(
const Packet& a,
const Packet& b) {
546 return bitwise_helper<Packet>::bitwise_xor(a, b);
550template <
typename Packet>
551EIGEN_DEVICE_FUNC
inline Packet pnot(
const Packet& a) {
552 return bitwise_helper<Packet>::bitwise_not(a);
556template <
typename Packet>
557EIGEN_DEVICE_FUNC
inline Packet pandnot(
const Packet& a,
const Packet& b) {
558 return pand(a, pnot(b));
562template <
typename Packet>
563EIGEN_DEVICE_FUNC
inline Packet pcmp_lt(
const Packet& a,
const Packet& b) {
564 return a < b ? ptrue(a) : pzero(a);
568template <
typename Packet>
569EIGEN_DEVICE_FUNC
inline Packet pcmp_eq(
const Packet& a,
const Packet& b) {
570 return a == b ? ptrue(a) : pzero(a);
574template <
typename Packet>
575EIGEN_DEVICE_FUNC
inline Packet pcmp_le(
const Packet& a,
const Packet& b) {
576 return por(pcmp_eq(a, b), pcmp_lt(a, b));
580template <
typename Packet>
581EIGEN_DEVICE_FUNC
inline Packet pcmp_lt_or_nan(
const Packet& a,
const Packet& b) {
582 return a >= b ? pzero(a) : ptrue(a);
586template <typename Packet, bool is_scalar = is_scalar<Packet>::value>
588 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& mask,
const Packet& a,
const Packet& b) {
589 return por(pand(a, mask), pandnot(b, mask));
594template <
typename Packet>
595struct pselect_impl<Packet, true> {
596 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& mask,
const Packet& a,
const Packet& b) {
597 return numext::select(mask, a, b);
602template <
typename Packet>
603EIGEN_DEVICE_FUNC
inline Packet pselect(
const Packet& mask,
const Packet& a,
const Packet& b) {
604 return pselect_impl<Packet>::run(mask, a, b);
608EIGEN_DEVICE_FUNC
inline bool pselect<bool>(
const bool& cond,
const bool& a,
const bool& b) {
614template <
int NaNPropagation,
bool IsInteger>
616 template <
typename Packet,
typename Op>
617 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
626 template <
typename Packet,
typename Op>
627 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
628 Packet not_nan_mask_a = pcmp_eq(a, a);
629 Packet not_nan_mask_b = pcmp_eq(b, b);
630 return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), b), a);
639 template <
typename Packet,
typename Op>
640 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
641 Packet not_nan_mask_a = pcmp_eq(a, a);
642 Packet not_nan_mask_b = pcmp_eq(b, b);
643 return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), a), b);
647#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) [](const Type& aa, const Type& bb) { return Func(aa, bb); }
651template <
typename Packet>
652EIGEN_DEVICE_FUNC
inline Packet pmin(
const Packet& a,
const Packet& b) {
653 return numext::mini(a, b);
658template <
int NaNPropagation,
typename Packet>
659EIGEN_DEVICE_FUNC
inline Packet pmin(
const Packet& a,
const Packet& b) {
660 constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
661 return pminmax_impl<NaNPropagation, IsInteger>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
666template <
typename Packet>
667EIGEN_DEVICE_FUNC
inline Packet pmax(
const Packet& a,
const Packet& b) {
668 return numext::maxi(a, b);
673template <
int NaNPropagation,
typename Packet>
674EIGEN_DEVICE_FUNC
inline Packet pmax(
const Packet& a,
const Packet& b) {
675 constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
676 return pminmax_impl<NaNPropagation, IsInteger>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmax<Packet>)));
680template <
typename Packet>
681EIGEN_DEVICE_FUNC
inline Packet pabs(
const Packet& a) {
682 return numext::abs(a);
685EIGEN_DEVICE_FUNC
inline unsigned int pabs(
const unsigned int& a) {
689EIGEN_DEVICE_FUNC
inline unsigned long pabs(
const unsigned long& a) {
693EIGEN_DEVICE_FUNC
inline unsigned long long pabs(
const unsigned long long& a) {
698template <
typename Packet>
699EIGEN_DEVICE_FUNC
inline Packet paddsub(
const Packet& a,
const Packet& b) {
700 return pselect(peven_mask(a), padd(a, b), psub(a, b));
704template <
typename Packet>
705EIGEN_DEVICE_FUNC
inline Packet parg(
const Packet& a) {
711template <
int N,
typename T>
712EIGEN_DEVICE_FUNC
inline T parithmetic_shift_right(
const T& a) {
713 return numext::arithmetic_shift_right(a, N);
717template <
int N,
typename T>
718EIGEN_DEVICE_FUNC
inline T plogical_shift_right(
const T& a) {
719 return numext::logical_shift_right(a, N);
723template <
int N,
typename T>
724EIGEN_DEVICE_FUNC
inline T plogical_shift_left(
const T& a) {
725 return numext::logical_shift_left(a, N);
731template <
typename Packet>
732EIGEN_DEVICE_FUNC
inline Packet pfrexp(
const Packet& a, Packet& exponent) {
734 EIGEN_USING_STD(frexp);
735 Packet result =
static_cast<Packet
>(frexp(a, &
exp));
736 exponent =
static_cast<Packet
>(
exp);
743template <
typename Packet>
744EIGEN_DEVICE_FUNC
inline Packet pldexp(
const Packet& a,
const Packet& exponent) {
745 EIGEN_USING_STD(ldexp)
746 return static_cast<Packet
>(ldexp(a,
static_cast<int>(exponent)));
750template <
typename Packet>
751EIGEN_DEVICE_FUNC
inline Packet pabsdiff(
const Packet& a,
const Packet& b) {
752 return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b));
756template <
typename Packet>
757EIGEN_DEVICE_FUNC
inline Packet pload(
const typename unpacket_traits<Packet>::type* from) {
765template <
typename Packet>
766EIGEN_DEVICE_FUNC
inline Packet pload_partial(
const typename unpacket_traits<Packet>::type* from,
const Index n,
767 const Index offset = 0) {
768 const Index packet_size = unpacket_traits<Packet>::size;
769 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will read past end of packet");
770 typedef typename unpacket_traits<Packet>::type Scalar;
771 EIGEN_ALIGN_MAX Scalar elements[packet_size] = {Scalar(0)};
772 for (
Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
773 elements[i] = from[i - offset];
775 return pload<Packet>(elements);
779template <
typename Packet>
780EIGEN_DEVICE_FUNC
inline Packet ploadu(
const typename unpacket_traits<Packet>::type* from) {
786template <
typename Packet>
787EIGEN_DEVICE_FUNC
inline Packet ploadu_partial(
const typename unpacket_traits<Packet>::type* from,
const Index n,
788 const Index offset = 0) {
789 const Index packet_size = unpacket_traits<Packet>::size;
790 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will read past end of packet");
791 typedef typename unpacket_traits<Packet>::type Scalar;
792 EIGEN_ALIGN_MAX Scalar elements[packet_size] = {Scalar(0)};
793 for (
Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
794 elements[i] = from[i - offset];
796 return pload<Packet>(elements);
803template <
typename Packet>
804EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_load_available, Packet> ploadu(
805 const typename unpacket_traits<Packet>::type* from,
typename unpacket_traits<Packet>::mask_t umask);
808template <
typename Packet>
809EIGEN_DEVICE_FUNC
inline Packet pset1(
const typename unpacket_traits<Packet>::type& a) {
814template <
typename Packet,
typename BitsType>
815EIGEN_DEVICE_FUNC
inline Packet pset1frombits(BitsType a);
818template <
typename Packet>
819EIGEN_DEVICE_FUNC
inline Packet pload1(
const typename unpacket_traits<Packet>::type* a) {
820 return pset1<Packet>(*a);
828template <
typename Packet>
829EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ploaddup(
const typename unpacket_traits<Packet>::type* from) {
839template <
typename Packet>
840EIGEN_DEVICE_FUNC
inline Packet ploadquad(
const typename unpacket_traits<Packet>::type* from) {
841 return pload1<Packet>(from);
853template <
typename Packet>
854EIGEN_DEVICE_FUNC
inline void pbroadcast4(
const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1,
855 Packet& a2, Packet& a3) {
856 a0 = pload1<Packet>(a + 0);
857 a1 = pload1<Packet>(a + 1);
858 a2 = pload1<Packet>(a + 2);
859 a3 = pload1<Packet>(a + 3);
869template <
typename Packet>
870EIGEN_DEVICE_FUNC
inline void pbroadcast2(
const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1) {
871 a0 = pload1<Packet>(a + 0);
872 a1 = pload1<Packet>(a + 1);
876template <
typename Packet>
877EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet plset(
const typename unpacket_traits<Packet>::type& a) {
881template <
typename Packet,
typename EnableIf =
void>
882struct peven_mask_impl {
883 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(
const Packet&) {
884 typedef typename unpacket_traits<Packet>::type Scalar;
885 const size_t n = unpacket_traits<Packet>::size;
886 EIGEN_ALIGN_TO_BOUNDARY(
sizeof(Packet)) Scalar elements[n];
887 for (
size_t i = 0; i < n; ++i) {
888 memset(elements + i, ((i & 1) == 0 ? 0xff : 0),
sizeof(Scalar));
890 return ploadu<Packet>(elements);
894template <
typename Scalar>
895struct peven_mask_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value>> {
896 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run(
const Scalar&) {
return Scalar(1); }
901template <
typename Packet>
902EIGEN_DEVICE_FUNC
inline Packet peven_mask(
const Packet& a) {
903 return peven_mask_impl<Packet>::run(a);
907template <
typename Scalar,
typename Packet>
908EIGEN_DEVICE_FUNC
inline void pstore(Scalar* to,
const Packet& from) {
915template <
typename Scalar,
typename Packet>
916EIGEN_DEVICE_FUNC
inline void pstore_partial(Scalar* to,
const Packet& from,
const Index n,
const Index offset = 0) {
917 const Index packet_size = unpacket_traits<Packet>::size;
918 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will write past end of packet");
919 EIGEN_ALIGN_MAX Scalar elements[packet_size];
920 pstore<Scalar>(elements, from);
921 for (
Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
922 to[i] = elements[i + offset];
927template <
typename Scalar,
typename Packet>
928EIGEN_DEVICE_FUNC
inline void pstoreu(Scalar* to,
const Packet& from) {
933template <
typename Scalar,
typename Packet>
934EIGEN_DEVICE_FUNC
inline void pstoreu_partial(Scalar* to,
const Packet& from,
const Index n,
const Index offset = 0) {
935 const Index packet_size = unpacket_traits<Packet>::size;
936 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will write past end of packet");
937 EIGEN_ALIGN_MAX Scalar elements[packet_size];
938 pstore<Scalar>(elements, from);
939 for (
Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
940 to[i] = elements[i + offset];
948template <
typename Scalar,
typename Packet>
949EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_store_available,
void> pstoreu(
950 Scalar* to,
const Packet& from,
typename unpacket_traits<Packet>::mask_t umask);
952template <
typename Scalar,
typename Packet>
953EIGEN_DEVICE_FUNC
inline Packet pgather(
const Scalar* from,
Index ) {
954 return ploadu<Packet>(from);
957template <
typename Scalar,
typename Packet>
958EIGEN_DEVICE_FUNC
inline Packet pgather_partial(
const Scalar* from,
Index stride,
const Index n) {
959 const Index packet_size = unpacket_traits<Packet>::size;
960 EIGEN_ALIGN_MAX Scalar elements[packet_size] = {Scalar(0)};
961 for (
Index i = 0; i < numext::mini(n, packet_size); i++) {
962 elements[i] = from[i * stride];
964 return pload<Packet>(elements);
967template <
typename Scalar,
typename Packet>
968EIGEN_DEVICE_FUNC
inline void pscatter(Scalar* to,
const Packet& from,
Index ) {
972template <
typename Scalar,
typename Packet>
973EIGEN_DEVICE_FUNC
inline void pscatter_partial(Scalar* to,
const Packet& from,
Index stride,
const Index n) {
974 const Index packet_size = unpacket_traits<Packet>::size;
975 EIGEN_ALIGN_MAX Scalar elements[packet_size];
976 pstore<Scalar>(elements, from);
977 for (
Index i = 0; i < numext::mini(n, packet_size); i++) {
978 to[i * stride] = elements[i];
983template <
typename Scalar>
984EIGEN_DEVICE_FUNC
inline void prefetch(
const Scalar* addr) {
985#if defined(EIGEN_HIP_DEVICE_COMPILE)
987#elif defined(EIGEN_CUDA_ARCH)
988#if defined(__LP64__) || EIGEN_OS_WIN64
990 asm(
" prefetch.L1 [ %1 ];" :
"=l"(addr) :
"l"(addr));
993 asm(
" prefetch.L1 [ %1 ];" :
"=r"(addr) :
"r"(addr));
995#elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
996 __builtin_prefetch(addr);
1001template <
typename Packet>
1002EIGEN_DEVICE_FUNC
inline Packet preverse(
const Packet& a) {
1007template <
typename Packet>
1008EIGEN_DEVICE_FUNC
inline Packet pcplxflip(
const Packet& a) {
1009 return Packet(numext::imag(a), numext::real(a));
1017template <
typename Packet>
1018EIGEN_DEVICE_FUNC
inline Packet pisnan(
const Packet& a) {
1019 return pandnot(ptrue(a), pcmp_eq(a, a));
1023template <
typename Packet>
1024EIGEN_DEVICE_FUNC
inline Packet pisinf(
const Packet& a) {
1025 using Scalar =
typename unpacket_traits<Packet>::type;
1026 constexpr Scalar inf = NumTraits<Scalar>::infinity();
1027 return pcmp_eq(pabs(a), pset1<Packet>(inf));
1031template <
typename Packet>
1032EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psin(
const Packet& a) {
1033 EIGEN_USING_STD(
sin);
1038template <
typename Packet>
1039EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcos(
const Packet& a) {
1040 EIGEN_USING_STD(
cos);
1045template <
typename Packet>
1046EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptan(
const Packet& a) {
1047 EIGEN_USING_STD(
tan);
1052template <
typename Packet>
1053EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pasin(
const Packet& a) {
1054 EIGEN_USING_STD(
asin);
1059template <
typename Packet>
1060EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacos(
const Packet& a) {
1061 EIGEN_USING_STD(
acos);
1066template <
typename Packet>
1067EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh(
const Packet& a) {
1068 EIGEN_USING_STD(
sinh);
1073template <
typename Packet>
1074EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh(
const Packet& a) {
1075 EIGEN_USING_STD(
cosh);
1080template <
typename Packet>
1081EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patan(
const Packet& a) {
1082 EIGEN_USING_STD(
atan);
1087template <
typename Packet>
1088EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptanh(
const Packet& a) {
1089 EIGEN_USING_STD(
tanh);
1094template <
typename Packet>
1095EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patanh(
const Packet& a) {
1096 EIGEN_USING_STD(
atanh);
1101template <
typename Packet>
1102EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(
const Packet& a) {
1103 return numext::exp(a);
1107template <
typename Packet>
1108EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp2(
const Packet& a) {
1109 return numext::exp2(a);
1113template <
typename Packet>
1114EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexpm1(
const Packet& a) {
1115 return numext::expm1(a);
1119template <
typename Packet>
1120EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog(
const Packet& a) {
1121 EIGEN_USING_STD(
log);
1126template <
typename Packet>
1127EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog1p(
const Packet& a) {
1128 return numext::log1p(a);
1132template <
typename Packet>
1133EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog10(
const Packet& a) {
1134 EIGEN_USING_STD(
log10);
1139template <
typename Packet>
1140EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(
const Packet& a) {
1141 using Scalar =
typename internal::unpacket_traits<Packet>::type;
1142 using RealScalar =
typename NumTraits<Scalar>::Real;
1143 return pmul(pset1<Packet>(Scalar(RealScalar(EIGEN_LOG2E))), plog(a));
1147template <
typename Packet>
1148EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt(
const Packet& a) {
1149 return numext::sqrt(a);
1153template <
typename Packet>
1154EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcbrt(
const Packet& a) {
1155 return numext::cbrt(a);
1158template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
1159 bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1160struct nearest_integer_packetop_impl {
1161 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_floor(
const Packet& x) {
return numext::floor(x); }
1162 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_ceil(
const Packet& x) {
return numext::ceil(x); }
1163 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_rint(
const Packet& x) {
return numext::rint(x); }
1164 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_round(
const Packet& x) {
return numext::round(x); }
1165 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_trunc(
const Packet& x) {
return numext::trunc(x); }
1169template <
typename Packet>
1170EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pround(
const Packet& a) {
1171 return nearest_integer_packetop_impl<Packet>::run_round(a);
1175template <
typename Packet>
1176EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pfloor(
const Packet& a) {
1177 return nearest_integer_packetop_impl<Packet>::run_floor(a);
1182template <
typename Packet>
1183EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet print(
const Packet& a) {
1184 return nearest_integer_packetop_impl<Packet>::run_rint(a);
1188template <
typename Packet>
1189EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pceil(
const Packet& a) {
1190 return nearest_integer_packetop_impl<Packet>::run_ceil(a);
1194template <
typename Packet>
1195EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ptrunc(
const Packet& a) {
1196 return nearest_integer_packetop_impl<Packet>::run_trunc(a);
1199template <
typename Packet,
typename EnableIf =
void>
1201 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return numext::sign(a); }
1205template <
typename Packet>
1206EIGEN_DEVICE_FUNC
inline Packet psign(
const Packet& a) {
1207 return psign_impl<Packet>::run(a);
1211EIGEN_DEVICE_FUNC
inline bool psign(
const bool& a) {
1216template <
typename Packet>
1217EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type pfirst(
const Packet& a) {
1225template <
typename Packet>
1226EIGEN_DEVICE_FUNC
inline std::conditional_t<(unpacket_traits<Packet>::size % 8) == 0,
1227 typename unpacket_traits<Packet>::half, Packet>
1228predux_half_dowto4(
const Packet& a) {
1233template <
typename Packet,
typename Op>
1234EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_helper(
const Packet& a, Op op) {
1235 typedef typename unpacket_traits<Packet>::type Scalar;
1236 const size_t n = unpacket_traits<Packet>::size;
1237 EIGEN_ALIGN_TO_BOUNDARY(
sizeof(Packet)) Scalar elements[n];
1238 pstoreu<Scalar>(elements, a);
1239 for (
size_t k = n / 2; k > 0; k /= 2) {
1240 for (
size_t i = 0; i < k; ++i) {
1241 elements[i] = op(elements[i], elements[i + k]);
1248template <
typename Packet>
1249EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux(
const Packet& a) {
1254template <
typename Packet>
1255EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_mul(
const Packet& a) {
1256 typedef typename unpacket_traits<Packet>::type Scalar;
1257 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmul<Scalar>)));
1261template <
typename Packet>
1262EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_min(
const Packet& a) {
1263 typedef typename unpacket_traits<Packet>::type Scalar;
1264 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<Scalar>)));
1268template <
typename Packet>
1269EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_max(
const Packet& a) {
1270 typedef typename unpacket_traits<Packet>::type Scalar;
1271 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<Scalar>)));
1274template <
int NaNPropagation,
typename Packet>
1275struct predux_min_max_helper_impl {
1276 using Scalar =
typename unpacket_traits<Packet>::type;
1277 static constexpr bool UsePredux_ = NaNPropagation ==
PropagateFast || NumTraits<Scalar>::IsInteger;
1278 template <
bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux,
bool> = true>
1279 static EIGEN_DEVICE_FUNC
inline Scalar run_min(
const Packet& a) {
1280 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<NaNPropagation, Scalar>)));
1282 template <
bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux,
bool> = true>
1283 static EIGEN_DEVICE_FUNC
inline Scalar run_max(
const Packet& a) {
1284 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<NaNPropagation, Scalar>)));
1286 template <
bool UsePredux = UsePredux_, std::enable_if_t<UsePredux,
bool> = true>
1287 static EIGEN_DEVICE_FUNC
inline Scalar run_min(
const Packet& a) {
1288 return predux_min(a);
1290 template <
bool UsePredux = UsePredux_, std::enable_if_t<UsePredux,
bool> = true>
1291 static EIGEN_DEVICE_FUNC
inline Scalar run_max(
const Packet& a) {
1292 return predux_max(a);
1296template <
int NaNPropagation,
typename Packet>
1297EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_min(
const Packet& a) {
1298 return predux_min_max_helper_impl<NaNPropagation, Packet>::run_min(a);
1301template <
int NaNPropagation,
typename Packet>
1302EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_max(
const Packet& a) {
1303 return predux_min_max_helper_impl<NaNPropagation, Packet>::run_max(a);
1306#undef EIGEN_BINARY_OP_NAN_PROPAGATION
1318template <
typename Packet>
1319EIGEN_DEVICE_FUNC
inline bool predux_any(
const Packet& a) {
1326 typedef typename unpacket_traits<Packet>::type Scalar;
1327 return numext::not_equal_strict(predux(a), Scalar(0));
1334template <
typename Packet,
typename EnableIf =
void>
1336 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1337 return padd(pmul(a, b), c);
1339 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1340 return psub(pmul(a, b), c);
1342 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1343 return psub(c, pmul(a, b));
1345 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1346 return pnegate(pmadd(a, b, c));
1350template <
typename Scalar>
1351struct pmadd_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value && NumTraits<Scalar>::IsSigned>> {
1352 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmadd(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1353 return numext::madd<Scalar>(a, b, c);
1355 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmsub(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1356 return numext::madd<Scalar>(a, b, Scalar(-c));
1358 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmadd(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1359 return numext::madd<Scalar>(Scalar(-a), b, c);
1361 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmsub(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1362 return -Scalar(numext::madd<Scalar>(a, b, c));
1368template <
typename Packet>
1369EIGEN_DEVICE_FUNC
inline Packet pmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1370 return pmadd_impl<Packet>::pmadd(a, b, c);
1374template <
typename Packet>
1375EIGEN_DEVICE_FUNC
inline Packet pmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1376 return pmadd_impl<Packet>::pmsub(a, b, c);
1380template <
typename Packet>
1381EIGEN_DEVICE_FUNC
inline Packet pnmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1382 return pmadd_impl<Packet>::pnmadd(a, b, c);
1386template <
typename Packet>
1387EIGEN_DEVICE_FUNC
inline Packet pnmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1388 return pmadd_impl<Packet>::pnmsub(a, b, c);
1395template <
typename Packet>
1396inline void pstore1(
typename unpacket_traits<Packet>::type* to,
const typename unpacket_traits<Packet>::type& a) {
1397 pstore(to, pset1<Packet>(a));
1402template <
typename Packet,
int Alignment>
1403EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(
const typename unpacket_traits<Packet>::type* from) {
1404 if (Alignment >= unpacket_traits<Packet>::alignment)
1405 return pload<Packet>(from);
1407 return ploadu<Packet>(from);
1412template <
typename Packet,
int Alignment>
1413EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_partial(
const typename unpacket_traits<Packet>::type* from,
1415 if (Alignment >= unpacket_traits<Packet>::alignment)
1416 return pload_partial<Packet>(from, n, offset);
1418 return ploadu_partial<Packet>(from, n, offset);
1423template <
typename Scalar,
typename Packet,
int Alignment>
1424EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pstoret(Scalar* to,
const Packet& from) {
1425 if (Alignment >= unpacket_traits<Packet>::alignment)
1433template <
typename Scalar,
typename Packet,
int Alignment>
1434EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pstoret_partial(Scalar* to,
const Packet& from,
const Index n,
1435 const Index offset = 0) {
1436 if (Alignment >= unpacket_traits<Packet>::alignment)
1437 pstore_partial(to, from, n, offset);
1439 pstoreu_partial(to, from, n, offset);
1447template <
typename Packet,
int LoadMode>
1448EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(
const typename unpacket_traits<Packet>::type* from) {
1449 return ploadt<Packet, LoadMode>(from);
1457#if !defined(EIGEN_GPUCC)
1460inline std::complex<float> pmul(
const std::complex<float>& a,
const std::complex<float>& b) {
1461 return std::complex<float>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
1465inline std::complex<double> pmul(
const std::complex<double>& a,
const std::complex<double>& b) {
1466 return std::complex<double>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
1475template <typename Packet, int N = unpacket_traits<Packet>::size>
1480template <
typename Packet>
1481EIGEN_DEVICE_FUNC
inline void ptranspose(PacketBlock<Packet, 1>& ) {
1494template <
typename Packet>
1495EIGEN_DEVICE_FUNC
inline Packet pblend(
const Selector<unpacket_traits<Packet>::size>& ifPacket,
1496 const Packet& thenPacket,
const Packet& elsePacket) {
1497 return ifPacket.select[0] ? thenPacket : elsePacket;
1501template <
typename Packet>
1502EIGEN_DEVICE_FUNC
inline Packet preciprocal(
const Packet& a) {
1503 using Scalar =
typename unpacket_traits<Packet>::type;
1504 return pdiv(pset1<Packet>(Scalar(1)), a);
1508template <
typename Packet>
1509EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet prsqrt(
const Packet& a) {
1510 return preciprocal<Packet>(psqrt(a));
1513template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
1514 bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1515struct psignbit_impl;
1516template <
typename Packet,
bool IsInteger>
1517struct psignbit_impl<Packet, true, IsInteger> {
1518 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static constexpr Packet run(
const Packet& a) {
return numext::signbit(a); }
1520template <
typename Packet>
1521struct psignbit_impl<Packet, false, false> {
1524 typedef typename unpacket_traits<Packet>::type Scalar;
1525 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static Packet run(
const Packet& a) {
1526 const Packet cst_pos_one = pset1<Packet>(Scalar(1));
1527 const Packet cst_neg_one = pset1<Packet>(Scalar(-1));
1528 return pcmp_eq(por(pand(a, cst_neg_one), cst_pos_one), cst_neg_one);
1531template <
typename Packet>
1532struct psignbit_impl<Packet, false, true> {
1534 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static constexpr Packet run(
const Packet& a) {
return pcmp_lt(a, pzero(a)); }
1537template <
typename Packet>
1538EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
constexpr Packet psignbit(
const Packet& a) {
1539 return psignbit_impl<Packet>::run(a);
1543template <typename Packet, std::enable_if_t<is_scalar<Packet>::value,
int> = 0>
1544EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(
const Packet& y,
const Packet& x) {
1545 return numext::atan2(y, x);
1549template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value,
int> = 0>
1550EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(
const Packet& y,
const Packet& x) {
1551 typedef typename internal::unpacket_traits<Packet>::type Scalar;
1556 const Packet kSignMask = pset1<Packet>(-Scalar(0));
1557 const Packet kZero = pzero(x);
1558 const Packet kOne = pset1<Packet>(Scalar(1));
1559 const Packet kPi = pset1<Packet>(Scalar(EIGEN_PI));
1561 const Packet x_has_signbit = psignbit(x);
1562 const Packet y_signmask = pand(y, kSignMask);
1563 const Packet x_signmask = pand(x, kSignMask);
1564 const Packet result_signmask = pxor(y_signmask, x_signmask);
1565 const Packet shift = por(pand(x_has_signbit, kPi), y_signmask);
1567 const Packet x_and_y_are_same = pcmp_eq(pabs(x), pabs(y));
1568 const Packet x_and_y_are_zero = pcmp_eq(por(x, y), kZero);
1570 Packet
arg = pdiv(y, x);
1571 arg = pselect(x_and_y_are_same, por(kOne, result_signmask),
arg);
1572 arg = pselect(x_and_y_are_zero, result_signmask,
arg);
1574 Packet result = patan(
arg);
1575 result = padd(result, shift);
1580template <typename Packet, std::enable_if_t<is_scalar<Packet>::value,
int> = 0>
1581EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(
const Packet& a) {
1582 return Packet(numext::arg(a));
1586template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value,
int> = 0>
1587EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(
const Packet& a) {
1588 EIGEN_STATIC_ASSERT(NumTraits<
typename unpacket_traits<Packet>::type>::IsComplex,
1589 THIS METHOD IS FOR COMPLEX TYPES ONLY)
1590 using RealPacket =
typename unpacket_traits<Packet>::as_real;
1592 RealPacket aflip = pcplxflip(a).v;
1593 RealPacket result = patan2(aflip, a.v);
1594 return (Packet)pand(result, peven_mask(result));
1599template <
typename Packet>
1600EIGEN_DEVICE_FUNC
inline Packet ploaduSegment(
const typename unpacket_traits<Packet>::type* from,
Index begin,
1602 using Scalar =
typename unpacket_traits<Packet>::type;
1603 constexpr Index PacketSize = unpacket_traits<Packet>::size;
1604 eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) &&
"invalid range");
1605 Scalar aux[PacketSize] = {};
1606 for (
Index k = begin; k < begin + count; k++) {
1609 return ploadu<Packet>(aux);
1614template <
typename Packet>
1615EIGEN_DEVICE_FUNC
inline Packet ploadSegment(
const typename unpacket_traits<Packet>::type* from,
Index begin,
1617 return ploaduSegment<Packet>(from, begin, count);
1623template <
typename Scalar,
typename Packet>
1624EIGEN_DEVICE_FUNC
inline void pstoreuSegment(Scalar* to,
const Packet& from,
Index begin,
Index count) {
1625 constexpr Index PacketSize = unpacket_traits<Packet>::size;
1626 eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) &&
"invalid range");
1627 Scalar aux[PacketSize];
1628 pstoreu<Scalar, Packet>(aux, from);
1629 for (
Index k = begin; k < begin + count; k++) {
1637template <
typename Scalar,
typename Packet>
1638EIGEN_DEVICE_FUNC
inline void pstoreSegment(Scalar* to,
const Packet& from,
Index begin,
Index count) {
1639 return pstoreuSegment(to, from, begin, count);
1644template <
typename Packet,
int Alignment>
1645EIGEN_DEVICE_FUNC
inline Packet ploadtSegment(
const typename unpacket_traits<Packet>::type* from,
Index begin,
1647 constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
1648 if (Alignment >= RequiredAlignment) {
1649 return ploadSegment<Packet>(from, begin, count);
1651 return ploaduSegment<Packet>(from, begin, count);
1657template <
typename Scalar,
typename Packet,
int Alignment>
1658EIGEN_DEVICE_FUNC
inline void pstoretSegment(Scalar* to,
const Packet& from,
Index begin,
Index count) {
1659 constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
1660 if (Alignment >= RequiredAlignment) {
1661 pstoreSegment<Scalar, Packet>(to, from, begin, count);
1663 pstoreuSegment<Scalar, Packet>(to, from, begin, count);
1669template <
typename Packet>
1670class StreamablePacket {
1672 using Scalar =
typename unpacket_traits<Packet>::type;
1673 StreamablePacket(
const Packet& packet) { pstoreu(v_, packet); }
1675 friend std::ostream& operator<<(std::ostream& os,
const StreamablePacket& packet) {
1676 os <<
"{" << packet.v_[0];
1677 for (
int i = 1; i < unpacket_traits<Packet>::size; ++i) {
1678 os <<
"," << packet.v_[i];
1685 Scalar v_[unpacket_traits<Packet>::size];
1691template <
typename Packet>
1692StreamablePacket<Packet> postream(
const Packet& packet) {
1693 return StreamablePacket<Packet>(packet);
@ PropagateNaN
Definition Constants.h:342
@ PropagateNumbers
Definition Constants.h:344
@ PropagateFast
Definition Constants.h:340
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cosh_op< typename Derived::Scalar >, const Derived > cosh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_atanh_op< typename Derived::Scalar >, const Derived > atanh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tan_op< typename Derived::Scalar >, const Derived > tan(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_atan_op< typename Derived::Scalar >, const Derived > atan(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sin_op< typename Derived::Scalar >, const Derived > sin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_asin_op< typename Derived::Scalar >, const Derived > asin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tanh_op< typename Derived::Scalar >, const Derived > tanh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_acos_op< typename Derived::Scalar >, const Derived > acos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log10_op< typename Derived::Scalar >, const Derived > log10(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_arg_op< typename Derived::Scalar >, const Derived > arg(const Eigen::ArrayBase< Derived > &x)