// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_GENERIC_PACKET_MATH_H
#define EIGEN_GENERIC_PACKET_MATH_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

/** \internal
 * \file GenericPacketMath.h
 *
 * Default implementation for types not supported by the vectorization.
 * In practice these functions are provided to make easier the writing
 * of generic vectorized code.
 */

#ifndef EIGEN_DEBUG_ALIGNED_LOAD
#define EIGEN_DEBUG_ALIGNED_LOAD
#endif

#ifndef EIGEN_DEBUG_UNALIGNED_LOAD
#define EIGEN_DEBUG_UNALIGNED_LOAD
#endif

#ifndef EIGEN_DEBUG_ALIGNED_STORE
#define EIGEN_DEBUG_ALIGNED_STORE
#endif

#ifndef EIGEN_DEBUG_UNALIGNED_STORE
#define EIGEN_DEBUG_UNALIGNED_STORE
#endif

struct default_packet_traits {
  enum {
    // Ops that are implemented for most types.
    HasAdd = 1,
    HasSub = 1,
    HasShift = 1,
    HasMul = 1,
    HasNegate = 1,
    HasAbs = 1,
    HasAbs2 = 1,
    HasMin = 1,
    HasMax = 1,
    HasConj = 1,
    HasSetLinear = 1,
    HasSign = 1,
    HasAbsDiff = 1,
    // By default, the nearest integer functions (rint, round, floor, ceil, trunc) are enabled for all scalar and packet
    // types
    HasRound = 1,

    HasArg = 0,
    // This flag is used to indicate whether packet comparison is supported.
    // pcmp_eq and pcmp_lt should be defined for it to be true.
    HasCmp = 0,

    HasDiv = 0,
    HasReciprocal = 0,
    HasSqrt = 0,
    HasRsqrt = 0,
    HasCbrt = 0,
    HasExp = 0,
    HasExpm1 = 0,
    HasLog = 0,
    HasLog1p = 0,
    HasLog10 = 0,
    HasPow = 0,
    HasSin = 0,
    HasCos = 0,
    HasTan = 0,
    HasASin = 0,
    HasACos = 0,
    HasATan = 0,
    HasATanh = 0,
    HasSinh = 0,
    HasCosh = 0,
    HasASinh = 0,
    HasACosh = 0,
    HasTanh = 0,
    HasLGamma = 0,
    HasDiGamma = 0,
    HasZeta = 0,
    HasPolygamma = 0,
    HasErf = 0,
    HasErfc = 0,
    HasNdtri = 0,
    HasBessel = 0,
    HasIGamma = 0,
    HasIGammaDerA = 0,
    HasGammaSampleDerAlpha = 0,
    HasIGammac = 0,
    HasBetaInc = 0
  };
};

template <typename T>
struct packet_traits : default_packet_traits {
  using type = T;
  using half = T;
  enum {
    Vectorizable = 0,
    size = 1,
    AlignedOnScalar = 0,
  };
  enum {
    HasAdd = 0,
    HasSub = 0,
    HasAbsDiff = 0,
    HasMul = 0,
    HasNegate = 0,
    HasAbs = 0,
    HasAbs2 = 0,
    HasMin = 0,
    HasMax = 0,
    HasConj = 0,
    HasSetLinear = 0
  };
};

template <typename T>
struct packet_traits<const T> : packet_traits<T> {};

struct default_unpacket_traits {
  enum { vectorizable = false, masked_load_available = false, masked_store_available = false };
};

template <typename T>
struct unpacket_traits : default_unpacket_traits {
  using type = T;
  using half = T;
  using integer_packet = typename numext::get_integer_by_size<sizeof(T)>::signed_type;
  enum {
    size = 1,
    alignment = alignof(T),
  };
};

template <typename T>
struct unpacket_traits<const T> : unpacket_traits<T> {};

/** \internal A convenience utility for determining if the type is a scalar.
 * This is used to enable some generic packet implementations.
 */
template <typename Packet>
struct is_scalar : std::is_same<Packet, typename unpacket_traits<Packet>::type> {};

// automatically and succinctly define combinations of pcast<SrcPacket,TgtPacket> when
// 1) the packets are the same type, or
// 2) the packets differ only in sign.
// In both of these cases, preinterpret (bit_cast) is equivalent to pcast (static_cast)
template <typename SrcPacket, typename TgtPacket,
          bool Scalar = is_scalar<SrcPacket>::value && is_scalar<TgtPacket>::value>
struct is_degenerate_helper : std::is_same<SrcPacket, TgtPacket> {};
template <>
struct is_degenerate_helper<int8_t, uint8_t, true> : std::true_type {};
template <>
struct is_degenerate_helper<int16_t, uint16_t, true> : std::true_type {};
template <>
struct is_degenerate_helper<int32_t, uint32_t, true> : std::true_type {};
template <>
struct is_degenerate_helper<int64_t, uint64_t, true> : std::true_type {};

template <typename SrcPacket, typename TgtPacket>
struct is_degenerate_helper<SrcPacket, TgtPacket, false> {
  using SrcScalar = typename unpacket_traits<SrcPacket>::type;
  static constexpr int SrcSize = unpacket_traits<SrcPacket>::size;
  using TgtScalar = typename unpacket_traits<TgtPacket>::type;
  static constexpr int TgtSize = unpacket_traits<TgtPacket>::size;
  static constexpr bool value = is_degenerate_helper<SrcScalar, TgtScalar, true>::value && (SrcSize == TgtSize);
};

// is_degenerate<T1,T2>::value == is_degenerate<T2,T1>::value
template <typename SrcPacket, typename TgtPacket>
struct is_degenerate {
  static constexpr bool value =
      is_degenerate_helper<SrcPacket, TgtPacket>::value || is_degenerate_helper<TgtPacket, SrcPacket>::value;
};

template <typename Packet>
struct is_half {
  using Scalar = typename unpacket_traits<Packet>::type;
  static constexpr int Size = unpacket_traits<Packet>::size;
  using DefaultPacket = typename packet_traits<Scalar>::type;
  static constexpr int DefaultSize = unpacket_traits<DefaultPacket>::size;
  static constexpr bool value = Size != 1 && Size < DefaultSize;
};

template <typename Src, typename Tgt>
struct type_casting_traits {
  enum {
    VectorizedCast =
        is_degenerate<Src, Tgt>::value && packet_traits<Src>::Vectorizable && packet_traits<Tgt>::Vectorizable,
    SrcCoeffRatio = 1,
    TgtCoeffRatio = 1
  };
};

// provides a succinct template to define vectorized casting traits with respect to the largest accessible packet types
template <typename Src, typename Tgt>
struct vectorized_type_casting_traits {
  enum : int {
    DefaultSrcPacketSize = packet_traits<Src>::size,
    DefaultTgtPacketSize = packet_traits<Tgt>::size,
    VectorizedCast = 1,
    SrcCoeffRatio = plain_enum_max(DefaultTgtPacketSize / DefaultSrcPacketSize, 1),
    TgtCoeffRatio = plain_enum_max(DefaultSrcPacketSize / DefaultTgtPacketSize, 1)
  };
};

/** \internal Wrapper to ensure that multiple packet types can map to the same
    underlying vector type. */
template <typename T, int unique_id = 0>
struct eigen_packet_wrapper {
  EIGEN_ALWAYS_INLINE operator T&() { return m_val; }
  EIGEN_ALWAYS_INLINE operator const T&() const { return m_val; }
  EIGEN_ALWAYS_INLINE eigen_packet_wrapper() = default;
  EIGEN_ALWAYS_INLINE eigen_packet_wrapper(const T& v) : m_val(v) {}
  EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(const T& v) {
    m_val = v;
    return *this;
  }

  T m_val;
};

template <typename Target, typename Packet, bool IsSame = std::is_same<Target, Packet>::value>
struct preinterpret_generic;

template <typename Target, typename Packet>
struct preinterpret_generic<Target, Packet, false> {
  // the packets are not the same, attempt scalar bit_cast
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Target run(const Packet& a) {
    return numext::bit_cast<Target, Packet>(a);
  }
};

template <typename Packet>
struct preinterpret_generic<Packet, Packet, true> {
  // the packets are the same type: do nothing
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& a) { return a; }
};

template <typename ComplexPacket>
struct preinterpret_generic<typename unpacket_traits<ComplexPacket>::as_real, ComplexPacket, false> {
  using RealPacket = typename unpacket_traits<ComplexPacket>::as_real;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE RealPacket run(const ComplexPacket& a) { return a.v; }
};

/** \internal \returns reinterpret_cast<Target>(a) */
template <typename Target, typename Packet>
EIGEN_DEVICE_FUNC inline Target preinterpret(const Packet& a) {
  return preinterpret_generic<Target, Packet>::run(a);
}

