mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add signbit function
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
8f8e36458f
commit
82b152dbe7
@@ -229,10 +229,7 @@ template<> struct packet_traits<int64_t> : default_packet_traits
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 1,
|
||||
HasCmp = 1,
|
||||
size=4,
|
||||
|
||||
// requires AVX512
|
||||
HasShift = 0,
|
||||
size=4
|
||||
};
|
||||
};
|
||||
#endif
|
||||
@@ -360,6 +357,35 @@ template <int N>
|
||||
EIGEN_STRONG_INLINE Packet4l plogical_shift_left(Packet4l a) {
|
||||
return _mm256_slli_epi64(a, N);
|
||||
}
|
||||
#ifdef EIGEN_VECTORIZE_AVX512FP16
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE Packet4l parithmetic_shift_right(Packet4l a) { return _mm256_srai_epi64(a, N); }
|
||||
#else
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE std::enable_if_t< (N == 0), Packet4l> parithmetic_shift_right(Packet4l a) {
|
||||
return a;
|
||||
}
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE std::enable_if_t< (N > 0) && (N < 32), Packet4l> parithmetic_shift_right(Packet4l a) {
|
||||
__m256i hi_word = _mm256_srai_epi32(a, N);
|
||||
__m256i lo_word = _mm256_srli_epi64(a, N);
|
||||
return _mm256_blend_epi32(hi_word, lo_word, 0b01010101);
|
||||
}
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE std::enable_if_t< (N >= 32) && (N < 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
||||
__m256i hi_word = _mm256_srai_epi32(a, 31);
|
||||
__m256i lo_word = _mm256_shuffle_epi32(_mm256_srai_epi32(a, N - 32), (shuffle_mask<1, 1, 3, 3>::mask));
|
||||
return _mm256_blend_epi32(hi_word, lo_word, 0b01010101);
|
||||
}
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE std::enable_if_t< (N == 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
||||
return _mm256_shuffle_epi32(_mm256_srai_epi32(a, 31), (shuffle_mask<1, 1, 3, 3>::mask));
|
||||
}
|
||||
template <int N>
|
||||
EIGEN_STRONG_INLINE std::enable_if_t< (N < 0) || (N > 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
||||
return parithmetic_shift_right<int(N&63)>(a);
|
||||
}
|
||||
#endif
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4l pload<Packet4l>(const int64_t* from) {
|
||||
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
|
||||
@@ -1103,6 +1129,11 @@ template<> EIGEN_STRONG_INLINE Packet8i pabs(const Packet8i& a)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet8h psignbit(const Packet8h& a) { return _mm_srai_epi16(a, 15); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8bf psignbit(const Packet8bf& a) { return _mm_srai_epi16(a, 15); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8f psignbit(const Packet8f& a) { return _mm256_castsi256_ps(parithmetic_shift_right<31>((Packet8i)_mm256_castps_si256(a))); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4d psignbit(const Packet4d& a) { return _mm256_castsi256_pd(parithmetic_shift_right<63>((Packet4l)_mm256_castpd_si256(a))); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet8f pfrexp<Packet8f>(const Packet8f& a, Packet8f& exponent) {
|
||||
return pfrexp_generic(a,exponent);
|
||||
}
|
||||
|
||||
@@ -1127,6 +1127,11 @@ template<> EIGEN_STRONG_INLINE Packet16i pabs(const Packet16i& a)
|
||||
return _mm512_abs_epi32(a);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet16h psignbit(const Packet16h& a) { return _mm256_srai_epi16(a, 15); }
|
||||
template<> EIGEN_STRONG_INLINE Packet16bf psignbit(const Packet16bf& a) { return _mm256_srai_epi16(a, 15); }
|
||||
template<> EIGEN_STRONG_INLINE Packet16f psignbit(const Packet16f& a) { return _mm512_castsi512_ps(_mm512_srai_epi32(_mm512_castps_si512(a), 31)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8d psignbit(const Packet8d& a) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), 63)); }
|
||||
|
||||
template<>
|
||||
EIGEN_STRONG_INLINE Packet16f pfrexp<Packet16f>(const Packet16f& a, Packet16f& exponent){
|
||||
return pfrexp_generic(a, exponent);
|
||||
|
||||
@@ -196,6 +196,13 @@ EIGEN_STRONG_INLINE Packet32h pabs<Packet32h>(const Packet32h& a) {
|
||||
return _mm512_abs_ph(a);
|
||||
}
|
||||
|
||||
// psignbit
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet32h psignbit<Packet32h>(const Packet32h& a) {
|
||||
return _mm512_castsi512_ph(_mm512_srai_epi16(_mm512_castph_si512(a), 15));
|
||||
}
|
||||
|
||||
// pmin
|
||||
|
||||
template <>
|
||||
|
||||
@@ -1575,6 +1575,9 @@ template<> EIGEN_STRONG_INLINE Packet8bf pabs(const Packet8bf& a) {
|
||||
return pand<Packet8us>(p8us_abs_mask, a);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet8bf psignbit(const Packet8bf& a) { return vec_sra(a.m_val, vec_splat_u16(15)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psignbit(const Packet4f& a) { return (Packet4f)vec_sra((Packet4i)a, vec_splats(uint32_t(31))); }
|
||||
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i parithmetic_shift_right(const Packet4i& a)
|
||||
{ return vec_sra(a,reinterpret_cast<Packet4ui>(pset1<Packet4i>(N))); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i plogical_shift_right(const Packet4i& a)
|
||||
@@ -2928,7 +2931,7 @@ template<> EIGEN_STRONG_INLINE Packet2d preverse(const Packet2d& a)
|
||||
return vec_sld(a, a, 8);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a) { return vec_abs(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d psignbit(const Packet2d& a) { return (Packet2d)vec_sra((Packet2l)a, vec_splats(uint64_t(63))); }
|
||||
// VSX support varies between different compilers and even different
|
||||
// versions of the same compiler. For gcc version >= 4.9.3, we can use
|
||||
// vec_cts to efficiently convert Packet2d to Packet2l. Otherwise, use
|
||||
|
||||
@@ -2372,6 +2372,12 @@ template<> EIGEN_STRONG_INLINE Packet2l pabs(const Packet2l& a) {
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2ul pabs(const Packet2ul& a) { return a; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4h psignbit(const Packet4h& a) { vreinterpret_f16_s16( vshr_n_s16( vreinterpret_s16_f16(a), 15)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet8h psignbit(const Packet8h& a) { vreinterpretq_f16_s16(vshrq_n_s16(vreinterpretq_s16_f16(a), 15)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2f psignbit(const Packet2f& a) { vreinterpret_f32_s32( vshr_n_s32( vreinterpret_s32_f32(a), 31)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psignbit(const Packet4f& a) { vreinterpretq_f32_s32(vshrq_n_s32(vreinterpretq_s32_f32(a), 31)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d psignbit(const Packet2d& a) { vreinterpretq_f64_s64(vshrq_n_s64(vreinterpretq_s64_f64(a), 63)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pfrexp<Packet2f>(const Packet2f& a, Packet2f& exponent)
|
||||
{ return pfrexp_generic(a,exponent); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfrexp<Packet4f>(const Packet4f& a, Packet4f& exponent)
|
||||
|
||||
@@ -649,6 +649,17 @@ template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psignbit(const Packet4f& a) { return _mm_castsi128_ps(_mm_srai_epi32(_mm_castps_si128(a), 31)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d psignbit(const Packet2d& a)
|
||||
{
|
||||
Packet4f tmp = psignbit<Packet4f>(_mm_castpd_ps(a));
|
||||
#ifdef EIGEN_VECTORIZE_AVX
|
||||
return _mm_castps_pd(_mm_permute_ps(tmp, (shuffle_mask<1, 1, 3, 3>::mask)));
|
||||
#else
|
||||
return _mm_castps_pd(_mm_shuffle_ps(tmp, tmp, (shuffle_mask<1, 1, 3, 3>::mask)));
|
||||
#endif // EIGEN_VECTORIZE_AVX
|
||||
}
|
||||
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user