12#ifndef EIGEN_GENERIC_PACKET_MATH_H
13#define EIGEN_GENERIC_PACKET_MATH_H
16#include "./InternalHeaderCheck.h"
30#ifndef EIGEN_DEBUG_ALIGNED_LOAD
31#define EIGEN_DEBUG_ALIGNED_LOAD
34#ifndef EIGEN_DEBUG_UNALIGNED_LOAD
35#define EIGEN_DEBUG_UNALIGNED_LOAD
38#ifndef EIGEN_DEBUG_ALIGNED_STORE
39#define EIGEN_DEBUG_ALIGNED_STORE
42#ifndef EIGEN_DEBUG_UNALIGNED_STORE
43#define EIGEN_DEBUG_UNALIGNED_STORE
46struct default_packet_traits {
104 HasGammaSampleDerAlpha = 0,
111struct packet_traits : default_packet_traits {
135struct packet_traits<const T> : packet_traits<T> {};
137struct default_unpacket_traits {
138 enum { vectorizable =
false, masked_load_available =
false, masked_store_available =
false };
142struct unpacket_traits : default_unpacket_traits {
145 using integer_packet =
typename numext::get_integer_by_size<
sizeof(T)>::signed_type;
148 alignment =
alignof(T),
153struct unpacket_traits<const T> : unpacket_traits<T> {};
158template <
typename Packet>
159struct is_scalar : std::is_same<Packet, typename unpacket_traits<Packet>::type> {};
165template <
typename SrcPacket,
typename TgtPacket,
166 bool Scalar = is_scalar<SrcPacket>::value && is_scalar<TgtPacket>::value>
167struct is_degenerate_helper : std::is_same<SrcPacket, TgtPacket> {};
169struct is_degenerate_helper<int8_t, uint8_t, true> : std::true_type {};
171struct is_degenerate_helper<int16_t, uint16_t, true> : std::true_type {};
173struct is_degenerate_helper<int32_t, uint32_t, true> : std::true_type {};
175struct is_degenerate_helper<int64_t, uint64_t, true> : std::true_type {};
177template <
typename SrcPacket,
typename TgtPacket>
178struct is_degenerate_helper<SrcPacket, TgtPacket, false> {
179 using SrcScalar =
typename unpacket_traits<SrcPacket>::type;
180 static constexpr int SrcSize = unpacket_traits<SrcPacket>::size;
181 using TgtScalar =
typename unpacket_traits<TgtPacket>::type;
182 static constexpr int TgtSize = unpacket_traits<TgtPacket>::size;
183 static constexpr bool value = is_degenerate_helper<SrcScalar, TgtScalar, true>::value && (SrcSize == TgtSize);
187template <
typename SrcPacket,
typename TgtPacket>
188struct is_degenerate {
189 static constexpr bool value =
190 is_degenerate_helper<SrcPacket, TgtPacket>::value || is_degenerate_helper<TgtPacket, SrcPacket>::value;
193template <
typename Packet>
195 using Scalar =
typename unpacket_traits<Packet>::type;
196 static constexpr int Size = unpacket_traits<Packet>::size;
197 using DefaultPacket =
typename packet_traits<Scalar>::type;
198 static constexpr int DefaultSize = unpacket_traits<DefaultPacket>::size;
199 static constexpr bool value = Size != 1 && Size < DefaultSize;
202template <
typename Src,
typename Tgt>
203struct type_casting_traits {
206 is_degenerate<Src, Tgt>::value && packet_traits<Src>::Vectorizable && packet_traits<Tgt>::Vectorizable,
213template <
typename Src,
typename Tgt>
214struct vectorized_type_casting_traits {
216 DefaultSrcPacketSize = packet_traits<Src>::size,
217 DefaultTgtPacketSize = packet_traits<Tgt>::size,
219 SrcCoeffRatio = plain_enum_max(DefaultTgtPacketSize / DefaultSrcPacketSize, 1),
220 TgtCoeffRatio = plain_enum_max(DefaultSrcPacketSize / DefaultTgtPacketSize, 1)
226template <
typename T,
int unique_
id = 0>
227struct eigen_packet_wrapper {
228 EIGEN_ALWAYS_INLINE
operator T&() {
return m_val; }
229 EIGEN_ALWAYS_INLINE
operator const T&()
const {
return m_val; }
230 EIGEN_ALWAYS_INLINE eigen_packet_wrapper() =
default;
231 EIGEN_ALWAYS_INLINE eigen_packet_wrapper(
const T& v) : m_val(v) {}
232 EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(
const T& v) {
240template <typename Target, typename Packet, bool IsSame = std::is_same<Target, Packet>::value>
241struct preinterpret_generic;
243template <
typename Target,
typename Packet>
244struct preinterpret_generic<Target, Packet, false> {
246 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Target run(
const Packet& a) {
247 return numext::bit_cast<Target, Packet>(a);
251template <
typename Packet>
252struct preinterpret_generic<Packet, Packet, true> {
254 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(
const Packet& a) {
return a; }
257template <
typename ComplexPacket>
258struct preinterpret_generic<typename unpacket_traits<ComplexPacket>::as_real, ComplexPacket, false> {
259 using RealPacket =
typename unpacket_traits<ComplexPacket>::as_real;
260 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE RealPacket run(
const ComplexPacket& a) {
return a.v; }
264template <
typename Target,
typename Packet>
265EIGEN_DEVICE_FUNC
inline Target preinterpret(
const Packet& a) {
266 return preinterpret_generic<Target, Packet>::run(a);
269template <typename SrcPacket, typename TgtPacket, bool Degenerate = is_degenerate<SrcPacket, TgtPacket>::value,
270 bool TgtIsHalf = is_half<TgtPacket>::value>
273template <
typename SrcPacket,
typename TgtPacket>
274struct pcast_generic<SrcPacket, TgtPacket, false, false> {
276 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
277 return cast_impl<SrcPacket, TgtPacket>::run(a);
281template <
typename Packet>
282struct pcast_generic<Packet, Packet, true, false> {
284 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(
const Packet& a) {
return a; }
287template <
typename SrcPacket,
typename TgtPacket,
bool TgtIsHalf>
288struct pcast_generic<SrcPacket, TgtPacket, true, TgtIsHalf> {
290 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
return preinterpret<TgtPacket>(a); }
294template <
typename SrcPacket,
typename TgtPacket>
295EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a) {
296 return pcast_generic<SrcPacket, TgtPacket>::run(a);
298template <
typename SrcPacket,
typename TgtPacket>
299EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b) {
300 return pcast_generic<SrcPacket, TgtPacket>::run(a, b);
302template <
typename SrcPacket,
typename TgtPacket>
303EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b,
const SrcPacket& c,
304 const SrcPacket& d) {
305 return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d);
307template <
typename SrcPacket,
typename TgtPacket>
308EIGEN_DEVICE_FUNC
inline TgtPacket pcast(
const SrcPacket& a,
const SrcPacket& b,
const SrcPacket& c,
const SrcPacket& d,
309 const SrcPacket& e,
const SrcPacket& f,
const SrcPacket& g,
310 const SrcPacket& h) {
311 return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d, e, f, g, h);
314template <
typename SrcPacket,
typename TgtPacket>
315struct pcast_generic<SrcPacket, TgtPacket, false, true> {
318 using DefaultTgtPacket =
typename is_half<TgtPacket>::DefaultPacket;
319 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(
const SrcPacket& a) {
320 return preinterpret<TgtPacket>(pcast<SrcPacket, DefaultTgtPacket>(a));
325template <
typename Packet>
326EIGEN_DEVICE_FUNC
inline Packet padd(
const Packet& a,
const Packet& b) {
332EIGEN_DEVICE_FUNC
inline bool padd(
const bool& a,
const bool& b) {
340template <
typename Packet>
341EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_fpops_available, Packet> padd(
342 const Packet& a,
const Packet& b,
typename unpacket_traits<Packet>::mask_t umask);
345template <
typename Packet>
346EIGEN_DEVICE_FUNC
inline Packet psub(
const Packet& a,
const Packet& b) {
351template <
typename Packet>
352EIGEN_DEVICE_FUNC
inline Packet pnegate(
const Packet& a) {
353 EIGEN_STATIC_ASSERT((!std::is_same<
typename unpacket_traits<Packet>::type,
bool>::value),
354 NEGATE IS NOT DEFINED FOR BOOLEAN TYPES)
355 return numext::negate(a);
359template <
typename Packet>
360EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pconj(
const Packet& a) {
361 using Scalar =
typename unpacket_traits<Packet>::type;
362 EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex)
363 return numext::conj(a);
369template <
typename Packet>
370EIGEN_DEVICE_FUNC
inline Packet pmul(
const Packet& a,
const Packet& b) {
371 return internal::mul(a, b);
374EIGEN_DEVICE_FUNC
inline bool pmul(
const bool& a,
const bool& b) {
379template <
typename Packet>
380EIGEN_DEVICE_FUNC
inline Packet pdiv(
const Packet& a,
const Packet& b) {
384EIGEN_DEVICE_FUNC
inline bool pdiv(
const bool& a,
const bool& b) {
389template <
typename Packet,
typename EnableIf =
void>
391 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& ) {
393 memset(
static_cast<void*
>(&b), 0xff,
sizeof(Packet));
399template <
typename Scalar>
400struct ptrue_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value>> {
401 static EIGEN_DEVICE_FUNC
inline Scalar run(
const Scalar&) {
return Scalar(1); }
406struct ptrue_impl<bool, void> {
407 static EIGEN_DEVICE_FUNC
inline bool run(
const bool&) {
return true; }
414template <
typename Packet>
415EIGEN_DEVICE_FUNC
inline Packet ptrue(
const Packet& a) {
416 if (is_scalar<Packet>::value || std::is_same<Packet, bool>::value) {
419 return ptrue_impl<Packet>::run(a);
422 memset(
static_cast<void*
>(&b), 0xff,
sizeof(Packet));
423 EIGEN_FAST_MATH_CONSTANT_BARRIER(b);
428template <
typename Packet,
typename EnableIf =
void>
430 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& ) {
432 memset(
static_cast<void*
>(&b), 0x00,
sizeof(Packet));
440struct pzero_impl<T, std::enable_if_t<is_scalar<T>::value>> {
441 static EIGEN_DEVICE_FUNC
inline T run(
const T& ) {
return T(0); }
445template <
typename Packet>
446EIGEN_DEVICE_FUNC
inline Packet pzero(
const Packet& a) {
447 return pzero_impl<Packet>::run(a);
452 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a & b; }
457 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a | b; }
462 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a,
const T& b)
const {
return a ^ b; }
467 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE T operator()(
const T& a)
const {
return ~a; }
471struct bit_and<bool> {
472 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a & b; }
477 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a | b; }
481struct bit_xor<bool> {
482 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a,
const bool& b)
const {
return a != b; }
486struct bit_not<bool> {
487 EIGEN_DEVICE_FUNC
constexpr EIGEN_ALWAYS_INLINE
bool operator()(
const bool& a)
const {
return !a; }
492struct operator_bitwise_helper {
493 EIGEN_DEVICE_FUNC
static inline T bitwise_and(
const T& a,
const T& b) {
return bit_and<T>()(a, b); }
494 EIGEN_DEVICE_FUNC
static inline T bitwise_or(
const T& a,
const T& b) {
return bit_or<T>()(a, b); }
495 EIGEN_DEVICE_FUNC
static inline T bitwise_xor(
const T& a,
const T& b) {
return bit_xor<T>()(a, b); }
496 EIGEN_DEVICE_FUNC
static inline T bitwise_not(
const T& a) {
return bit_not<T>()(a); }
501struct bytewise_bitwise_helper {
502 EIGEN_DEVICE_FUNC
static inline T bitwise_and(
const T& a,
const T& b) {
503 return binary(a, b, bit_and<unsigned char>());
505 EIGEN_DEVICE_FUNC
static inline T bitwise_or(
const T& a,
const T& b) {
return binary(a, b, bit_or<unsigned char>()); }
506 EIGEN_DEVICE_FUNC
static inline T bitwise_xor(
const T& a,
const T& b) {
507 return binary(a, b, bit_xor<unsigned char>());
509 EIGEN_DEVICE_FUNC
static inline T bitwise_not(
const T& a) {
return unary(a, bit_not<unsigned char>()); }
512 template <
typename Op>
513 EIGEN_DEVICE_FUNC
static inline T unary(
const T& a, Op op) {
514 const unsigned char* a_ptr =
reinterpret_cast<const unsigned char*
>(&a);
516 unsigned char* c_ptr =
reinterpret_cast<unsigned char*
>(&c);
517 for (
size_t i = 0; i <
sizeof(T); ++i) {
518 *c_ptr++ = op(*a_ptr++);
523 template <
typename Op>
524 EIGEN_DEVICE_FUNC
static inline T binary(
const T& a,
const T& b, Op op) {
525 const unsigned char* a_ptr =
reinterpret_cast<const unsigned char*
>(&a);
526 const unsigned char* b_ptr =
reinterpret_cast<const unsigned char*
>(&b);
528 unsigned char* c_ptr =
reinterpret_cast<unsigned char*
>(&c);
529 for (
size_t i = 0; i <
sizeof(T); ++i) {
530 *c_ptr++ = op(*a_ptr++, *b_ptr++);
537template <
typename T,
typename EnableIf =
void>
538struct bitwise_helper :
public bytewise_bitwise_helper<T> {};
542struct bitwise_helper<
543 T, std::enable_if_t<is_scalar<T>::value && (NumTraits<T>::IsInteger || NumTraits<T>::RequireInitialization)>>
544 :
public operator_bitwise_helper<T> {};
547template <
typename Packet>
548EIGEN_DEVICE_FUNC
inline Packet pand(
const Packet& a,
const Packet& b) {
549 return bitwise_helper<Packet>::bitwise_and(a, b);
553template <
typename Packet>
554EIGEN_DEVICE_FUNC
inline Packet por(
const Packet& a,
const Packet& b) {
555 return bitwise_helper<Packet>::bitwise_or(a, b);
559template <
typename Packet>
560EIGEN_DEVICE_FUNC
inline Packet pxor(
const Packet& a,
const Packet& b) {
561 return bitwise_helper<Packet>::bitwise_xor(a, b);
565template <
typename Packet>
566EIGEN_DEVICE_FUNC
inline Packet pnot(
const Packet& a) {
567 return bitwise_helper<Packet>::bitwise_not(a);
571template <
typename Packet>
572EIGEN_DEVICE_FUNC
inline Packet pandnot(
const Packet& a,
const Packet& b) {
573 return pand(a, pnot(b));
577template <
typename Packet>
578EIGEN_DEVICE_FUNC
inline Packet pcmp_lt(
const Packet& a,
const Packet& b) {
579 return a < b ? ptrue(a) : pzero(a);
583template <
typename Packet>
584EIGEN_DEVICE_FUNC
inline Packet pcmp_eq(
const Packet& a,
const Packet& b) {
585 return a == b ? ptrue(a) : pzero(a);
589template <
typename Packet>
590EIGEN_DEVICE_FUNC
inline Packet pcmp_le(
const Packet& a,
const Packet& b) {
591 return por(pcmp_eq(a, b), pcmp_lt(a, b));
595template <
typename Packet>
596EIGEN_DEVICE_FUNC
inline Packet pcmp_lt_or_nan(
const Packet& a,
const Packet& b) {
597 return a >= b ? pzero(a) : ptrue(a);
601template <typename Packet, bool is_scalar = is_scalar<Packet>::value>
603 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& mask,
const Packet& a,
const Packet& b) {
604 return por(pand(a, mask), pandnot(b, mask));
609template <
typename Packet>
610struct pselect_impl<Packet, true> {
611 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& mask,
const Packet& a,
const Packet& b) {
612 return numext::select(mask, a, b);
617template <
typename Packet>
618EIGEN_DEVICE_FUNC
inline Packet pselect(
const Packet& mask,
const Packet& a,
const Packet& b) {
619 return pselect_impl<Packet>::run(mask, a, b);
623EIGEN_DEVICE_FUNC
inline bool pselect<bool>(
const bool& cond,
const bool& a,
const bool& b) {
628template <
typename Packet>
629struct pminmax_propagates_nan : bool_constant<false> {};
635template <
int NaNPropagation,
bool IsInteger,
bool NativePropagatesNaN = false>
637 template <
typename Packet,
typename Op>
638 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
647 template <
typename Packet,
typename Op>
648 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
653 Packet not_nan_mask_a = pcmp_eq(a, a);
654 Packet not_nan_mask_b = pcmp_eq(b, b);
655 return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), b), a);
662template <
bool NativePropagatesNaN>
664 template <
typename Packet,
typename Op>
665 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a,
const Packet& b, Op op) {
666 Packet not_nan_mask_a = pcmp_eq(a, a);
667 Packet not_nan_mask_b = pcmp_eq(b, b);
668 return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), a), b);
672#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) [](const Type& aa, const Type& bb) { return Func(aa, bb); }
676template <
typename Packet>
677EIGEN_DEVICE_FUNC
inline Packet pmin(
const Packet& a,
const Packet& b) {
678 return numext::mini(a, b);
683template <
int NaNPropagation,
typename Packet>
684EIGEN_DEVICE_FUNC
inline Packet pmin(
const Packet& a,
const Packet& b) {
685 constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
686 constexpr bool NativePropagatesNaN = pminmax_propagates_nan<Packet>::value;
687 return pminmax_impl<NaNPropagation, IsInteger, NativePropagatesNaN>::run(
688 a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
693template <
typename Packet>
694EIGEN_DEVICE_FUNC
inline Packet pmax(
const Packet& a,
const Packet& b) {
695 return numext::maxi(a, b);
700template <
int NaNPropagation,
typename Packet>
701EIGEN_DEVICE_FUNC
inline Packet pmax(
const Packet& a,
const Packet& b) {
702 constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
703 constexpr bool NativePropagatesNaN = pminmax_propagates_nan<Packet>::value;
704 return pminmax_impl<NaNPropagation, IsInteger, NativePropagatesNaN>::run(
705 a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmax<Packet>)));
709template <
typename Packet, std::enable_if_t<!(NumTraits<
typename unpacket_traits<Packet>::type>::IsInteger &&
710 !NumTraits<
typename unpacket_traits<Packet>::type>::IsSigned),
712EIGEN_DEVICE_FUNC
inline Packet pabs(
const Packet& a) {
713 return numext::abs(a);
716template <typename Packet, std::enable_if_t<NumTraits<typename unpacket_traits<Packet>::type>::IsInteger &&
717 !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned,
719EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pabs(
const Packet& a) {
724template <
typename Packet>
725EIGEN_DEVICE_FUNC
inline Packet paddsub(
const Packet& a,
const Packet& b) {
726 return pselect(peven_mask(a), padd(a, b), psub(a, b));
730template <
typename Packet>
731EIGEN_DEVICE_FUNC
inline Packet parg(
const Packet& a) {
737template <
int N,
typename T>
738EIGEN_DEVICE_FUNC
inline T parithmetic_shift_right(
const T& a) {
739 return numext::arithmetic_shift_right(a, N);
743template <
int N,
typename T>
744EIGEN_DEVICE_FUNC
inline T plogical_shift_right(
const T& a) {
745 return numext::logical_shift_right(a, N);
749template <
int N,
typename T>
750EIGEN_DEVICE_FUNC
inline T plogical_shift_left(
const T& a) {
751 return numext::logical_shift_left(a, N);
757template <
typename Packet>
758EIGEN_DEVICE_FUNC
inline Packet pfrexp(
const Packet& a, Packet& exponent) {
760 EIGEN_USING_STD(frexp);
761 Packet result =
static_cast<Packet
>(frexp(a, &exp));
762 exponent =
static_cast<Packet
>(exp);
769template <
typename Packet>
770EIGEN_DEVICE_FUNC
inline Packet pldexp(
const Packet& a,
const Packet& exponent) {
771 EIGEN_USING_STD(ldexp)
772 return static_cast<Packet
>(ldexp(a,
static_cast<int>(exponent)));
776template <
typename Packet>
777EIGEN_DEVICE_FUNC
inline std::enable_if_t<NumTraits<typename unpacket_traits<Packet>::type>::IsInteger, Packet>
778pabsdiff(
const Packet& a,
const Packet& b) {
779 return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b));
781template <
typename Packet>
782EIGEN_DEVICE_FUNC
inline std::enable_if_t<!NumTraits<typename unpacket_traits<Packet>::type>::IsInteger, Packet>
783pabsdiff(
const Packet& a,
const Packet& b) {
784 return pabs(psub(a, b));
788template <
typename Packet>
789EIGEN_DEVICE_FUNC
inline Packet pload(
const typename unpacket_traits<Packet>::type* from) {
797template <
typename Packet>
798EIGEN_DEVICE_FUNC
inline Packet pload_partial(
const typename unpacket_traits<Packet>::type* from,
const Index n,
799 const Index offset = 0) {
800 const Index packet_size = unpacket_traits<Packet>::size;
801 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will read past end of packet");
802 using Scalar =
typename unpacket_traits<Packet>::type;
803 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
804 for (Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
805 elements[i] = from[i - offset];
807 return pload<Packet>(elements);
811template <
typename Packet>
812EIGEN_DEVICE_FUNC
inline Packet ploadu(
const typename unpacket_traits<Packet>::type* from) {
818template <
typename Packet>
819EIGEN_DEVICE_FUNC
inline Packet ploadu_partial(
const typename unpacket_traits<Packet>::type* from,
const Index n,
820 const Index offset = 0) {
821 const Index packet_size = unpacket_traits<Packet>::size;
822 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will read past end of packet");
823 using Scalar =
typename unpacket_traits<Packet>::type;
824 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
825 for (Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
826 elements[i] = from[i - offset];
828 return pload<Packet>(elements);
835template <
typename Packet>
836EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_load_available, Packet> ploadu(
837 const typename unpacket_traits<Packet>::type* from,
typename unpacket_traits<Packet>::mask_t umask);
840template <
typename Packet>
841EIGEN_DEVICE_FUNC
inline Packet pset1(
const typename unpacket_traits<Packet>::type& a) {
846template <
typename Packet,
typename BitsType>
847EIGEN_DEVICE_FUNC
inline Packet pset1frombits(BitsType a) {
848 using Scalar =
typename unpacket_traits<Packet>::type;
849 return pset1<Packet>(numext::bit_cast<Scalar>(a));
852template <
typename Packet>
853struct packet_bit_pattern_traits {
854 using Scalar =
typename unpacket_traits<Packet>::type;
855 using Bits =
typename numext::get_integer_by_size<
sizeof(Scalar)>::unsigned_type;
856 enum { HasIntegerBits = !std::is_void<Bits>::value };
861template <
typename Scalar>
862EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pscalar_from_float_bits(numext::uint32_t bits) {
863#if EIGEN_COMP_GNUC_STRICT && defined(__FINITE_MATH_ONLY__) && __FINITE_MATH_ONLY__ && \
864 !defined(EIGEN_GPU_COMPILE_PHASE) && !defined(SYCL_DEVICE_ONLY)
867 __asm__(
"" :
"+m"(bits));
869 EIGEN_FAST_MATH_CONSTANT_BARRIER(bits);
870 return static_cast<Scalar
>(numext::bit_cast<float>(bits));
873template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
874 bool IsScalar = is_scalar<Packet>::value>
875struct psignmask_impl;
877template <
typename Packet,
bool IsScalar>
878struct psignmask_impl<Packet, true, IsScalar> {
879 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
880 using Scalar =
typename packet_bit_pattern_traits<Packet>::Scalar;
881 using Bits =
typename packet_bit_pattern_traits<Packet>::Bits;
882 constexpr Bits kSignBit =
static_cast<Bits
>(Bits(1) << (CHAR_BIT *
sizeof(Scalar) - 1));
883 return pset1frombits<Packet, Bits>(kSignBit);
887template <
typename Scalar>
888struct psignmask_impl<Scalar, false, true> {
889 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() {
return pscalar_from_float_bits<Scalar>(0x80000000u); }
902template <
typename Packet>
903EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet psignmask() {
904 return psignmask_impl<Packet>::run();
917template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
918 bool IsScalar = is_scalar<Packet>::value>
921template <
typename Packet,
bool IsScalar>
922struct pinf_impl<Packet, true, IsScalar> {
923 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
924 using Scalar =
typename packet_bit_pattern_traits<Packet>::Scalar;
925 using Bits =
typename packet_bit_pattern_traits<Packet>::Bits;
926 constexpr int kMantissaBits = std::numeric_limits<Scalar>::digits - 1;
927 constexpr int kExponentBits =
static_cast<int>(CHAR_BIT *
sizeof(Scalar)) - 1 - kMantissaBits;
928 constexpr Bits kInf =
static_cast<Bits
>(((Bits(1) << kExponentBits) - 1) << kMantissaBits);
929 return pset1frombits<Packet, Bits>(kInf);
933template <
typename Scalar>
934struct pinf_impl<Scalar, false, true> {
935 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() {
return pscalar_from_float_bits<Scalar>(0x7f800000u); }
938template <
typename Packet>
939EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pinf() {
940 return pinf_impl<Packet>::run();
944template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
945 bool IsScalar = is_scalar<Packet>::value>
948template <
typename Packet,
bool IsScalar>
949struct pnan_impl<Packet, true, IsScalar> {
950 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
951 using Scalar =
typename packet_bit_pattern_traits<Packet>::Scalar;
952 using Bits =
typename packet_bit_pattern_traits<Packet>::Bits;
953 constexpr int kMantissaBits = std::numeric_limits<Scalar>::digits - 1;
954 constexpr int kExponentBits =
static_cast<int>(CHAR_BIT *
sizeof(Scalar)) - 1 - kMantissaBits;
955 constexpr Bits kInf =
static_cast<Bits
>(((Bits(1) << kExponentBits) - 1) << kMantissaBits);
956 constexpr Bits kNaN =
static_cast<Bits
>(kInf | (Bits(1) << (kMantissaBits - 1)));
957 return pset1frombits<Packet, Bits>(kNaN);
961template <
typename Scalar>
962struct pnan_impl<Scalar, false, true> {
963 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() {
return pscalar_from_float_bits<Scalar>(0x7fc00000u); }
966template <
typename Packet>
967EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnan() {
968 return pnan_impl<Packet>::run();
971template <typename Scalar, std::enable_if_t<std::is_trivially_copyable<Scalar>::value,
int> = 0>
972EIGEN_DEVICE_FUNC
inline Scalar pload1_scalar(
const Scalar* a) {
974 EIGEN_USING_STD(memcpy)
975 memcpy(&scalar, a,
sizeof(Scalar));
979template <typename Scalar, std::enable_if_t<!std::is_trivially_copyable<Scalar>::value,
int> = 0>
980EIGEN_DEVICE_FUNC
inline Scalar pload1_scalar(
const Scalar* a) {
985template <
typename Packet>
986EIGEN_DEVICE_FUNC
inline Packet pload1(
const typename unpacket_traits<Packet>::type* a) {
987 using Scalar =
typename unpacket_traits<Packet>::type;
988 return pset1<Packet>(pload1_scalar<Scalar>(a));
996template <
typename Packet>
997EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ploaddup(
const typename unpacket_traits<Packet>::type* from) {
998 return pload1<Packet>(from);
1007template <
typename Packet>
1008EIGEN_DEVICE_FUNC
inline Packet ploadquad(
const typename unpacket_traits<Packet>::type* from) {
1009 return pload1<Packet>(from);
1021template <
typename Packet>
1022EIGEN_DEVICE_FUNC
inline void pbroadcast4(
const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1,
1023 Packet& a2, Packet& a3) {
1024 a0 = pload1<Packet>(a + 0);
1025 a1 = pload1<Packet>(a + 1);
1026 a2 = pload1<Packet>(a + 2);
1027 a3 = pload1<Packet>(a + 3);
1037template <
typename Packet>
1038EIGEN_DEVICE_FUNC
inline void pbroadcast2(
const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1) {
1039 a0 = pload1<Packet>(a + 0);
1040 a1 = pload1<Packet>(a + 1);
1044template <
typename Packet>
1045EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet plset(
const typename unpacket_traits<Packet>::type& a) {
1051template <
typename Packet>
1052EIGEN_DEVICE_FUNC
inline Packet peven_mask(
const Packet& ) {
1053 using Scalar =
typename unpacket_traits<Packet>::type;
1054 if (is_scalar<Packet>::value) {
1056 return pset1<Packet>(Scalar(1));
1058 const size_t n = unpacket_traits<Packet>::size;
1060 char* bytes =
reinterpret_cast<char*
>(&b);
1061 for (
size_t i = 0; i < n; ++i) {
1062 memset(bytes + i *
sizeof(Scalar), ((i & 1) == 0 ? 0xff : 0),
sizeof(Scalar));
1064 EIGEN_FAST_MATH_CONSTANT_BARRIER(b);
1069template <
typename Scalar,
typename Packet>
1070EIGEN_DEVICE_FUNC
inline void pstore(Scalar* to,
const Packet& from) {
1077template <
typename Scalar,
typename Packet>
1078EIGEN_DEVICE_FUNC
inline void pstore_partial(Scalar* to,
const Packet& from,
const Index n,
const Index offset = 0) {
1079 const Index packet_size = unpacket_traits<Packet>::size;
1080 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will write past end of packet");
1081 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
1082 pstore<Scalar>(elements, from);
1083 for (Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
1084 to[i] = elements[i + offset];
1089template <
typename Scalar,
typename Packet>
1090EIGEN_DEVICE_FUNC
inline void pstoreu(Scalar* to,
const Packet& from) {
1095template <
typename Scalar,
typename Packet>
1096EIGEN_DEVICE_FUNC
inline void pstoreu_partial(Scalar* to,
const Packet& from,
const Index n,
const Index offset = 0) {
1097 const Index packet_size = unpacket_traits<Packet>::size;
1098 eigen_assert(n + offset <= packet_size &&
"number of elements plus offset will write past end of packet");
1099 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
1100 pstore<Scalar>(elements, from);
1101 for (Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
1102 to[i] = elements[i + offset];
1110template <
typename Scalar,
typename Packet>
1111EIGEN_DEVICE_FUNC
inline std::enable_if_t<unpacket_traits<Packet>::masked_store_available,
void> pstoreu(
1112 Scalar* to,
const Packet& from,
typename unpacket_traits<Packet>::mask_t umask);
1114template <
typename Scalar,
typename Packet>
1115EIGEN_DEVICE_FUNC
inline Packet pgather(
const Scalar* from, Index ) {
1116 return ploadu<Packet>(from);
1119template <
typename Scalar,
typename Packet>
1120EIGEN_DEVICE_FUNC
inline Packet pgather_partial(
const Scalar* from, Index stride,
const Index n) {
1121 const Index packet_size = unpacket_traits<Packet>::size;
1122 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
1123 for (Index i = 0; i < numext::mini(n, packet_size); i++) {
1124 elements[i] = from[i * stride];
1126 return pload<Packet>(elements);
1129template <
typename Scalar,
typename Packet>
1130EIGEN_DEVICE_FUNC
inline void pscatter(Scalar* to,
const Packet& from, Index ) {
1134template <
typename Scalar,
typename Packet>
1135EIGEN_DEVICE_FUNC
inline void pscatter_partial(Scalar* to,
const Packet& from, Index stride,
const Index n) {
1136 const Index packet_size = unpacket_traits<Packet>::size;
1137 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
1138 pstore<Scalar>(elements, from);
1139 for (Index i = 0; i < numext::mini(n, packet_size); i++) {
1140 to[i * stride] = elements[i];
1145template <
typename Scalar>
1146EIGEN_DEVICE_FUNC
inline void prefetch(
const Scalar* addr) {
1147#if defined(EIGEN_HIP_DEVICE_COMPILE)
1149#elif defined(EIGEN_CUDA_ARCH)
1150#if defined(__LP64__) || EIGEN_OS_WIN64
1152 asm(
" prefetch.L1 [ %1 ];" :
"=l"(addr) :
"l"(addr));
1155 asm(
" prefetch.L1 [ %1 ];" :
"=r"(addr) :
"r"(addr));
1157#elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
1158 __builtin_prefetch(addr);
1163template <
typename Packet>
1164EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet preverse(
const Packet& a) {
1169template <
typename Packet>
1170EIGEN_DEVICE_FUNC
inline Packet pcplxflip(
const Packet& a) {
1171 return Packet(numext::imag(a), numext::real(a));
1176template <
typename Packet>
1177EIGEN_DEVICE_FUNC
inline Packet pdupreal(
const Packet& a) {
1178 return Packet(numext::real(a), numext::real(a));
1183template <
typename Packet>
1184EIGEN_DEVICE_FUNC
inline Packet pdupimag(
const Packet& a) {
1185 return Packet(numext::imag(a), numext::imag(a));
1193template <
typename Packet>
1194EIGEN_DEVICE_FUNC
inline Packet pisnan(
const Packet& a);
1199template <typename Packet, bool IsComplex = NumTraits<typename unpacket_traits<Packet>::type>::IsComplex,
1200 bool IsScalar = is_scalar<Packet>::value,
1201 bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1204 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return pcmp_lt_or_nan(a, a); }
1210template <
typename Packet,
bool IsScalar>
1211struct pisnan_impl<Packet, false, IsScalar, true> {
1212 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return pzero(a); }
1215template <
typename Packet,
bool IsInteger>
1216struct pisnan_impl<Packet, true, false, IsInteger> {
1217 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
1218 using RealPacket =
typename unpacket_traits<Packet>::as_real;
1220 Packet nan_lanes = Packet(pisnan<RealPacket>(a.v));
1221 return por(nan_lanes, pcplxflip(nan_lanes));
1227template <
typename Scalar,
bool IsInteger>
1228struct pisnan_impl<Scalar, true, true, IsInteger> {
1229 static EIGEN_DEVICE_FUNC
inline Scalar run(
const Scalar& a) {
1230 using RealScalar =
typename NumTraits<Scalar>::Real;
1231 const RealScalar nan_mask =
1232 por(pisnan_impl<RealScalar>::run(numext::real(a)), pisnan_impl<RealScalar>::run(numext::imag(a)));
1233 return Scalar(nan_mask);
1238template <
typename Packet>
1239EIGEN_DEVICE_FUNC
inline Packet pisnan(
const Packet& a) {
1240 return pisnan_impl<Packet>::run(a);
1243template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1245 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return pcmp_eq(pabs(a), pinf<Packet>()); }
1251template <
typename Packet>
1252struct pisinf_impl<Packet, true> {
1253 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return pzero(a); }
1257template <
typename Packet>
1258EIGEN_DEVICE_FUNC
inline Packet pisinf(
const Packet& a) {
1259 return pisinf_impl<Packet>::run(a);
1262template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1263struct pisfinite_impl {
1265 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return pcmp_lt(pabs(a), pinf<Packet>()); }
1270template <
typename Packet>
1271struct pisfinite_impl<Packet, true> {
1272 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return ptrue(a); }
1276template <
typename Packet>
1277EIGEN_DEVICE_FUNC
inline Packet pisfinite(
const Packet& a) {
1278 return pisfinite_impl<Packet>::run(a);
1282template <
typename Packet>
1283EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psin(
const Packet& a) {
1284 EIGEN_USING_STD(sin);
1289template <
typename Packet>
1290EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcos(
const Packet& a) {
1291 EIGEN_USING_STD(cos);
1296template <
typename Packet>
1297EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptan(
const Packet& a) {
1298 EIGEN_USING_STD(tan);
1303template <
typename Packet>
1304EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pasin(
const Packet& a) {
1305 EIGEN_USING_STD(asin);
1310template <
typename Packet>
1311EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacos(
const Packet& a) {
1312 EIGEN_USING_STD(acos);
1317template <
typename Packet>
1318EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh(
const Packet& a) {
1319 EIGEN_USING_STD(sinh);
1324template <
typename Packet>
1325EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh(
const Packet& a) {
1326 EIGEN_USING_STD(cosh);
1331template <
typename Packet>
1332EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patan(
const Packet& a) {
1333 EIGEN_USING_STD(atan);
1338template <
typename Packet>
1339EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptanh(
const Packet& a) {
1340 EIGEN_USING_STD(tanh);
1345template <
typename Packet>
1346EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patanh(
const Packet& a) {
1347 EIGEN_USING_STD(atanh);
1352template <
typename Packet>
1353EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pasinh(
const Packet& a) {
1354 EIGEN_USING_STD(asinh);
1359template <
typename Packet>
1360EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacosh(
const Packet& a) {
1361 EIGEN_USING_STD(acosh);
1366template <
typename Packet>
1367EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(
const Packet& a) {
1368 return numext::exp(a);
1372template <
typename Packet>
1373EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp2(
const Packet& a) {
1374 return numext::exp2(a);
1378template <
typename Packet>
1379EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexpm1(
const Packet& a) {
1380 return numext::expm1(a);
1384template <
typename Packet>
1385EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog(
const Packet& a) {
1386 EIGEN_USING_STD(log);
1391template <
typename Packet>
1392EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog1p(
const Packet& a) {
1393 return numext::log1p(a);
1397template <
typename Packet>
1398EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog10(
const Packet& a) {
1399 EIGEN_USING_STD(log10);
1403template <typename Packet, bool IsComplexPacket = NumTraits<typename unpacket_traits<Packet>::type>::IsComplex &&
1404 !is_scalar<Packet>::value>
1406 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
1407 using Scalar =
typename internal::unpacket_traits<Packet>::type;
1408 using RealScalar =
typename NumTraits<Scalar>::Real;
1409 return pmul(pset1<Packet>(Scalar(RealScalar(EIGEN_LOG2E))), plog(a));
1414template <
typename Packet>
1415struct plog2_impl<Packet, true> {
1416 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
1417 using RealPacket =
typename unpacket_traits<Packet>::as_real;
1418 using RealScalar =
typename unpacket_traits<RealPacket>::type;
1419 return Packet(pmul(pset1<RealPacket>(RealScalar(EIGEN_LOG2E)), plog(a).v));
1424template <
typename Packet>
1425EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(
const Packet& a) {
1426 return plog2_impl<Packet>::run(a);
1430template <
typename Packet>
1431EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt(
const Packet& a) {
1432 return numext::sqrt(a);
1436template <
typename Packet>
1437EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcbrt(
const Packet& a) {
1438 return numext::cbrt(a);
1441template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
1442 bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
1443struct nearest_integer_packetop_impl {
1444 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_floor(
const Packet& x) {
return numext::floor(x); }
1445 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_ceil(
const Packet& x) {
return numext::ceil(x); }
1446 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_rint(
const Packet& x) {
return numext::rint(x); }
1447 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_round(
const Packet& x) {
return numext::round(x); }
1448 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_trunc(
const Packet& x) {
return numext::trunc(x); }
1452template <
typename Packet>
1453EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pround(
const Packet& a) {
1454 return nearest_integer_packetop_impl<Packet>::run_round(a);
1458template <
typename Packet>
1459EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pfloor(
const Packet& a) {
1460 return nearest_integer_packetop_impl<Packet>::run_floor(a);
1465template <
typename Packet>
1466EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet print(
const Packet& a) {
1467 return nearest_integer_packetop_impl<Packet>::run_rint(a);
1471template <
typename Packet>
1472EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pceil(
const Packet& a) {
1473 return nearest_integer_packetop_impl<Packet>::run_ceil(a);
1477template <
typename Packet>
1478EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ptrunc(
const Packet& a) {
1479 return nearest_integer_packetop_impl<Packet>::run_trunc(a);
1482template <
typename Packet,
typename EnableIf =
void>
1484 static EIGEN_DEVICE_FUNC
inline Packet run(
const Packet& a) {
return numext::sign(a); }
1488template <
typename Packet>
1489EIGEN_DEVICE_FUNC
inline Packet psign(
const Packet& a) {
1490 return psign_impl<Packet>::run(a);
1494EIGEN_DEVICE_FUNC
inline bool psign(
const bool& a) {
1499template <
typename Packet>
1500EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type pfirst(
const Packet& a) {
1508template <
typename Packet>
1509EIGEN_DEVICE_FUNC
inline std::conditional_t<(unpacket_traits<Packet>::size % 8) == 0,
1510 typename unpacket_traits<Packet>::half, Packet>
1511predux_half(
const Packet& a) {
1516template <
typename Packet,
typename Op>
1517EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_helper(
const Packet& a, Op op) {
1518 using Scalar =
typename unpacket_traits<Packet>::type;
1519 const size_t n = unpacket_traits<Packet>::size;
1520 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[n];
1521 pstoreu<Scalar>(elements, a);
1522 for (
size_t k = n / 2; k > 0; k /= 2) {
1523 for (
size_t i = 0; i < k; ++i) {
1524 elements[i] = op(elements[i], elements[i + k]);
1530template <typename Packet, std::enable_if_t<unpacket_traits<Packet>::size == 1,
int> = 0>
1531EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
typename unpacket_traits<Packet>::type predux_one_element(
const Packet& a) {
1536template <
typename Packet>
1537EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
typename unpacket_traits<Packet>::type predux(
const Packet& a) {
1538 return predux_one_element(a);
1542template <
typename Packet>
1543EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
typename unpacket_traits<Packet>::type predux_mul(
const Packet& a) {
1544 using Scalar =
typename unpacket_traits<Packet>::type;
1545 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmul<Scalar>)));
1549template <
typename Packet>
1550EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_min(
const Packet& a) {
1551 using Scalar =
typename unpacket_traits<Packet>::type;
1552 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<Scalar>)));
1556template <
typename Packet>
1557EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_max(
const Packet& a) {
1558 using Scalar =
typename unpacket_traits<Packet>::type;
1559 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<Scalar>)));
1562template <
int NaNPropagation,
typename Packet>
1563struct predux_min_max_helper_impl {
1564 using Scalar =
typename unpacket_traits<Packet>::type;
1565 static constexpr bool UsePredux_ = NaNPropagation ==
PropagateFast || NumTraits<Scalar>::IsInteger;
1566 template <
bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux,
bool> = true>
1567 static EIGEN_DEVICE_FUNC
inline Scalar run_min(
const Packet& a) {
1568 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<NaNPropagation, Scalar>)));
1570 template <
bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux,
bool> = true>
1571 static EIGEN_DEVICE_FUNC
inline Scalar run_max(
const Packet& a) {
1572 return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<NaNPropagation, Scalar>)));
1574 template <
bool UsePredux = UsePredux_, std::enable_if_t<UsePredux,
bool> = true>
1575 static EIGEN_DEVICE_FUNC
inline Scalar run_min(
const Packet& a) {
1576 return predux_min(a);
1578 template <
bool UsePredux = UsePredux_, std::enable_if_t<UsePredux,
bool> = true>
1579 static EIGEN_DEVICE_FUNC
inline Scalar run_max(
const Packet& a) {
1580 return predux_max(a);
1584template <
int NaNPropagation,
typename Packet>
1585EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_min(
const Packet& a) {
1586 return predux_min_max_helper_impl<NaNPropagation, Packet>::run_min(a);
1589template <
int NaNPropagation,
typename Packet>
1590EIGEN_DEVICE_FUNC
inline typename unpacket_traits<Packet>::type predux_max(
const Packet& a) {
1591 return predux_min_max_helper_impl<NaNPropagation, Packet>::run_max(a);
1594#undef EIGEN_BINARY_OP_NAN_PROPAGATION
1596template <typename Packet, bool IsBoolean = std::is_same<typename unpacket_traits<Packet>::type,
bool>::value>
1597struct predux_count_impl {
1598 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE Index run(
const Packet& a) {
1599 using Scalar =
typename unpacket_traits<Packet>::type;
1600 const Packet true_values = pandnot(pset1<Packet>(Scalar(1)), pcmp_eq(a, pzero(a)));
1601 return static_cast<Index
>(numext::real(predux(true_values)));
1605template <
typename Packet>
1606struct predux_count_impl<Packet, true> {
1607 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE Index run(
const Packet& a) {
1608 using Scalar =
typename unpacket_traits<Packet>::type;
1609 constexpr int PacketSize = unpacket_traits<Packet>::size;
1610 EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar values[PacketSize];
1611 pstoreu<Scalar>(values, a);
1613 for (
int i = 0; i < PacketSize; ++i) result += values[i] ? 1 : 0;
1619template <
typename Packet>
1620EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index predux_count(
const Packet& a) {
1621 return predux_count_impl<Packet>::run(a);
1627template <
typename Packet>
1628EIGEN_DEVICE_FUNC
inline bool predux_any(
const Packet& a) {
1636 using Scalar =
typename unpacket_traits<Packet>::type;
1637 return numext::not_equal_strict(predux(a), Scalar(0));
1640template <typename Packet, bool IsBoolean = std::is_same<typename unpacket_traits<Packet>::type,
bool>::value>
1641struct predux_all_impl {
1642 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE
bool run(
const Packet& a) {
return !predux_any(pcmp_eq(a, pzero(a))); }
1645template <
typename Packet>
1646struct predux_all_impl<Packet, true> {
1647 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE
bool run(
const Packet& a) {
return predux_mul(a); }
1651template <
typename Packet>
1652EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool predux_all(
const Packet& a) {
1653 return predux_all_impl<Packet>::run(a);
1660template <
typename Packet,
typename EnableIf =
void>
1662 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1663 return padd(pmul(a, b), c);
1665 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1666 return psub(pmul(a, b), c);
1668 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1669 return psub(c, pmul(a, b));
1671 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1672 return pnegate(padd(pmul(a, b), c));
1676template <
typename Scalar>
1677struct pmadd_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value && NumTraits<Scalar>::IsSigned>> {
1678 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmadd(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1679 return numext::madd<Scalar>(a, b, c);
1681 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmsub(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1682 return numext::madd<Scalar>(a, b, Scalar(-c));
1684 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmadd(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1685 return numext::madd<Scalar>(Scalar(-a), b, c);
1687 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmsub(
const Scalar& a,
const Scalar& b,
const Scalar& c) {
1688 return -Scalar(numext::madd<Scalar>(a, b, c));
1694template <
typename Packet>
1695EIGEN_DEVICE_FUNC
inline Packet pmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1696 return pmadd_impl<Packet>::pmadd(a, b, c);
1700template <
typename Packet>
1701EIGEN_DEVICE_FUNC
inline Packet pmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1702 return pmadd_impl<Packet>::pmsub(a, b, c);
1706template <
typename Packet>
1707EIGEN_DEVICE_FUNC
inline Packet pnmadd(
const Packet& a,
const Packet& b,
const Packet& c) {
1708 return pmadd_impl<Packet>::pnmadd(a, b, c);
1712template <
typename Packet>
1713EIGEN_DEVICE_FUNC
inline Packet pnmsub(
const Packet& a,
const Packet& b,
const Packet& c) {
1714 return pmadd_impl<Packet>::pnmsub(a, b, c);
1721template <
typename Packet>
1722inline void pstore1(
typename unpacket_traits<Packet>::type* to,
const typename unpacket_traits<Packet>::type& a) {
1723 pstore(to, pset1<Packet>(a));
1728template <
typename Packet,
int Alignment>
1729EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(
const typename unpacket_traits<Packet>::type* from) {
1730 EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
1731 return pload<Packet>(from);
1733 return ploadu<Packet>(from);
1739template <
typename Packet,
int Alignment>
1740EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_partial(
const typename unpacket_traits<Packet>::type* from,
1741 const Index n,
const Index offset = 0) {
1742 EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
1743 return pload_partial<Packet>(from, n, offset);
1745 return ploadu_partial<Packet>(from, n, offset);
1751template <
typename Scalar,
typename Packet,
int Alignment>
1752EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pstoret(Scalar* to,
const Packet& from) {
1753 EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
1762template <
typename Scalar,
typename Packet,
int Alignment>
1763EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pstoret_partial(Scalar* to,
const Packet& from,
const Index n,
1764 const Index offset = 0) {
1765 EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
1766 pstore_partial(to, from, n, offset);
1768 pstoreu_partial(to, from, n, offset);
1777template <
typename Packet,
int LoadMode>
1778EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(
const typename unpacket_traits<Packet>::type* from) {
1779 return ploadt<Packet, LoadMode>(from);
1787#if !defined(EIGEN_GPUCC)
1790inline std::complex<float> pmul(
const std::complex<float>& a,
const std::complex<float>& b) {
1791 return std::complex<float>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
1795inline std::complex<double> pmul(
const std::complex<double>& a,
const std::complex<double>& b) {
1796 return std::complex<double>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
1805template <typename Packet, int N = unpacket_traits<Packet>::size>
1810template <
typename Packet,
int size = 1>
1811EIGEN_DEVICE_FUNC
inline void ptranspose(PacketBlock<Packet, size>& ) {
1816template <
typename Packet>
1817EIGEN_DEVICE_FUNC
inline Packet preciprocal(
const Packet& a) {
1818 using Scalar =
typename unpacket_traits<Packet>::type;
1819 return pdiv(pset1<Packet>(Scalar(1)), a);
1823template <
typename Packet>
1824EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet prsqrt(
const Packet& a) {
1825 return preciprocal<Packet>(psqrt(a));
1828template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
1829 bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger,
1830 bool IsUnsigned = IsInteger && !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned>
1831struct psignbit_impl;
1832template <
typename Packet,
bool IsInteger,
bool IsUn
signed>
1833struct psignbit_impl<Packet, true, IsInteger, IsUnsigned> {
1834 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static constexpr Packet run(
const Packet& a) {
return numext::signbit(a); }
1836template <
typename Packet>
1837struct psignbit_impl<Packet, false, false, false> {
1840 using Scalar =
typename unpacket_traits<Packet>::type;
1841 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static Packet run(
const Packet& a) {
1842 const Packet cst_pos_one = pset1<Packet>(Scalar(1));
1843 const Packet cst_neg_one = pset1<Packet>(Scalar(-1));
1844 return pcmp_eq(por(pand(a, cst_neg_one), cst_pos_one), cst_neg_one);
1847template <
typename Packet>
1848struct psignbit_impl<Packet, false, true, false> {
1850 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static constexpr Packet run(
const Packet& a) {
return pcmp_lt(a, pzero(a)); }
1852template <
typename Packet>
1853struct psignbit_impl<Packet, false, true, true> {
1854 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static constexpr Packet run(
const Packet& a) {
return pzero(a); }
1857template <
typename Packet>
1858EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
constexpr Packet psignbit(
const Packet& a) {
1859 return psignbit_impl<Packet>::run(a);
1863template <typename Packet, std::enable_if_t<is_scalar<Packet>::value,
int> = 0>
1864EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(
const Packet& y,
const Packet& x) {
1865 return numext::atan2(y, x);
1869template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value,
int> = 0>
1870EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(
const Packet& y,
const Packet& x) {
1871 using Scalar =
typename internal::unpacket_traits<Packet>::type;
1876 const Packet kSignMask = psignmask<Packet>();
1877 const Packet kZero = pzero(x);
1878 const Packet kOne = pset1<Packet>(Scalar(1));
1879 const Packet kPi = pset1<Packet>(Scalar(EIGEN_PI));
1881 const Packet x_has_signbit = psignbit(x);
1882 const Packet y_signmask = pand(y, kSignMask);
1883 const Packet x_signmask = pand(x, kSignMask);
1884 const Packet result_signmask = pxor(y_signmask, x_signmask);
1885 const Packet shift = por(pand(x_has_signbit, kPi), y_signmask);
1887 const Packet x_and_y_are_same = pcmp_eq(pabs(x), pabs(y));
1888 const Packet x_and_y_are_zero = pcmp_eq(por(x, y), kZero);
1890 Packet arg = pdiv(y, x);
1891 arg = pselect(x_and_y_are_same, por(kOne, result_signmask), arg);
1892 arg = pselect(x_and_y_are_zero, result_signmask, arg);
1894 Packet result = patan(arg);
1895 result = padd(result, shift);
1900template <typename Packet, std::enable_if_t<is_scalar<Packet>::value,
int> = 0>
1901EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(
const Packet& a) {
1902 return Packet(numext::arg(a));
1906template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value,
int> = 0>
1907EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(
const Packet& a) {
1908 EIGEN_STATIC_ASSERT(NumTraits<
typename unpacket_traits<Packet>::type>::IsComplex,
1909 THIS METHOD IS FOR COMPLEX TYPES ONLY)
1910 using RealPacket =
typename unpacket_traits<Packet>::as_real;
1912 RealPacket aflip = pcplxflip(a).v;
1913 RealPacket result = patan2(aflip, a.v);
1914 return (Packet)pand(result, peven_mask(result));
1919template <
typename Packet>
1920EIGEN_DEVICE_FUNC
inline Packet ploaduSegment(
const typename unpacket_traits<Packet>::type* from, Index begin,
1922 using Scalar =
typename unpacket_traits<Packet>::type;
1923 constexpr Index PacketSize = unpacket_traits<Packet>::size;
1924 eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) &&
"invalid range");
1925 Scalar aux[PacketSize] = {};
1926 for (Index k = begin; k < begin + count; k++) {
1929 return ploadu<Packet>(aux);
1934template <
typename Packet>
1935EIGEN_DEVICE_FUNC
inline Packet ploadSegment(
const typename unpacket_traits<Packet>::type* from, Index begin,
1937 return ploaduSegment<Packet>(from, begin, count);
1943template <
typename Scalar,
typename Packet>
1944EIGEN_DEVICE_FUNC
inline void pstoreuSegment(Scalar* to,
const Packet& from, Index begin, Index count) {
1945 constexpr Index PacketSize = unpacket_traits<Packet>::size;
1946 eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) &&
"invalid range");
1947 Scalar aux[PacketSize];
1948 pstoreu<Scalar, Packet>(aux, from);
1949 for (Index k = begin; k < begin + count; k++) {
1957template <
typename Scalar,
typename Packet>
1958EIGEN_DEVICE_FUNC
inline void pstoreSegment(Scalar* to,
const Packet& from, Index begin, Index count) {
1959 return pstoreuSegment(to, from, begin, count);
1964template <
typename Packet,
int Alignment>
1965EIGEN_DEVICE_FUNC
inline Packet ploadtSegment(
const typename unpacket_traits<Packet>::type* from, Index begin,
1967 constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
1968 EIGEN_IF_CONSTEXPR (Alignment >= RequiredAlignment) {
1969 return ploadSegment<Packet>(from, begin, count);
1971 return ploaduSegment<Packet>(from, begin, count);
1977template <
typename Scalar,
typename Packet,
int Alignment>
1978EIGEN_DEVICE_FUNC
inline void pstoretSegment(Scalar* to,
const Packet& from, Index begin, Index count) {
1979 constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
1980 EIGEN_IF_CONSTEXPR (Alignment >= RequiredAlignment) {
1981 pstoreSegment<Scalar, Packet>(to, from, begin, count);
1983 pstoreuSegment<Scalar, Packet>(to, from, begin, count);
1989template <
typename Packet>
1990class StreamablePacket {
1992 using Scalar =
typename unpacket_traits<Packet>::type;
1993 StreamablePacket(
const Packet& packet) { pstoreu(v_, packet); }
1995 friend std::ostream& operator<<(std::ostream& os,
const StreamablePacket& packet) {
1996 os <<
"{" << packet.v_[0];
1997 for (
int i = 1; i < unpacket_traits<Packet>::size; ++i) {
1998 os <<
"," << packet.v_[i];
2005 Scalar v_[unpacket_traits<Packet>::size];
2011template <
typename Packet>
2012StreamablePacket<Packet> postream(
const Packet& packet) {
2013 return StreamablePacket<Packet>(packet);
@ PropagateNaN
Definition Constants.h:343
@ PropagateNumbers
Definition Constants.h:345
@ PropagateFast
Definition Constants.h:341