template <typename SrcPacket, typename TgtPacket, bool Degenerate = is_degenerate<SrcPacket, TgtPacket>::value,
          bool TgtIsHalf = is_half<TgtPacket>::value>
struct pcast_generic;

template <typename SrcPacket, typename TgtPacket>
struct pcast_generic<SrcPacket, TgtPacket, false, false> {
  // the packets are not degenerate: attempt scalar static_cast
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(const SrcPacket& a) {
    return cast_impl<SrcPacket, TgtPacket>::run(a);
  }
};

template <typename Packet>
struct pcast_generic<Packet, Packet, true, false> {
  // the packets are the same: do nothing
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& a) { return a; }
};

template <typename SrcPacket, typename TgtPacket, bool TgtIsHalf>
struct pcast_generic<SrcPacket, TgtPacket, true, TgtIsHalf> {
  // the packets are degenerate: preinterpret is equivalent to pcast
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(const SrcPacket& a) { return preinterpret<TgtPacket>(a); }
};

/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
template <typename SrcPacket, typename TgtPacket>
EIGEN_DEVICE_FUNC inline TgtPacket pcast(const SrcPacket& a) {
  return pcast_generic<SrcPacket, TgtPacket>::run(a);
}
template <typename SrcPacket, typename TgtPacket>
EIGEN_DEVICE_FUNC inline TgtPacket pcast(const SrcPacket& a, const SrcPacket& b) {
  return pcast_generic<SrcPacket, TgtPacket>::run(a, b);
}
template <typename SrcPacket, typename TgtPacket>
EIGEN_DEVICE_FUNC inline TgtPacket pcast(const SrcPacket& a, const SrcPacket& b, const SrcPacket& c,
                                         const SrcPacket& d) {
  return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d);
}
template <typename SrcPacket, typename TgtPacket>
EIGEN_DEVICE_FUNC inline TgtPacket pcast(const SrcPacket& a, const SrcPacket& b, const SrcPacket& c, const SrcPacket& d,
                                         const SrcPacket& e, const SrcPacket& f, const SrcPacket& g,
                                         const SrcPacket& h) {
  return pcast_generic<SrcPacket, TgtPacket>::run(a, b, c, d, e, f, g, h);
}

template <typename SrcPacket, typename TgtPacket>
struct pcast_generic<SrcPacket, TgtPacket, false, true> {
  // TgtPacket is a half packet of some other type
  // perform cast and truncate result
  using DefaultTgtPacket = typename is_half<TgtPacket>::DefaultPacket;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TgtPacket run(const SrcPacket& a) {
    return preinterpret<TgtPacket>(pcast<SrcPacket, DefaultTgtPacket>(a));
  }
};

// Make x opaque to the compiler without changing its value, where supported.
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pbarrier(Packet& x) {
  EIGEN_UNUSED_VARIABLE(x);
  EIGEN_OPTIMIZATION_BARRIER(x)
}
// The wrapper is a class, which EIGEN_OPTIMIZATION_BARRIER passes through memory; its vector can stay in a register.
template <typename T, int unique_id>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pbarrier(eigen_packet_wrapper<T, unique_id>& x) {
  pbarrier(x.m_val);
}

/** \internal \returns a + b (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet padd(const Packet& a, const Packet& b) {
  return a + b;
}
// Bool arithmetic is specialized to avoid compiler warnings. Bitwise operations are intentional to keep scalar
// evaluator loops branch-free.
template <>
EIGEN_DEVICE_FUNC inline bool padd(const bool& a, const bool& b) {
  return a | b;
}

/** \internal \returns a packet version of \a *from, (un-aligned masked add)
 * There is no generic implementation. We only have implementations for specialized
 * cases. Generic case should not be called.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline std::enable_if_t<unpacket_traits<Packet>::masked_fpops_available, Packet> padd(
    const Packet& a, const Packet& b, typename unpacket_traits<Packet>::mask_t umask);

/** \internal \returns a - b (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet psub(const Packet& a, const Packet& b) {
  return a - b;
}

/** \internal \returns -a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pnegate(const Packet& a) {
  EIGEN_STATIC_ASSERT((!std::is_same<typename unpacket_traits<Packet>::type, bool>::value),
                      NEGATE IS NOT DEFINED FOR BOOLEAN TYPES)
  return numext::negate(a);
}

/** \internal \returns conj(a) (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pconj(const Packet& a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex)
    return numext::conj(a);
  else
    return a;
}

/** \internal \returns a * b (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmul(const Packet& a, const Packet& b) {
  return internal::mul(a, b);
}
template <>
EIGEN_DEVICE_FUNC inline bool pmul(const bool& a, const bool& b) {
  return a & b;
}

/** \internal \returns a / b (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pdiv(const Packet& a, const Packet& b) {
  return a / b;
}
template <>
EIGEN_DEVICE_FUNC inline bool pdiv(const bool& a, const bool& b) {
  return a & b;
}

// In the generic packet case, memset to all one bits.
template <typename Packet, typename EnableIf = void>
struct ptrue_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/) {
    Packet b;
    memset(static_cast<void*>(&b), 0xff, sizeof(Packet));
    return b;
  }
};

// Use a value of one for scalars.
template <typename Scalar>
struct ptrue_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value>> {
  static EIGEN_DEVICE_FUNC inline Scalar run(const Scalar&) { return Scalar(1); }
};

// For booleans, we can only directly set a valid `bool` value to avoid UB.
template <>
struct ptrue_impl<bool, void> {
  static EIGEN_DEVICE_FUNC inline bool run(const bool&) { return true; }
};

// The all-ones value of a floating-point packet is a NaN bit pattern, which fast-math builds
// may fold to poison; see EIGEN_FAST_MATH_CONSTANT_BARRIER in Macros.h. The same applies to
// peven_mask, pinf and pnan below.
/** \internal \returns one bits. */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ptrue(const Packet& a) {
  if (is_scalar<Packet>::value || std::is_same<Packet, bool>::value) {
    // Scalar and boolean "masks" hold the value one, which is a legal value class; delegating
    // to ptrue_impl (and its specializations) is safe here.
    return ptrue_impl<Packet>::run(a);
  }
  Packet b;
  memset(static_cast<void*>(&b), 0xff, sizeof(Packet));
  // Every backend stores integer packets in integer vector types, which the poison folding does not affect.
  EIGEN_IF_CONSTEXPR (!NumTraits<typename unpacket_traits<Packet>::type>::IsInteger) {
    EIGEN_FAST_MATH_CONSTANT_BARRIER(b);
  }
  return b;
}

// In the general packet case, memset to zero.
template <typename Packet, typename EnableIf = void>
struct pzero_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/) {
    Packet b;
    memset(static_cast<void*>(&b), 0x00, sizeof(Packet));
    return b;
  }
};

// For scalars, explicitly set to Scalar(0), since the underlying representation
// for zero may not consist of all-zero bits.
template <typename T>
struct pzero_impl<T, std::enable_if_t<is_scalar<T>::value>> {
  static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/) { return T(0); }
};

/** \internal \returns packet of zeros */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pzero(const Packet& a) {
  return pzero_impl<Packet>::run(a);
}

template <typename T>
struct bit_and {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const { return a & b; }
};

template <typename T>
struct bit_or {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const { return a | b; }
};

template <typename T>
struct bit_xor {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const { return a ^ b; }
};

template <typename T>
struct bit_not {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE T operator()(const T& a) const { return ~a; }
};

template <>
struct bit_and<bool> {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE bool operator()(const bool& a, const bool& b) const { return a & b; }
};

template <>
struct bit_or<bool> {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE bool operator()(const bool& a, const bool& b) const { return a | b; }
};

template <>
struct bit_xor<bool> {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE bool operator()(const bool& a, const bool& b) const { return a != b; }
};

template <>
struct bit_not<bool> {
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE bool operator()(const bool& a) const { return !a; }
};

// Use operators &, |, ^, ~.
template <typename T>
struct operator_bitwise_helper {
  EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) { return bit_and<T>()(a, b); }
  EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { return bit_or<T>()(a, b); }
  EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) { return bit_xor<T>()(a, b); }
  EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { return bit_not<T>()(a); }
};

// Apply binary operations byte-by-byte
template <typename T>
struct bytewise_bitwise_helper {
  EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) {
    return binary(a, b, bit_and<unsigned char>());
  }
  EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { return binary(a, b, bit_or<unsigned char>()); }
  EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) {
    return binary(a, b, bit_xor<unsigned char>());
  }
  EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { return unary(a, bit_not<unsigned char>()); }

 private:
  template <typename Op>
  EIGEN_DEVICE_FUNC static inline T unary(const T& a, Op op) {
    const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
    T c;
    unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
    for (size_t i = 0; i < sizeof(T); ++i) {
      *c_ptr++ = op(*a_ptr++);
    }
    return c;
  }

  template <typename Op>
  EIGEN_DEVICE_FUNC static inline T binary(const T& a, const T& b, Op op) {
    const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
    const unsigned char* b_ptr = reinterpret_cast<const unsigned char*>(&b);
    T c;
    unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
    for (size_t i = 0; i < sizeof(T); ++i) {
      *c_ptr++ = op(*a_ptr++, *b_ptr++);
    }
    return c;
  }
};

