// 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 inline Packet pconj(const Packet& a) {
  return numext::conj(a);
}

/** \internal \returns a * b (coeff-wise) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pmul(const Packet& a, const Packet& b) {
  return 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 \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. */
template <int NaNPropagation, bool IsInteger>
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> {
  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 <>
struct pminmax_impl<PropagateNumbers, false> {
  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;
  return pminmax_impl<NaNPropagation, IsInteger>::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;
  return pminmax_impl<NaNPropagation, IsInteger>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmax<Packet>)));
}

/** \internal \returns the absolute value of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pabs(const Packet& a) {
  return numext::abs(a);
}
template <>
EIGEN_DEVICE_FUNC inline unsigned int pabs(const unsigned int& a) {
  return a;
}
template <>
EIGEN_DEVICE_FUNC inline unsigned long pabs(const unsigned long& a) {
  return a;
}
template <>
EIGEN_DEVICE_FUNC inline unsigned long long pabs(const unsigned long long& 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 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];
}

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

/** \internal \returns the product of the elements of \a a */
template <typename Packet>
EIGEN_DEVICE_FUNC 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

/** \internal \returns true if all coeffs of \a a means "true"
 * It is supposed to be called on values returned by pcmp_*.
 */
// TODO: implement predux_all when needed.

/** \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).
  // For all these cases, taking the sum is just fine, and this boils down to a no-op for scalars.
  using Scalar = typename unpacket_traits<Packet>::type;
  return numext::not_equal_strict(predux(a), Scalar(0));
}

/***************************************************************************
 * 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>
struct psignbit_impl;
template <typename Packet, bool IsInteger>
struct psignbit_impl<Packet, true, IsInteger> {
  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> {
  // 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> {
  // generic implementation for integer packets
  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Packet run(const Packet& a) { return pcmp_lt(a, 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
