// 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));
  }
};

/** \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));
  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);
}

/** \internal \returns the bitwise not of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pnot(const Packet& a) {
  return bitwise_helper<Packet>::bitwise_not(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
 ***************************/

// 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(pcmp_lt_or_nan<RealPacket>(a.v, 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) {
  EIGEN_USING_STD(log);
  return 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) {
  EIGEN_USING_STD(log10);
  return log10(a);
}

/** \internal \returns the log2 of \a a (coeff-wise) */
template <typename Packet>
EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(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));
}

/** \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));
  }
};

template <typename Scalar>
struct pmadd_impl<Scalar, std::enable_if_t<is_scalar<Scalar>::value && NumTraits<Scalar>::IsSigned>> {
  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 not defined. \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 not defined. \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 not defined.*/
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