// In the general case, use byte-by-byte manipulation.
template <typename T, typename EnableIf = void>
struct bitwise_helper : public bytewise_bitwise_helper<T> {};

// For integers or non-trivial scalars, use binary operators.
template <typename T>
struct bitwise_helper<
    T, std::enable_if_t<is_scalar<T>::value && (NumTraits<T>::IsInteger || NumTraits<T>::RequireInitialization)>>
    : public operator_bitwise_helper<T> {};

/** \internal \returns the bitwise and of \a a and \a b */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pand(const Packet& a, const Packet& b) {
  return bitwise_helper<Packet>::bitwise_and(a, b);
}

/** \internal \returns the bitwise or of \a a and \a b */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet por(const Packet& a, const Packet& b) {
  return bitwise_helper<Packet>::bitwise_or(a, b);
}

/** \internal \returns the bitwise xor of \a a and \a b */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pxor(const Packet& a, const Packet& b) {
  return bitwise_helper<Packet>::bitwise_xor(a, b);
}

// Packets use the backend's pxor and ptrue: compilers do not reliably vectorize the bytewise fallback (GCC 10 at -O2,
// GCC and Clang at -O1). For boolean packets ptrue is true, so this is the logical not.
template <typename Packet, bool IsScalar = is_scalar<Packet>::value>
struct pnot_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pxor(a, ptrue(a)); }
};

template <typename Packet>
struct pnot_impl<Packet, true> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return bitwise_helper<Packet>::bitwise_not(a); }
};

/** \internal \returns the bitwise not of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pnot(const Packet& a) {
  return pnot_impl<Packet>::run(a);
}

/** \internal \returns the bitwise and of \a a and not \a b */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pandnot(const Packet& a, const Packet& b) {
  return pand(a, pnot(b));
}

/** \internal \returns a < b as a bit mask */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pcmp_lt(const Packet& a, const Packet& b) {
  return a < b ? ptrue(a) : pzero(a);
}

/** \internal \returns a == b as a bit mask */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pcmp_eq(const Packet& a, const Packet& b) {
  return a == b ? ptrue(a) : pzero(a);
}

/** \internal \returns a <= b as a bit mask */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pcmp_le(const Packet& a, const Packet& b) {
  return por(pcmp_eq(a, b), pcmp_lt(a, b));
}

/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pcmp_lt_or_nan(const Packet& a, const Packet& b) {
  return a >= b ? pzero(a) : ptrue(a);
}

// In the general case, use bitwise select.
template <typename Packet, bool is_scalar = is_scalar<Packet>::value>
struct pselect_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
    return por(pand(a, mask), pandnot(b, mask));
  }
};

// For scalars, use ternary select.
template <typename Packet>
struct pselect_impl<Packet, true> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
    return numext::select(mask, a, b);
  }
};

/** \internal \returns \a or \b for each field in packet according to \mask */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pselect(const Packet& mask, const Packet& a, const Packet& b) {
  return pselect_impl<Packet>::run(mask, a, b);
}

template <>
EIGEN_DEVICE_FUNC inline bool pselect<bool>(const bool& cond, const bool& a, const bool& b) {
  return cond ? a : b;
}

/** \internal Whether plain pmin/pmax already propagate NaN for \a Packet. */
template <typename Packet>
struct pminmax_propagates_nan : bool_constant<false> {};

/** \internal \returns the min or max of \a a and \a b (coeff-wise)
    If either \a a or \a b are NaN, the result is implementation defined, except that a
    PropagateNaN request on a packet whose plain pmin/pmax already propagates NaN
    (\a NativePropagatesNaN) returns NaN. */
template <int NaNPropagation, bool IsInteger, bool NativePropagatesNaN = false>
struct pminmax_impl {
  template <typename Packet, typename Op>
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
    return op(a, b);
  }
};

/** \internal \returns the min or max of \a a and \a b (coeff-wise)
    If either \a a or \a b are NaN, NaN is returned. */
template <>
struct pminmax_impl<PropagateNaN, false, false> {
  template <typename Packet, typename Op>
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
    // pselect is an ordinary call, so op(a, b) is evaluated even where an operand is NaN;
    // only its result is discarded there. op therefore need not propagate NaN, but must
    // still be well-defined on NaN input. Operands stay in the caller's order so that op
    // selects the same one on a signed-zero tie as plain pmin/pmax does for this Packet.
    Packet not_nan_mask_a = pcmp_eq(a, a);
    Packet not_nan_mask_b = pcmp_eq(b, b);
    return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), b), a);
  }
};

/** \internal \returns the min or max of \a a and \a b (coeff-wise)
    If both \a a and \a b are NaN, NaN is returned.
    Equivalent to std::fmin(a, b).  */
template <bool NativePropagatesNaN>
struct pminmax_impl<PropagateNumbers, false, NativePropagatesNaN> {
  template <typename Packet, typename Op>
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
    Packet not_nan_mask_a = pcmp_eq(a, a);
    Packet not_nan_mask_b = pcmp_eq(b, b);
    return pselect(not_nan_mask_a, pselect(not_nan_mask_b, op(a, b), a), b);
  }
};

#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) [](const Type& aa, const Type& bb) { return Func(aa, bb); }

/** \internal \returns the min of \a a and \a b  (coeff-wise).
    If \a a or \a b is NaN, the return value is implementation defined. */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmin(const Packet& a, const Packet& b) {
  return numext::mini(a, b);
}

/** \internal \returns the min of \a a and \a b  (coeff-wise).
    NaNPropagation determines the NaN propagation semantics. */
template <int NaNPropagation, typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmin(const Packet& a, const Packet& b) {
  constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
  constexpr bool NativePropagatesNaN = pminmax_propagates_nan<Packet>::value;
  return pminmax_impl<NaNPropagation, IsInteger, NativePropagatesNaN>::run(
      a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
}

/** \internal \returns the max of \a a and \a b  (coeff-wise)
    If \a a or \a b is NaN, the return value is implementation defined. */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmax(const Packet& a, const Packet& b) {
  return numext::maxi(a, b);
}

/** \internal \returns the max of \a a and \a b  (coeff-wise).
    NaNPropagation determines the NaN propagation semantics. */
template <int NaNPropagation, typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmax(const Packet& a, const Packet& b) {
  constexpr bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger;
  constexpr bool NativePropagatesNaN = pminmax_propagates_nan<Packet>::value;
  return pminmax_impl<NaNPropagation, IsInteger, NativePropagatesNaN>::run(
      a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmax<Packet>)));
}

/** \internal \returns the absolute value of \a a */
template <typename Packet, std::enable_if_t<!(NumTraits<typename unpacket_traits<Packet>::type>::IsInteger &&
                                              !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned),
                                            int> = 0>
EIGEN_DEVICE_FUNC inline Packet pabs(const Packet& a) {
  return numext::abs(a);
}

template <typename Packet, std::enable_if_t<NumTraits<typename unpacket_traits<Packet>::type>::IsInteger &&
                                                !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned,
                                            int> = 0>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pabs(const Packet& a) {
  return a;
}

/** \internal \returns the addsub value of \a a,b */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet paddsub(const Packet& a, const Packet& b) {
  return pselect(peven_mask(a), padd(a, b), psub(a, b));
}

/** \internal \returns the phase angle of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet parg(const Packet& a) {
  using numext::arg;
  return arg(a);
}

/** \internal \returns \a a arithmetically shifted by N bits to the right */
template <int N, typename T>
EIGEN_DEVICE_FUNC inline T parithmetic_shift_right(const T& a) {
  return numext::arithmetic_shift_right(a, N);
}

/** \internal \returns \a a logically shifted by N bits to the right */
template <int N, typename T>
EIGEN_DEVICE_FUNC inline T plogical_shift_right(const T& a) {
  return numext::logical_shift_right(a, N);
}

/** \internal \returns \a a shifted by N bits to the left */
template <int N, typename T>
EIGEN_DEVICE_FUNC inline T plogical_shift_left(const T& a) {
  return numext::logical_shift_left(a, N);
}

