Bit shifting functions

This commit is contained in:
Charles Schlosser
2024-05-03 18:55:02 +00:00
committed by Rasmus Munk Larsen
parent 9700fc847a
commit 8e47971789
6 changed files with 113 additions and 48 deletions

View File

@@ -709,33 +709,21 @@ EIGEN_DEVICE_FUNC inline Packet parg(const Packet& a) {
}
/** \internal \returns \a a arithmetically shifted by N bits to the right */
template <int N>
EIGEN_DEVICE_FUNC inline int parithmetic_shift_right(const int& a) {
return a >> N;
}
template <int N>
EIGEN_DEVICE_FUNC inline long int parithmetic_shift_right(const long int& a) {
return a >> N;
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>
EIGEN_DEVICE_FUNC inline int plogical_shift_right(const int& a) {
return static_cast<int>(static_cast<unsigned int>(a) >> N);
}
template <int N>
EIGEN_DEVICE_FUNC inline long int plogical_shift_right(const long int& a) {
return static_cast<long>(static_cast<unsigned long>(a) >> N);
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>
EIGEN_DEVICE_FUNC inline int plogical_shift_left(const int& a) {
return a << N;
}
template <int N>
EIGEN_DEVICE_FUNC inline long int plogical_shift_left(const long int& a) {
return a << N;
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

View File

@@ -1746,6 +1746,23 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double fmod(const double& a, const double&
#undef SYCL_SPECIALIZE_BINARY_FUNC
#endif
template <typename Scalar, typename Enable = std::enable_if_t<std::is_integral<Scalar>::value>>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar logical_shift_left(const Scalar& a, int n) {
return a << n;
}
template <typename Scalar, typename Enable = std::enable_if_t<std::is_integral<Scalar>::value>>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar logical_shift_right(const Scalar& a, int n) {
using UnsignedScalar = typename numext::get_integer_by_size<sizeof(Scalar)>::unsigned_type;
return bit_cast<Scalar, UnsignedScalar>(bit_cast<UnsignedScalar, Scalar>(a) >> n);
}
template <typename Scalar, typename Enable = std::enable_if_t<std::is_integral<Scalar>::value>>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar arithmetic_shift_right(const Scalar& a, int n) {
using SignedScalar = typename numext::get_integer_by_size<sizeof(Scalar)>::signed_type;
return bit_cast<Scalar, SignedScalar>(bit_cast<SignedScalar, Scalar>(a) >> n);
}
} // end namespace numext
namespace internal {

View File

@@ -101,10 +101,10 @@ namespace numext {
template <typename Tgt, typename Src>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
// The behaviour of memcpy is not specified for non-trivially copyable types
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED);
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED)
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
THIS_TYPE_IS_NOT_SUPPORTED);
EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED);
THIS_TYPE_IS_NOT_SUPPORTED)
EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED)
Tgt tgt;
// Load src into registers first. This allows the memcpy to be elided by CUDA.

View File

@@ -219,7 +219,9 @@ struct functor_traits<core_cast_op<SrcType, DstType>> {
*/
template <typename Scalar, int N>
struct scalar_shift_right_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const { return a >> N; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const {
return numext::arithmetic_shift_right(a);
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const {
return internal::parithmetic_shift_right<N>(a);
@@ -237,7 +239,9 @@ struct functor_traits<scalar_shift_right_op<Scalar, N>> {
*/
template <typename Scalar, int N>
struct scalar_shift_left_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const { return a << N; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& a) const {
return numext::logical_shift_left(a);
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const {
return internal::plogical_shift_left<N>(a);