// abs template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> abs(batch<T, A> const& self, requires_arch<avx512bw>) noexcept
{
if (std::is_unsigned<T>::value)
{ return self;
}
// decr_if template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> decr_if(batch<T, A> const& self, batch_bool<T, A> const& mask, requires_arch<avx512bw>) noexcept
{
// eq template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> eq(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_EQ>(self, other);
}
// ge template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> ge(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_GE>(self, other);
}
// gt template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> gt(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_GT>(self, other);
}
// incr_if template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> incr_if(batch<T, A> const& self, batch_bool<T, A> const& mask, requires_arch<avx512bw>) noexcept
{
// insert template <class A, class T, size_t I, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> insert(batch<T, A> const& self, T val, index<I> pos, requires_arch<avx512bw>) noexcept
{
XSIMD_IF_CONSTEXPR(sizeof(T) == 1)
{ return _mm512_mask_set1_epi8(self, __mmask64(1ULL << (I & 63)), val);
} else XSIMD_IF_CONSTEXPR(sizeof(T) == 2)
{ return _mm512_mask_set1_epi16(self, __mmask32(1 << (I & 31)), val);
} else
{ return insert(self, val, pos, avx512dq {});
}
}
// le template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> le(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_LE>(self, other);
}
// lt template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> lt(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_LT>(self, other);
}
// mul template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> mul(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{
XSIMD_IF_CONSTEXPR(sizeof(T) == 1)
{
__m512i upper = _mm512_and_si512(_mm512_mullo_epi16(self, other), _mm512_srli_epi16(_mm512_set1_epi16(-1), 8));
__m512i lower = _mm512_slli_epi16(_mm512_mullo_epi16(_mm512_srli_epi16(self, 8), _mm512_srli_epi16(other, 8)), 8); return _mm512_or_si512(upper, lower);
} else XSIMD_IF_CONSTEXPR(sizeof(T) == 2)
{ return _mm512_mullo_epi16(self, other);
} else
{ return mul(self, other, avx512dq {});
}
}
// mul_hi template <class A>
XSIMD_INLINE batch<int8_t, A> mul_hi(batch<int8_t, A> const& self, batch<int8_t, A> const& other, requires_arch<avx512bw>) noexcept
{ // Per-128-bit-lane unpack/pack pair preserves byte ordering across // the four 128-bit lanes of a ZMM, so no inter-lane permute needed.
__m512i a_lo = _mm512_srai_epi16(_mm512_unpacklo_epi8(self, self), 8);
__m512i a_hi = _mm512_srai_epi16(_mm512_unpackhi_epi8(self, self), 8);
__m512i b_lo = _mm512_srai_epi16(_mm512_unpacklo_epi8(other, other), 8);
__m512i b_hi = _mm512_srai_epi16(_mm512_unpackhi_epi8(other, other), 8);
__m512i p_lo = _mm512_srai_epi16(_mm512_mullo_epi16(a_lo, b_lo), 8);
__m512i p_hi = _mm512_srai_epi16(_mm512_mullo_epi16(a_hi, b_hi), 8); return _mm512_packs_epi16(p_lo, p_hi);
} template <class A>
XSIMD_INLINE batch<uint8_t, A> mul_hi(batch<uint8_t, A> const& self, batch<uint8_t, A> const& other, requires_arch<avx512bw>) noexcept
{
__m512i zero = _mm512_setzero_si512();
__m512i a_lo = _mm512_unpacklo_epi8(self, zero);
__m512i a_hi = _mm512_unpackhi_epi8(self, zero);
__m512i b_lo = _mm512_unpacklo_epi8(other, zero);
__m512i b_hi = _mm512_unpackhi_epi8(other, zero);
__m512i p_lo = _mm512_srli_epi16(_mm512_mullo_epi16(a_lo, b_lo), 8);
__m512i p_hi = _mm512_srli_epi16(_mm512_mullo_epi16(a_hi, b_hi), 8); return _mm512_packus_epi16(p_lo, p_hi);
} template <class A>
XSIMD_INLINE batch<int16_t, A> mul_hi(batch<int16_t, A> const& self, batch<int16_t, A> const& other, requires_arch<avx512bw>) noexcept
{ return _mm512_mulhi_epi16(self, other);
} template <class A>
XSIMD_INLINE batch<uint16_t, A> mul_hi(batch<uint16_t, A> const& self, batch<uint16_t, A> const& other, requires_arch<avx512bw>) noexcept
{ return _mm512_mulhi_epu16(self, other);
}
// neq template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch_bool<T, A> neq(batch<T, A> const& self, batch<T, A> const& other, requires_arch<avx512bw>) noexcept
{ return detail::compare_int_avx512bw<A, T, _MM_CMPINT_NE>(self, other);
}
// select template <class A, class T, class = std::enable_if_t<std::is_integral<T>::value>>
XSIMD_INLINE batch<T, A> select(batch_bool<T, A> const& cond, batch<T, A> const& true_br, batch<T, A> const& false_br, requires_arch<avx512bw>) noexcept
{
XSIMD_IF_CONSTEXPR(sizeof(T) == 1)
{ return _mm512_mask_blend_epi8(cond, false_br.data, true_br.data);
} else XSIMD_IF_CONSTEXPR(sizeof(T) == 2)
{ return _mm512_mask_blend_epi16(cond, false_br.data, true_br.data);
} else
{ return select(cond, true_br, false_br, avx512dq {});
}
}
// slide_left template <size_t N, class A, class T, class = std::enable_if_t<(N & 3) == 2 && (N < 64)>>
XSIMD_INLINE batch<T, A> slide_left(batch<T, A> const& x, requires_arch<avx512bw>) noexcept
{
static_assert((N & 3) == 2 && N < 64, "The AVX512F implementation may have a lower latency.");
// slide_right template <size_t N, class A, class T, class = std::enable_if_t<(N & 3) == 2 && (N < 64)>>
XSIMD_INLINE batch<T, A> slide_right(batch<T, A> const& x, requires_arch<avx512bw>) noexcept
{
static_assert((N & 3) == 2 && N < 64, "The AVX512F implementation may have a lower latency.");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.