/** \internal \returns the significant and exponent of the underlying floating point numbers
 * See https://en.cppreference.com/w/cpp/numeric/math/frexp
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pfrexp(const Packet& a, Packet& exponent) {
  int exp;
  EIGEN_USING_STD(frexp);
  Packet result = static_cast<Packet>(frexp(a, &exp));
  exponent = static_cast<Packet>(exp);
  return result;
}

/** \internal \returns a * 2^((int)exponent)
 * See https://en.cppreference.com/w/cpp/numeric/math/ldexp
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pldexp(const Packet& a, const Packet& exponent) {
  EIGEN_USING_STD(ldexp)
  return static_cast<Packet>(ldexp(a, static_cast<int>(exponent)));
}

/** \internal \returns the absolute difference of \a a and \a b  (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline std::enable_if_t<NumTraits<typename unpacket_traits<Packet>::type>::IsInteger, Packet>
pabsdiff(const Packet& a, const Packet& b) {
  return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b));
}
template <typename Packet>
EIGEN_DEVICE_FUNC inline std::enable_if_t<!NumTraits<typename unpacket_traits<Packet>::type>::IsInteger, Packet>
pabsdiff(const Packet& a, const Packet& b) {
  return pabs(psub(a, b));
}

/** \internal \returns a packet version of \a *from, from must be properly aligned */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pload(const typename unpacket_traits<Packet>::type* from) {
  return *from;
}

/** \internal \returns n elements of a packet version of \a *from, from must be properly aligned
 * offset indicates the starting element in which to load and
 * offset + n <= unpacket_traits::size
 * All elements before offset and after the last element loaded will initialized with zero */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pload_partial(const typename unpacket_traits<Packet>::type* from, const Index n,
                                              const Index offset = 0) {
  const Index packet_size = unpacket_traits<Packet>::size;
  eigen_assert(n + offset <= packet_size && "number of elements plus offset will read past end of packet");
  using Scalar = typename unpacket_traits<Packet>::type;
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
  for (Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
    elements[i] = from[i - offset];
  }
  return pload<Packet>(elements);
}

/** \internal \returns a packet version of \a *from, (un-aligned load) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ploadu(const typename unpacket_traits<Packet>::type* from) {
  return *from;
}

/** \internal \returns n elements of a packet version of \a *from, (un-aligned load)
 * All elements after the last element loaded will initialized with zero */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ploadu_partial(const typename unpacket_traits<Packet>::type* from, const Index n,
                                               const Index offset = 0) {
  const Index packet_size = unpacket_traits<Packet>::size;
  eigen_assert(n + offset <= packet_size && "number of elements plus offset will read past end of packet");
  using Scalar = typename unpacket_traits<Packet>::type;
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
  for (Index i = offset; i < numext::mini(n + offset, packet_size); i++) {
    elements[i] = from[i - offset];
  }
  return pload<Packet>(elements);
}

/** \internal \returns a packet version of \a *from, (un-aligned masked load)
 * There is no generic implementation. We only have implementations for specialized
 * cases. Generic case should not be called.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline std::enable_if_t<unpacket_traits<Packet>::masked_load_available, Packet> ploadu(
    const typename unpacket_traits<Packet>::type* from, typename unpacket_traits<Packet>::mask_t umask);

/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pset1(const typename unpacket_traits<Packet>::type& a) {
  return a;
}

/** \internal \returns a packet with constant coefficients set from bits */
template <typename Packet, typename BitsType>
EIGEN_DEVICE_FUNC inline Packet pset1frombits(BitsType a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return pset1<Packet>(numext::bit_cast<Scalar>(a));
}

template <typename Packet>
struct packet_bit_pattern_traits {
  using Scalar = typename unpacket_traits<Packet>::type;
  using Bits = typename numext::get_integer_by_size<sizeof(Scalar)>::unsigned_type;
  enum { HasIntegerBits = !std::is_void<Bits>::value };
};

// Widening an opaque IEEE binary32 bit pattern produces the target's native extended-scalar representation without
// exposing a floating-point special-value literal to fast-math optimizers.
template <typename Scalar>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pscalar_from_float_bits(numext::uint32_t bits) {
#if EIGEN_COMP_GNUC_STRICT && defined(__FINITE_MATH_ONLY__) && __FINITE_MATH_ONLY__ && \
    !defined(EIGEN_GPU_COMPILE_PHASE) && !defined(__SYCL_DEVICE_ONLY__)
  // GCC also needs the integer pattern hidden before bit_cast and widening. Use a memory operand so this works on
  // targets where EIGEN_OPTIMIZATION_BARRIER is intentionally unavailable.
  __asm__("" : "+m"(bits));
#endif
  EIGEN_FAST_MATH_CONSTANT_BARRIER(bits);
  return static_cast<Scalar>(numext::bit_cast<float>(bits));
}

template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
          bool IsScalar = is_scalar<Packet>::value>
struct psignmask_impl;

template <typename Packet, bool IsScalar>
struct psignmask_impl<Packet, true, IsScalar> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
    using Scalar = typename packet_bit_pattern_traits<Packet>::Scalar;
    using Bits = typename packet_bit_pattern_traits<Packet>::Bits;
    constexpr Bits kSignBit = static_cast<Bits>(Bits(1) << (CHAR_BIT * sizeof(Scalar) - 1));
    return pset1frombits<Packet, Bits>(kSignBit);
  }
};

template <typename Scalar>
struct psignmask_impl<Scalar, false, true> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() { return pscalar_from_float_bits<Scalar>(0x80000000u); }
};

/** \internal \returns a packet with all coefficients set to -0.0, i.e. with only the sign bit set.
 *
 * When the lane type has a same-size integer type, the mask is deliberately constructed from the integer sign-bit
 * pattern via pset1frombits instead of the floating-point literal -Scalar(0): under fast-math flags (-ffast-math
 * implies -fno-signed-zeros) compilers may treat -0.0 and +0.0 as interchangeable, and e.g. GCC's value numbering
 * substitutes a splat of -0.0 with a nearby splat of +0.0, silently zeroing the mask and corrupting sign manipulation
 * of non-zero values. Architectures that specialize pset1frombits keep the constant in the integer domain, where no
 * floating-point simplification applies. Extended scalar types without a same-size integer use their native -0.0
 * representation instead. See https://gitlab.com/libeigen/eigen/-/merge_requests/2698.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet psignmask() {
  return psignmask_impl<Packet>::run();
}

/** \internal \returns a packet with all coefficients set to +infinity.
 *
 * When the lane type has a same-size integer type, the constant is constructed from its integer bit pattern via
 * pset1frombits rather than from a floating-point infinity literal: under fast-math flags (-ffast-math implies
 * -ffinite-math-only) an infinity or NaN literal is undefined behavior, and clang turns it into a poison value that
 * deletes the surrounding special-case handling — or the entire containing expression — at compile time. The bit
 * pattern is inert: comparisons against it simply fold to false when the compiler assumes finite math, and selects
 * using it as an arm keep or drop the special case as appropriate. Extended scalar types without a same-size integer
 * widen an opaque IEEE binary32 bit pattern instead.
 */
template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
          bool IsScalar = is_scalar<Packet>::value>
struct pinf_impl;

template <typename Packet, bool IsScalar>
struct pinf_impl<Packet, true, IsScalar> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
    using Scalar = typename packet_bit_pattern_traits<Packet>::Scalar;
    using Bits = typename packet_bit_pattern_traits<Packet>::Bits;
    constexpr int kMantissaBits = std::numeric_limits<Scalar>::digits - 1;
    constexpr int kExponentBits = static_cast<int>(CHAR_BIT * sizeof(Scalar)) - 1 - kMantissaBits;
    constexpr Bits kInf = static_cast<Bits>(((Bits(1) << kExponentBits) - 1) << kMantissaBits);
    return pset1frombits<Packet, Bits>(kInf);
  }
};

template <typename Scalar>
struct pinf_impl<Scalar, false, true> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() { return pscalar_from_float_bits<Scalar>(0x7f800000u); }
};

template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pinf() {
  return pinf_impl<Packet>::run();
}

/** \internal \returns a packet with all coefficients set to a quiet NaN, using the same construction as pinf(). */
template <typename Packet, bool HasIntegerBits = packet_bit_pattern_traits<Packet>::HasIntegerBits,
          bool IsScalar = is_scalar<Packet>::value>
struct pnan_impl;

template <typename Packet, bool IsScalar>
struct pnan_impl<Packet, true, IsScalar> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet run() {
    using Scalar = typename packet_bit_pattern_traits<Packet>::Scalar;
    using Bits = typename packet_bit_pattern_traits<Packet>::Bits;
    constexpr int kMantissaBits = std::numeric_limits<Scalar>::digits - 1;
    constexpr int kExponentBits = static_cast<int>(CHAR_BIT * sizeof(Scalar)) - 1 - kMantissaBits;
    constexpr Bits kInf = static_cast<Bits>(((Bits(1) << kExponentBits) - 1) << kMantissaBits);
    constexpr Bits kNaN = static_cast<Bits>(kInf | (Bits(1) << (kMantissaBits - 1)));
    return pset1frombits<Packet, Bits>(kNaN);
  }
};

template <typename Scalar>
struct pnan_impl<Scalar, false, true> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar run() { return pscalar_from_float_bits<Scalar>(0x7fc00000u); }
};

template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnan() {
  return pnan_impl<Packet>::run();
}

template <typename Scalar, std::enable_if_t<std::is_trivially_copyable<Scalar>::value, int> = 0>
EIGEN_DEVICE_FUNC inline Scalar pload1_scalar(const Scalar* a) {
  Scalar scalar;
  EIGEN_USING_STD(memcpy)
  memcpy(&scalar, a, sizeof(Scalar));
  return scalar;
}

template <typename Scalar, std::enable_if_t<!std::is_trivially_copyable<Scalar>::value, int> = 0>
EIGEN_DEVICE_FUNC inline Scalar pload1_scalar(const Scalar* a) {
  return Scalar(*a);
}

/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pload1(const typename unpacket_traits<Packet>::type* a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return pset1<Packet>(pload1_scalar<Scalar>(a));
}

/** \internal \returns a packet with elements of \a *from duplicated.
 * For instance, for a packet of 8 elements, 4 scalars will be read from \a *from and
 * duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
 * Currently, this function is only used for scalar * complex products.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ploaddup(const typename unpacket_traits<Packet>::type* from) {
  return pload1<Packet>(from);
}

/** \internal \returns a packet with elements of \a *from quadrupled.
 * For instance, for a packet of 8 elements, 2 scalars will be read from \a *from and
 * replicated to form: {from[0],from[0],from[0],from[0],from[1],from[1],from[1],from[1]}
 * Currently, this function is only used in matrix products.
 * For packet-size smaller or equal to 4, this function is equivalent to pload1
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ploadquad(const typename unpacket_traits<Packet>::type* from) {
  return pload1<Packet>(from);
}

/** \internal equivalent to
 * \code
 * a0 = pload1(a+0);
 * a1 = pload1(a+1);
 * a2 = pload1(a+2);
 * a3 = pload1(a+3);
 * \endcode
 * \sa pset1, pload1, ploaddup, pbroadcast2
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline void pbroadcast4(const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1,
                                          Packet& a2, Packet& a3) {
  a0 = pload1<Packet>(a + 0);
  a1 = pload1<Packet>(a + 1);
  a2 = pload1<Packet>(a + 2);
  a3 = pload1<Packet>(a + 3);
}

/** \internal equivalent to
 * \code
 * a0 = pload1(a+0);
 * a1 = pload1(a+1);
 * \endcode
 * \sa pset1, pload1, ploaddup, pbroadcast4
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline void pbroadcast2(const typename unpacket_traits<Packet>::type* a, Packet& a0, Packet& a1) {
  a0 = pload1<Packet>(a + 0);
  a1 = pload1<Packet>(a + 1);
}

/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet plset(const typename unpacket_traits<Packet>::type& a) {
  return a;
}

/** \internal \returns a packet with constant coefficients \a a, e.g.: (x, 0, x, 0),
     where x is the value of all 1-bits. */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet peven_mask(const Packet& /*a*/) {
  using Scalar = typename unpacket_traits<Packet>::type;
  if (is_scalar<Packet>::value) {
    // The scalar "mask" is numeric: true is represented by the value one.
    return pset1<Packet>(Scalar(1));
  }
  const size_t n = unpacket_traits<Packet>::size;
  Packet b;
  char* bytes = reinterpret_cast<char*>(&b);
  for (size_t i = 0; i < n; ++i) {
    memset(bytes + i * sizeof(Scalar), ((i & 1) == 0 ? 0xff : 0), sizeof(Scalar));
  }
  EIGEN_FAST_MATH_CONSTANT_BARRIER(b);
  return b;
}

/** \internal copy the packet \a from to \a *to, \a to must be properly aligned */
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from) {
  (*to) = from;
}

/** \internal copy n elements of the packet \a from to \a *to, \a to must be properly aligned
 * offset indicates the starting element in which to store and
 * offset + n <= unpacket_traits::size */
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstore_partial(Scalar* to, const Packet& from, const Index n, const Index offset = 0) {
  const Index packet_size = unpacket_traits<Packet>::size;
  eigen_assert(n + offset <= packet_size && "number of elements plus offset will write past end of packet");
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
  pstore<Scalar>(elements, from);
  for (Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
    to[i] = elements[i + offset];
  }
}

/** \internal copy the packet \a from to \a *to, (un-aligned store) */
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from) {
  (*to) = from;
}

/** \internal copy n elements of the packet \a from to \a *to, (un-aligned store) */
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstoreu_partial(Scalar* to, const Packet& from, const Index n, const Index offset = 0) {
  const Index packet_size = unpacket_traits<Packet>::size;
  eigen_assert(n + offset <= packet_size && "number of elements plus offset will write past end of packet");
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
  pstore<Scalar>(elements, from);
  for (Index i = 0; i < numext::mini(n, packet_size - offset); i++) {
    to[i] = elements[i + offset];
  }
}

/** \internal copy the packet \a from to \a *to, (un-aligned store with a mask)
 * There is no generic implementation. We only have implementations for specialized
 * cases. Generic case should not be called.
 */
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline std::enable_if_t<unpacket_traits<Packet>::masked_store_available, void> pstoreu(
    Scalar* to, const Packet& from, typename unpacket_traits<Packet>::mask_t umask);

template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/) {
  return ploadu<Packet>(from);
}

template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline Packet pgather_partial(const Scalar* from, Index stride, const Index n) {
  const Index packet_size = unpacket_traits<Packet>::size;
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size] = {Scalar(0)};
  for (Index i = 0; i < numext::mini(n, packet_size); i++) {
    elements[i] = from[i * stride];
  }
  return pload<Packet>(elements);
}

template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pscatter(Scalar* to, const Packet& from, Index /*stride*/) {
  pstore(to, from);
}

template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pscatter_partial(Scalar* to, const Packet& from, Index stride, const Index n) {
  const Index packet_size = unpacket_traits<Packet>::size;
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[packet_size];
  pstore<Scalar>(elements, from);
  for (Index i = 0; i < numext::mini(n, packet_size); i++) {
    to[i * stride] = elements[i];
  }
}

/** \internal tries to do cache prefetching of \a addr */
template <typename Scalar>
EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr) {
#if defined(EIGEN_HIP_DEVICE_COMPILE)
  // do nothing
#elif defined(EIGEN_CUDA_ARCH)
#if defined(__LP64__) || EIGEN_OS_WIN64
  // 64-bit pointer operand constraint for inlined asm
  asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
#else
  // 32-bit pointer operand constraint for inlined asm
  asm(" prefetch.L1 [ %1 ];" : "=r"(addr) : "r"(addr));
#endif
#elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
  __builtin_prefetch(addr);
#endif
}

/** \internal \returns the reversed elements of \a a*/
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet preverse(const Packet& a) {
  return a;
}

/** \internal \returns \a a with real and imaginary parts flipped (for complex types only) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a) {
  return Packet(numext::imag(a), numext::real(a));
}

/** \internal \returns \a a with real part duplicated (for complex types only) */
// TODO(rmlarsen): Define and use in all complex backends.
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pdupreal(const Packet& a) {
  return Packet(numext::real(a), numext::real(a));
}

/** \internal \returns \a a with imaginary part duplicated (for complex types only) */
// TODO(rmlarsen): Define and use in all complex backends.
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pdupimag(const Packet& a) {
  return Packet(numext::imag(a), numext::imag(a));
}

/**************************
 * Special math functions
 ***************************/

// Declared ahead of pisnan_impl so the complex case can use a backend's pisnan for the real packet.
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pisnan(const Packet& a);

// Implemented without ptrue: an all-ones float packet is a NaN bit pattern, which under
// fast-math flags clang turns into a poison constant that deletes any expression it flows
// into.
template <typename Packet, bool IsComplex = NumTraits<typename unpacket_traits<Packet>::type>::IsComplex,
          bool IsScalar = is_scalar<Packet>::value,
          bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct pisnan_impl {
  // Equivalent to !(a == a).
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pcmp_lt_or_nan(a, a); }
};

// Integer scalars have no NaN; the answer is the all-false mask. The generic path is unusable
// here: pcmp_lt_or_nan has no meaningful integer semantics (and its generic form does not even
// compile for integer SIMD packets).
template <typename Packet, bool IsScalar>
struct pisnan_impl<Packet, false, IsScalar, true> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pzero(a); }
};

template <typename Packet, bool IsInteger>
struct pisnan_impl<Packet, true, false, IsInteger> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
    using RealPacket = typename unpacket_traits<Packet>::as_real;
    // A NaN in either the real or the imaginary lane marks the whole complex element.
    Packet nan_lanes = Packet(pisnan<RealPacket>(a.v));
    return por(nan_lanes, pcplxflip(nan_lanes));
  }
};

// Scalar complex arguments have no wrapped real packet; combine the per-component results in the
// value domain, where the scalar mask convention is Scalar(1)/Scalar(0).
template <typename Scalar, bool IsInteger>
struct pisnan_impl<Scalar, true, true, IsInteger> {
  static EIGEN_DEVICE_FUNC inline Scalar run(const Scalar& a) {
    using RealScalar = typename NumTraits<Scalar>::Real;
    const RealScalar nan_mask =
        por(pisnan_impl<RealScalar>::run(numext::real(a)), pisnan_impl<RealScalar>::run(numext::imag(a)));
    return Scalar(nan_mask);
  }
};

/** \internal \returns isnan(a) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pisnan(const Packet& a) {
  return pisnan_impl<Packet>::run(a);
}

template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct pisinf_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pcmp_eq(pabs(a), pinf<Packet>()); }
};

// Integer scalars have no infinity; the answer is the all-false mask. The generic path is wrong
// for them: pinf() synthesizes its bit pattern from numeric_limits digits, which for int32 yields
// 2^30, so |a| == 2^30 would read as "inf".
template <typename Packet>
struct pisinf_impl<Packet, true> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pzero(a); }
};

/** \internal \returns isinf(a) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pisinf(const Packet& a) {
  return pisinf_impl<Packet>::run(a);
}

template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct pisfinite_impl {
  // |a| < inf is a single comparison that is false for both NaN and infinities.
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return pcmp_lt(pabs(a), pinf<Packet>()); }
};

// Integer scalars are always finite; the answer is the all-true mask (safe for integer packets,
// where all-ones is not a NaN bit pattern).
template <typename Packet>
struct pisfinite_impl<Packet, true> {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return ptrue(a); }
};

/** \internal \returns isfinite(a) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pisfinite(const Packet& a) {
  return pisfinite_impl<Packet>::run(a);
}

/** \internal \returns the sine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psin(const Packet& a) {
  EIGEN_USING_STD(sin);
  return sin(a);
}

/** \internal \returns the cosine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcos(const Packet& a) {
  EIGEN_USING_STD(cos);
  return cos(a);
}

/** \internal \returns the tan of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptan(const Packet& a) {
  EIGEN_USING_STD(tan);
  return tan(a);
}

/** \internal \returns the arc sine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pasin(const Packet& a) {
  EIGEN_USING_STD(asin);
  return asin(a);
}

/** \internal \returns the arc cosine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacos(const Packet& a) {
  EIGEN_USING_STD(acos);
  return acos(a);
}

/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh(const Packet& a) {
  EIGEN_USING_STD(sinh);
  return sinh(a);
}

/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh(const Packet& a) {
  EIGEN_USING_STD(cosh);
  return cosh(a);
}

/** \internal \returns the arc tangent of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patan(const Packet& a) {
  EIGEN_USING_STD(atan);
  return atan(a);
}

/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptanh(const Packet& a) {
  EIGEN_USING_STD(tanh);
  return tanh(a);
}

/** \internal \returns the arc tangent of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patanh(const Packet& a) {
  EIGEN_USING_STD(atanh);
  return atanh(a);
}

/** \internal \returns the inverse hyperbolic sine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pasinh(const Packet& a) {
  EIGEN_USING_STD(asinh);
  return asinh(a);
}

/** \internal \returns the inverse hyperbolic cosine of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacosh(const Packet& a) {
  EIGEN_USING_STD(acosh);
  return acosh(a);
}

/** \internal \returns the exp of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(const Packet& a) {
  return numext::exp(a);
}

/** \internal \returns the exp2 of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp2(const Packet& a) {
  return numext::exp2(a);
}

/** \internal \returns the expm1 of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexpm1(const Packet& a) {
  return numext::expm1(a);
}

/** \internal \returns the log of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog(const Packet& a) {
  return numext::log(a);
}

/** \internal \returns the log1p of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog1p(const Packet& a) {
  return numext::log1p(a);
}

/** \internal \returns the log10 of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog10(const Packet& a) {
  return numext::log10(a);
}

template <typename Packet, bool IsComplexPacket = NumTraits<typename unpacket_traits<Packet>::type>::IsComplex &&
                                                  !is_scalar<Packet>::value>
struct plog2_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
    using Scalar = typename internal::unpacket_traits<Packet>::type;
    using RealScalar = typename NumTraits<Scalar>::Real;
    return pmul(pset1<Packet>(Scalar(RealScalar(EIGEN_LOG2E))), plog(a));
  }
};

// Defined with plog_complex in GenericPacketMathComplex.h; declared here so that plog2 on a complex packet cannot
// silently take the primary template before that header.
template <typename Packet>
struct plog2_impl<Packet, true>;

/** \internal \returns the log2 of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(const Packet& a) {
  return plog2_impl<Packet>::run(a);
}

/** \internal \returns the square-root of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt(const Packet& a) {
  return numext::sqrt(a);
}

/** \internal \returns the cube-root of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcbrt(const Packet& a) {
  return numext::cbrt(a);
}

template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
          bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct nearest_integer_packetop_impl {
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_floor(const Packet& x) { return numext::floor(x); }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_ceil(const Packet& x) { return numext::ceil(x); }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_rint(const Packet& x) { return numext::rint(x); }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_round(const Packet& x) { return numext::round(x); }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_trunc(const Packet& x) { return numext::trunc(x); }
};

/** \internal \returns the rounded value of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pround(const Packet& a) {
  return nearest_integer_packetop_impl<Packet>::run_round(a);
}

/** \internal \returns the floor of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pfloor(const Packet& a) {
  return nearest_integer_packetop_impl<Packet>::run_floor(a);
}

/** \internal \returns the rounded value of \a a (coeff-wise) with current
 * rounding mode */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet print(const Packet& a) {
  return nearest_integer_packetop_impl<Packet>::run_rint(a);
}

/** \internal \returns the ceil of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pceil(const Packet& a) {
  return nearest_integer_packetop_impl<Packet>::run_ceil(a);
}

/** \internal \returns the truncation of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ptrunc(const Packet& a) {
  return nearest_integer_packetop_impl<Packet>::run_trunc(a);
}

template <typename Packet, typename EnableIf = void>
struct psign_impl {
  static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) { return numext::sign(a); }
};

/** \internal \returns the sign of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet psign(const Packet& a) {
  return psign_impl<Packet>::run(a);
}

template <>
EIGEN_DEVICE_FUNC inline bool psign(const bool& a) {
  return a;
}

/** \internal \returns the first element of a packet */
template <typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a) {
  return a;
}

/** \internal \returns the sum of the elements of upper and lower half of \a a if \a a is larger than 4.
 * For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
 * For packet-size smaller or equal to 4, this boils down to a noop.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline std::conditional_t<(unpacket_traits<Packet>::size % 8) == 0,
                                            typename unpacket_traits<Packet>::half, Packet>
predux_half(const Packet& a) {
  return a;
}

// Slow generic implementation of Packet reduction.
template <typename Packet, typename Op>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_helper(const Packet& a, Op op) {
  using Scalar = typename unpacket_traits<Packet>::type;
  const size_t n = unpacket_traits<Packet>::size;
  EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar elements[n];
  pstoreu<Scalar>(elements, a);
  for (size_t k = n / 2; k > 0; k /= 2) {
    for (size_t i = 0; i < k; ++i) {
      elements[i] = op(elements[i], elements[i + k]);
    }
  }
  return elements[0];
}

template <typename Packet, std::enable_if_t<unpacket_traits<Packet>::size == 1, int> = 0>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename unpacket_traits<Packet>::type predux_one_element(const Packet& a) {
  return pfirst(a);
}

/** \internal \returns the sum of the elements of \a a*/
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename unpacket_traits<Packet>::type predux(const Packet& a) {
  return predux_one_element(a);
}

/** \internal \returns the product of the elements of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename unpacket_traits<Packet>::type predux_mul(const Packet& a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmul<Scalar>)));
}

/** \internal \returns the min of the elements of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<Scalar>)));
}

/** \internal \returns the max of the elements of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<Scalar>)));
}

template <int NaNPropagation, typename Packet>
struct predux_min_max_helper_impl {
  using Scalar = typename unpacket_traits<Packet>::type;
  static constexpr bool UsePredux_ = NaNPropagation == PropagateFast || NumTraits<Scalar>::IsInteger;
  template <bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux, bool> = true>
  static EIGEN_DEVICE_FUNC inline Scalar run_min(const Packet& a) {
    return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<NaNPropagation, Scalar>)));
  }
  template <bool UsePredux = UsePredux_, std::enable_if_t<!UsePredux, bool> = true>
  static EIGEN_DEVICE_FUNC inline Scalar run_max(const Packet& a) {
    return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<NaNPropagation, Scalar>)));
  }
  template <bool UsePredux = UsePredux_, std::enable_if_t<UsePredux, bool> = true>
  static EIGEN_DEVICE_FUNC inline Scalar run_min(const Packet& a) {
    return predux_min(a);
  }
  template <bool UsePredux = UsePredux_, std::enable_if_t<UsePredux, bool> = true>
  static EIGEN_DEVICE_FUNC inline Scalar run_max(const Packet& a) {
    return predux_max(a);
  }
};

template <int NaNPropagation, typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a) {
  return predux_min_max_helper_impl<NaNPropagation, Packet>::run_min(a);
}

template <int NaNPropagation, typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a) {
  return predux_min_max_helper_impl<NaNPropagation, Packet>::run_max(a);
}

#undef EIGEN_BINARY_OP_NAN_PROPAGATION

template <typename Packet, bool IsBoolean = std::is_same<typename unpacket_traits<Packet>::type, bool>::value>
struct predux_count_impl {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index run(const Packet& a) {
    using Scalar = typename unpacket_traits<Packet>::type;
    const Packet true_values = pandnot(pset1<Packet>(Scalar(1)), pcmp_eq(a, pzero(a)));
    return static_cast<Index>(numext::real(predux(true_values)));
  }
};

template <typename Packet>
struct predux_count_impl<Packet, true> {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index run(const Packet& a) {
    using Scalar = typename unpacket_traits<Packet>::type;
    constexpr int PacketSize = unpacket_traits<Packet>::size;
    EIGEN_ALIGN_TO_BOUNDARY(unpacket_traits<Packet>::alignment) Scalar values[PacketSize];
    pstoreu<Scalar>(values, a);
    Index result = 0;
    for (int i = 0; i < PacketSize; ++i) result += values[i] ? 1 : 0;
    return result;
  }
};

/** \internal \returns the number of nonzero coefficients in \a a. */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index predux_count(const Packet& a) {
  return predux_count_impl<Packet>::run(a);
}

/** \internal \returns true if any coeffs of \a a means "true"
 * It is supposed to be called on values returned by pcmp_*.
 */
template <typename Packet>
EIGEN_DEVICE_FUNC inline bool predux_any(const Packet& a) {
  // Dirty but generic implementation where "true" is assumed to be non 0 and all the sames.
  // It is expected that "true" is either:
  //  - Scalar(1)
  //  - bits full of ones (NaN for floats),
  //  - or first bit equals to 1 (1 for ints, smallest denormal for floats).
  // This arithmetic fallback boils down to a no-op for scalars. Vector backends whose masks use floating-point bit
  // patterns must specialize this with an integer-bit reduction because fast-math or FTZ can discard those values.
  using Scalar = typename unpacket_traits<Packet>::type;
  return numext::not_equal_strict(predux(a), Scalar(0));
}

template <typename Packet, bool IsBoolean = std::is_same<typename unpacket_traits<Packet>::type, bool>::value>
struct predux_all_impl {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE bool run(const Packet& a) { return !predux_any(pcmp_eq(a, pzero(a))); }
};

template <typename Packet>
struct predux_all_impl<Packet, true> {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE bool run(const Packet& a) { return predux_mul(a); }
};

/** \internal \returns true if every coefficient in \a a is nonzero. */
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool predux_all(const Packet& a) {
  return predux_all_impl<Packet>::run(a);
}

/***************************************************************************
 * The following functions might not have to be overwritten for vectorized types
 ***************************************************************************/

template <typename Packet, typename EnableIf = void>
struct pmadd_impl {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmadd(const Packet& a, const Packet& b, const Packet& c) {
    return padd(pmul(a, b), c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pmsub(const Packet& a, const Packet& b, const Packet& c) {
    return psub(pmul(a, b), c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmadd(const Packet& a, const Packet& b, const Packet& c) {
    return psub(c, pmul(a, b));
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pnmsub(const Packet& a, const Packet& b, const Packet& c) {
    return pnegate(padd(pmul(a, b), c));
  }
};

#if defined(EIGEN_VECTORIZE_FMA)
// Scalar path for pmadd with FMA to ensure consistency with vectorized path.
template <typename Scalar>
struct pmadd_impl<Scalar, std::enable_if_t<std::is_same<Scalar, float>::value || std::is_same<Scalar, double>::value>> {
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmadd(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::fma(a, b, c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmsub(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::fma(a, b, Scalar(-c));
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmadd(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::fma(Scalar(-a), b, c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmsub(const Scalar& a, const Scalar& b, const Scalar& c) {
    return -Scalar(numext::fma(a, b, c));
  }
};

template <typename Scalar>
struct pmadd_impl<Scalar,
                  std::enable_if_t<is_scalar<Scalar>::value && NumTraits<Scalar>::IsSigned &&
                                   !std::is_same<Scalar, float>::value && !std::is_same<Scalar, double>::value>> {
#else
template <typename Scalar>
struct pmadd_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value && NumTraits<Scalar>::IsSigned>> {
#endif
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmadd(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::madd<Scalar>(a, b, c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pmsub(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::madd<Scalar>(a, b, Scalar(-c));
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmadd(const Scalar& a, const Scalar& b, const Scalar& c) {
    return numext::madd<Scalar>(Scalar(-a), b, c);
  }
  static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar pnmsub(const Scalar& a, const Scalar& b, const Scalar& c) {
    return -Scalar(numext::madd<Scalar>(a, b, c));
  }
};

// Multiply-add instructions.
/** \internal \returns a * b + c (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmadd(const Packet& a, const Packet& b, const Packet& c) {
  return pmadd_impl<Packet>::pmadd(a, b, c);
}

/** \internal \returns a * b - c (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmsub(const Packet& a, const Packet& b, const Packet& c) {
  return pmadd_impl<Packet>::pmsub(a, b, c);
}

/** \internal \returns -(a * b) + c (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pnmadd(const Packet& a, const Packet& b, const Packet& c) {
  return pmadd_impl<Packet>::pnmadd(a, b, c);
}

/** \internal \returns -(a * b + c) (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pnmsub(const Packet& a, const Packet& b, const Packet& c) {
  return pmadd_impl<Packet>::pnmsub(a, b, c);
}

/** \internal copy a packet with constant coefficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned
 */
// NOTE: this function must really be templated on the packet type (think about different packet types for the same
// scalar type)
template <typename Packet>
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a) {
  pstore(to, pset1<Packet>(a));
}

/** \internal \returns a packet version of \a *from.
 * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
template <typename Packet, int Alignment>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(const typename unpacket_traits<Packet>::type* from) {
  EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
    return pload<Packet>(from);
  } else {
    return ploadu<Packet>(from);
  }
}

/** \internal \returns n elements of a packet version of \a *from.
 * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
template <typename Packet, int Alignment>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_partial(const typename unpacket_traits<Packet>::type* from,
                                                            const Index n, const Index offset = 0) {
  EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
    return pload_partial<Packet>(from, n, offset);
  } else {
    return ploadu_partial<Packet>(from, n, offset);
  }
}

/** \internal copy the packet \a from to \a *to.
 * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
template <typename Scalar, typename Packet, int Alignment>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& from) {
  EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
    pstore(to, from);
  } else {
    pstoreu(to, from);
  }
}

/** \internal copy n elements of the packet \a from to \a *to.
 * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
template <typename Scalar, typename Packet, int Alignment>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret_partial(Scalar* to, const Packet& from, const Index n,
                                                           const Index offset = 0) {
  EIGEN_IF_CONSTEXPR (Alignment >= unpacket_traits<Packet>::alignment) {
    pstore_partial(to, from, n, offset);
  } else {
    pstoreu_partial(to, from, n, offset);
  }
}

/** \internal \returns a packet version of \a *from.
 * Unlike ploadt, ploadt_ro takes advantage of the read-only memory path on the
 * hardware if available to speedup the loading of data that won't be modified
 * by the current computation.
 */
template <typename Packet, int LoadMode>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from) {
  return ploadt<Packet, LoadMode>(from);
}

/***************************************************************************
 * Fast complex products (GCC generates a function call which is very slow)
 ***************************************************************************/

// Eigen+CUDA does not support complexes.
#if !defined(EIGEN_GPUCC)

template <>
inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b) {
  return std::complex<float>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
}

template <>
inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b) {
  return std::complex<double>(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag());
}

#endif

/***************************************************************************
 * PacketBlock, that is a collection of N packets where the number of words
 * in the packet is a multiple of N.
 ***************************************************************************/
template <typename Packet, int N = unpacket_traits<Packet>::size>
struct PacketBlock {
  Packet packet[N];
};

template <typename Packet, int size = 1>
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet, size>& /*kernel*/) {
  // Nothing to do in the scalar case, i.e. a 1x1 matrix.
}

/** \internal \returns 1 / a (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet preciprocal(const Packet& a) {
  using Scalar = typename unpacket_traits<Packet>::type;
  return pdiv(pset1<Packet>(Scalar(1)), a);
}

/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet prsqrt(const Packet& a) {
  return preciprocal<Packet>(psqrt(a));
}

template <typename Packet, bool IsScalar = is_scalar<Packet>::value,
          bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger,
          bool IsUnsigned = IsInteger && !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned>
struct psignbit_impl;
template <typename Packet, bool IsInteger, bool IsUnsigned>
struct psignbit_impl<Packet, true, IsInteger, IsUnsigned> {
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return numext::signbit(a); }
};
template <typename Packet>
struct psignbit_impl<Packet, false, false, false> {
  // generic implementation if not specialized in PacketMath.h
  // slower than arithmetic shift
  using Scalar = typename unpacket_traits<Packet>::type;
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static Packet run(const Packet& a) {
    const Packet cst_pos_one = pset1<Packet>(Scalar(1));
    const Packet cst_neg_one = pset1<Packet>(Scalar(-1));
    return pcmp_eq(por(pand(a, cst_neg_one), cst_pos_one), cst_neg_one);
  }
};
template <typename Packet>
struct psignbit_impl<Packet, false, true, false> {
  // generic implementation for signed integer packets
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return pcmp_lt(a, pzero(a)); }
};
template <typename Packet>
struct psignbit_impl<Packet, false, true, true> {
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return pzero(a); }
};
/** \internal \returns the sign bit of \a a as a bitmask*/
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE constexpr Packet psignbit(const Packet& a) {
  return psignbit_impl<Packet>::run(a);
}

/** \internal \returns the 2-argument arc tangent of \a y and \a x (coeff-wise) */
template <typename Packet, std::enable_if_t<is_scalar<Packet>::value, int> = 0>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(const Packet& y, const Packet& x) {
  return numext::atan2(y, x);
}

/** \internal \returns the 2-argument arc tangent of \a y and \a x (coeff-wise) */
template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value, int> = 0>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet patan2(const Packet& y, const Packet& x) {
  using Scalar = typename internal::unpacket_traits<Packet>::type;

  // See https://en.cppreference.com/w/cpp/numeric/math/atan2
  // for how corner cases are supposed to be handled according to the
  // IEEE floating-point standard (IEC 60559).
  const Packet kSignMask = psignmask<Packet>();
  const Packet kZero = pzero(x);
  const Packet kOne = pset1<Packet>(Scalar(1));
  const Packet kPi = pset1<Packet>(Scalar(EIGEN_PI));

  const Packet x_has_signbit = psignbit(x);
  const Packet y_signmask = pand(y, kSignMask);
  const Packet x_signmask = pand(x, kSignMask);
  const Packet result_signmask = pxor(y_signmask, x_signmask);
  const Packet shift = por(pand(x_has_signbit, kPi), y_signmask);

  const Packet x_and_y_are_same = pcmp_eq(pabs(x), pabs(y));
  const Packet x_and_y_are_zero = pcmp_eq(por(x, y), kZero);

  Packet arg = pdiv(y, x);
  arg = pselect(x_and_y_are_same, por(kOne, result_signmask), arg);
  arg = pselect(x_and_y_are_zero, result_signmask, arg);

  Packet result = patan(arg);
  result = padd(result, shift);
  return result;
}

/** \internal \returns the argument of \a a as a complex number */
template <typename Packet, std::enable_if_t<is_scalar<Packet>::value, int> = 0>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(const Packet& a) {
  return Packet(numext::arg(a));
}

/** \internal \returns the argument of \a a as a complex number */
template <typename Packet, std::enable_if_t<!is_scalar<Packet>::value, int> = 0>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pcarg(const Packet& a) {
  EIGEN_STATIC_ASSERT(NumTraits<typename unpacket_traits<Packet>::type>::IsComplex,
                      THIS METHOD IS FOR COMPLEX TYPES ONLY)
  using RealPacket = typename unpacket_traits<Packet>::as_real;
  // a                                              // r     i    r     i    ...
  RealPacket aflip = pcplxflip(a).v;                // i     r    i     r    ...
  RealPacket result = patan2(aflip, a.v);           // atan2 crap atan2 crap ...
  return (Packet)pand(result, peven_mask(result));  // atan2 0    atan2 0    ...
}

/** \internal \returns a packet populated with values in the range [begin, begin + count). Elements
 * outside this range are zero. \a *from does not need to be aligned, and can be null if \a count is zero.*/
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ploaduSegment(const typename unpacket_traits<Packet>::type* from, Index begin,
                                              Index count) {
  using Scalar = typename unpacket_traits<Packet>::type;
  constexpr Index PacketSize = unpacket_traits<Packet>::size;
  eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) && "invalid range");
  Scalar aux[PacketSize] = {};
  for (Index k = begin; k < begin + count; k++) {
    aux[k] = from[k];
  }
  return ploadu<Packet>(aux);
}

/** \internal \returns a packet populated with values in the range [begin, begin + count). Elements
 * outside this range are zero. \a *from must be aligned, and cannot be null.*/
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet ploadSegment(const typename unpacket_traits<Packet>::type* from, Index begin,
                                             Index count) {
  return ploaduSegment<Packet>(from, begin, count);
}

/** \internal copy the packet \a from in the range [begin, begin + count) to \a *to.
Elements outside of the range [begin, begin + count) are not defined. \a *to does not need to be aligned, and can be
null if \a count is zero.*/
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstoreuSegment(Scalar* to, const Packet& from, Index begin, Index count) {
  constexpr Index PacketSize = unpacket_traits<Packet>::size;
  eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) && "invalid range");
  Scalar aux[PacketSize];
  pstoreu<Scalar, Packet>(aux, from);
  for (Index k = begin; k < begin + count; k++) {
    to[k] = aux[k];
  }
}

/** \internal copy the packet \a from in the range [begin, begin + count) to \a *to.
Elements outside of the range [begin, begin + count) are not defined. \a *to must be aligned, and cannot be
null.*/
template <typename Scalar, typename Packet>
EIGEN_DEVICE_FUNC inline void pstoreSegment(Scalar* to, const Packet& from, Index begin, Index count) {
  return pstoreuSegment(to, from, begin, count);
}

/** \internal \returns a packet populated with values in the range [begin, begin + count). Elements
 * outside this range are zero.*/
template <typename Packet, int Alignment>
EIGEN_DEVICE_FUNC inline Packet ploadtSegment(const typename unpacket_traits<Packet>::type* from, Index begin,
                                              Index count) {
  constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
  EIGEN_IF_CONSTEXPR (Alignment >= RequiredAlignment) {
    return ploadSegment<Packet>(from, begin, count);
  } else {
    return ploaduSegment<Packet>(from, begin, count);
  }
}

/** \internal copy the packet \a from in the range [begin, begin + count) to \a *to.
Elements outside of the range [begin, begin + count) are not defined.*/
template <typename Scalar, typename Packet, int Alignment>
EIGEN_DEVICE_FUNC inline void pstoretSegment(Scalar* to, const Packet& from, Index begin, Index count) {
  constexpr int RequiredAlignment = unpacket_traits<Packet>::alignment;
  EIGEN_IF_CONSTEXPR (Alignment >= RequiredAlignment) {
    pstoreSegment<Scalar, Packet>(to, from, begin, count);
  } else {
    pstoreuSegment<Scalar, Packet>(to, from, begin, count);
  }
}

#ifndef EIGEN_NO_IO

template <typename Packet>
class StreamablePacket {
 public:
  using Scalar = typename unpacket_traits<Packet>::type;
  StreamablePacket(const Packet& packet) { pstoreu(v_, packet); }

  friend std::ostream& operator<<(std::ostream& os, const StreamablePacket& packet) {
    os << "{" << packet.v_[0];
    for (int i = 1; i < unpacket_traits<Packet>::size; ++i) {
      os << "," << packet.v_[i];
    }
    os << "}";
    return os;
  }

 private:
  Scalar v_[unpacket_traits<Packet>::size];
};

/**
 * \internal \returns an intermediary that can be used to ostream packets, e.g. for debugging.
 */
template <typename Packet>
StreamablePacket<Packet> postream(const Packet& packet) {
  return StreamablePacket<Packet>(packet);
}

#endif  // EIGEN_NO_IO

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_GENERIC_PACKET_MATH_H
