mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
GPU: Raise CUDA/HIP minimum and remove legacy guards
- Raise CUDA minimum from 9.0 to 11.4 (sm_70/Volta).
- Raise HIP minimum to GFX906 (Vega 20/MI50) / ROCm 5.6.
- Remove EIGEN_HAS_{CUDA,HIP,GPU}_FP16 guards — FP16 is always available
on sm_70+ and GFX906+.
- Remove obsolete __HIP_ARCH_HAS_* preprocessor branches.
- C++14 cleanup: remove pre-C++14 workarounds in GPU code.
- Fix NVCC warnings (deprecated register keyword, unreachable code,
tautological comparisons).
- Fix HIP test execution on gfx1151.
- Update CI configuration for new minimum versions.
This commit is contained in:
@@ -858,16 +858,8 @@ struct hash<Eigen::bfloat16> {
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
// Add the missing shfl* intrinsics.
|
||||
// The __shfl* functions are only valid on HIP or _CUDA_ARCH_ >= 300.
|
||||
// CUDA defines them for (__CUDA_ARCH__ >= 300 || !defined(__CUDA_ARCH__))
|
||||
//
|
||||
// HIP and CUDA prior to SDK 9.0 define
|
||||
// __shfl, __shfl_up, __shfl_down, __shfl_xor for int and float
|
||||
// CUDA since 9.0 deprecates those and instead defines
|
||||
// __shfl_sync, __shfl_up_sync, __shfl_down_sync, __shfl_xor_sync,
|
||||
// with native support for __half and __nv_bfloat16
|
||||
//
|
||||
// Warp shuffle overloads for Eigen::bfloat16.
|
||||
// HIP uses non-sync __shfl variants; CUDA has native __nv_bfloat16 support in __shfl_sync.
|
||||
// Note that the following are __device__ - only functions.
|
||||
#if defined(EIGEN_HIPCC)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
// Eigen with GPU support.
|
||||
// Any functions that require `numext::bit_cast` may also not be constexpr,
|
||||
// including any native types when setting via raw bit values.
|
||||
#if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
|
||||
#if defined(EIGEN_GPUCC) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
|
||||
#define _EIGEN_MAYBE_CONSTEXPR
|
||||
#else
|
||||
#define _EIGEN_MAYBE_CONSTEXPR constexpr
|
||||
@@ -121,12 +121,12 @@ namespace half_impl {
|
||||
//
|
||||
// Making the host side compile phase of hipcc use the same Eigen::half impl, as the gcc compile, resolves
|
||||
// this error, and hence the following convoluted #if condition
|
||||
#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if !defined(EIGEN_GPUCC) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
// Make our own __half_raw definition that is similar to CUDA's.
|
||||
struct __half_raw {
|
||||
struct construct_from_rep_tag {};
|
||||
#if (defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE))
|
||||
#if (defined(EIGEN_GPUCC) && !defined(EIGEN_GPU_COMPILE_PHASE))
|
||||
// Eigen::half can be used as the datatype for shared memory declarations (in Eigen and TF)
|
||||
// The element type for shared memory cannot have non-trivial constructors
|
||||
// and hence the following special casing (which skips the zero-initilization).
|
||||
@@ -152,16 +152,12 @@ struct __half_raw {
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif defined(EIGEN_HAS_HIP_FP16)
|
||||
#elif defined(EIGEN_HIPCC)
|
||||
// HIP GPU compile phase: nothing to do here.
|
||||
// HIP fp16 header file has a definition for __half_raw
|
||||
#elif defined(EIGEN_HAS_CUDA_FP16)
|
||||
#elif defined(EIGEN_CUDACC)
|
||||
|
||||
// CUDA GPU compile phase.
|
||||
#if EIGEN_CUDA_SDK_VER < 90000
|
||||
// In CUDA < 9.0, __half is the equivalent of CUDA 9's __half_raw
|
||||
typedef __half __half_raw;
|
||||
#endif // defined(EIGEN_HAS_CUDA_FP16)
|
||||
|
||||
#elif defined(SYCL_DEVICE_ONLY)
|
||||
typedef cl::sycl::half __half_raw;
|
||||
@@ -175,15 +171,13 @@ struct half_base : public __half_raw {
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base() {}
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(const __half_raw& h) : __half_raw(h) {}
|
||||
|
||||
#if defined(EIGEN_HAS_GPU_FP16)
|
||||
#if defined(EIGEN_HAS_HIP_FP16)
|
||||
#if defined(EIGEN_GPUCC)
|
||||
#if defined(EIGEN_HIPCC)
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(const __half& h) { x = __half_as_ushort(h); }
|
||||
#elif defined(EIGEN_HAS_CUDA_FP16)
|
||||
#if EIGEN_CUDA_SDK_VER >= 90000
|
||||
#elif defined(EIGEN_CUDACC)
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(const __half& h) : __half_raw(*(__half_raw*)&h) {}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace half_impl
|
||||
@@ -192,36 +186,29 @@ struct half_base : public __half_raw {
|
||||
struct half : public half_impl::half_base {
|
||||
// Writing this out as separate #if-else blocks to make the code easier to follow
|
||||
// The same applies to most #if-else blocks in this file
|
||||
#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if !defined(EIGEN_GPUCC) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Use the same base class for the following two scenarios
|
||||
// * when compiling without GPU support enabled
|
||||
// * during host compile phase when compiling with GPU support enabled
|
||||
typedef half_impl::__half_raw __half_raw;
|
||||
#elif defined(EIGEN_HAS_HIP_FP16)
|
||||
#elif defined(EIGEN_HIPCC)
|
||||
// Nothing to do here
|
||||
// HIP fp16 header file has a definition for __half_raw
|
||||
#elif defined(EIGEN_HAS_CUDA_FP16)
|
||||
// Note that EIGEN_CUDA_SDK_VER is set to 0 even when compiling with HIP, so
|
||||
// (EIGEN_CUDA_SDK_VER < 90000) is true even for HIP! So keeping this within
|
||||
// #if defined(EIGEN_HAS_CUDA_FP16) is needed
|
||||
#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER < 90000
|
||||
typedef half_impl::__half_raw __half_raw;
|
||||
#endif
|
||||
#elif defined(EIGEN_CUDACC)
|
||||
// Nothing to do here.
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half() {}
|
||||
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(const __half_raw& h) : half_impl::half_base(h) {}
|
||||
|
||||
#if defined(EIGEN_HAS_GPU_FP16)
|
||||
#if defined(EIGEN_HAS_HIP_FP16)
|
||||
#if defined(EIGEN_GPUCC)
|
||||
#if defined(EIGEN_HIPCC)
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(const __half& h) : half_impl::half_base(h) {}
|
||||
#elif defined(EIGEN_HAS_CUDA_FP16)
|
||||
#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
|
||||
#elif defined(EIGEN_CUDACC)
|
||||
EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(const __half& h) : half_impl::half_base(h) {}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
|
||||
explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(__fp16 b)
|
||||
@@ -248,7 +235,7 @@ struct half : public half_impl::half_base {
|
||||
return half_impl::half_to_float(*this);
|
||||
}
|
||||
|
||||
#if defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if defined(EIGEN_GPUCC) && !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
EIGEN_DEVICE_FUNC operator __half() const {
|
||||
::__half_raw hr;
|
||||
hr.x = x;
|
||||
@@ -380,8 +367,7 @@ namespace Eigen {
|
||||
|
||||
namespace half_impl {
|
||||
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Note: We deliberately do *not* define this to 1 even if we have Arm's native
|
||||
// fp16 type since GPU half types are rather different from native CPU half types.
|
||||
#define EIGEN_HAS_NATIVE_GPU_FP16
|
||||
@@ -393,24 +379,10 @@ namespace half_impl {
|
||||
// conversion steps back and forth.
|
||||
|
||||
#if defined(EIGEN_HAS_NATIVE_GPU_FP16)
|
||||
EIGEN_STRONG_INLINE __device__ half operator+(const half& a, const half& b) {
|
||||
#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
|
||||
return __hadd(::__half(a), ::__half(b));
|
||||
#else
|
||||
return __hadd(a, b);
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE __device__ half operator+(const half& a, const half& b) { return __hadd(::__half(a), ::__half(b)); }
|
||||
EIGEN_STRONG_INLINE __device__ half operator*(const half& a, const half& b) { return __hmul(a, b); }
|
||||
EIGEN_STRONG_INLINE __device__ half operator-(const half& a, const half& b) { return __hsub(a, b); }
|
||||
EIGEN_STRONG_INLINE __device__ half operator/(const half& a, const half& b) {
|
||||
#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
|
||||
return __hdiv(a, b);
|
||||
#else
|
||||
float num = __half2float(a);
|
||||
float denom = __half2float(b);
|
||||
return __float2half(num / denom);
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE __device__ half operator/(const half& a, const half& b) { return __hdiv(a, b); }
|
||||
EIGEN_STRONG_INLINE __device__ half operator-(const half& a) { return __hneg(a); }
|
||||
EIGEN_STRONG_INLINE __device__ half& operator+=(half& a, const half& b) {
|
||||
a = a + b;
|
||||
@@ -505,7 +477,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator>=(const half& a, const half&
|
||||
// We need to provide emulated *host-side* FP16 operators for clang.
|
||||
#pragma push_macro("EIGEN_DEVICE_FUNC")
|
||||
#undef EIGEN_DEVICE_FUNC
|
||||
#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_HAS_NATIVE_GPU_FP16)
|
||||
#if defined(EIGEN_CUDACC) && defined(EIGEN_HAS_NATIVE_GPU_FP16)
|
||||
#define EIGEN_DEVICE_FUNC __host__
|
||||
#else // both host and device need emulated ops.
|
||||
#define EIGEN_DEVICE_FUNC __host__ __device__
|
||||
@@ -636,7 +608,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw raw_uint
|
||||
// because this is constexpr function.
|
||||
// Fortunately, since we need to disable EIGEN_CONSTEXPR for GPU anyway, we can get out
|
||||
// of this catch22 by having separate bodies for GPU / non GPU
|
||||
#if defined(EIGEN_HAS_GPU_FP16)
|
||||
#if defined(EIGEN_GPUCC)
|
||||
__half_raw h;
|
||||
h.x = x;
|
||||
return h;
|
||||
@@ -661,8 +633,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC numext::uint16_t raw_half_as_uint16(const
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
__half tmp_ff = __float2half(ff);
|
||||
return *(__half_raw*)&tmp_ff;
|
||||
|
||||
@@ -735,8 +706,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff) {
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __half2float(h);
|
||||
#elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
|
||||
return static_cast<float>(h.x);
|
||||
@@ -778,8 +748,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isinf)(const half& a) {
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isnan)(const half& a) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __hisnan(a);
|
||||
#elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
|
||||
return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) > 0x7c00;
|
||||
@@ -810,16 +779,14 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half& a) {
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
return half(hexp(a));
|
||||
#else
|
||||
return half(::expf(float(a)));
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp2(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
return half(hexp2(a));
|
||||
#else
|
||||
return half(::exp2f(float(a)));
|
||||
@@ -827,9 +794,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp2(const half& a) {
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(const half& a) { return half(numext::expm1(float(a))); }
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && \
|
||||
EIGEN_CUDA_ARCH >= 530) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return half(hlog(a));
|
||||
#else
|
||||
return half(::logf(float(a)));
|
||||
@@ -842,8 +807,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log2(const half& a) {
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
return half(hsqrt(a));
|
||||
#else
|
||||
return half(::sqrtf(float(a)));
|
||||
@@ -864,16 +828,14 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half acos(const half& a) { return half(::a
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atan(const half& a) { return half(::atanf(float(a))); }
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atanh(const half& a) { return half(::atanhf(float(a))); }
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#if (defined(EIGEN_CUDA_ARCH)) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
return half(hfloor(a));
|
||||
#else
|
||||
return half(::floorf(float(a)));
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#if (defined(EIGEN_CUDA_ARCH)) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
return half(hceil(a));
|
||||
#else
|
||||
return half(::ceilf(float(a)));
|
||||
@@ -1007,20 +969,12 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half madd<Eigen::half>(const Eigen:
|
||||
} // namespace numext
|
||||
} // namespace Eigen
|
||||
|
||||
// Add the missing shfl* intrinsics.
|
||||
// The __shfl* functions are only valid on HIP or _CUDA_ARCH_ >= 300.
|
||||
// CUDA defines them for (__CUDA_ARCH__ >= 300 || !defined(__CUDA_ARCH__))
|
||||
//
|
||||
// HIP and CUDA prior to SDK 9.0 define
|
||||
// __shfl, __shfl_up, __shfl_down, __shfl_xor for int and float
|
||||
// CUDA since 9.0 deprecates those and instead defines
|
||||
// __shfl_sync, __shfl_up_sync, __shfl_down_sync, __shfl_xor_sync,
|
||||
// with native support for __half and __nv_bfloat16
|
||||
//
|
||||
// Warp shuffle overloads for Eigen::half.
|
||||
// CUDA uses __shfl_*_sync (with mask); HIP uses __shfl_* (no mask).
|
||||
// Note that the following are __device__ - only functions.
|
||||
#if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 300)) || defined(EIGEN_HIPCC)
|
||||
#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
|
||||
|
||||
#if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 90000
|
||||
#if defined(EIGEN_CUDACC)
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_sync(unsigned mask, Eigen::half var, int srcLane,
|
||||
int width = warpSize) {
|
||||
@@ -1046,7 +1000,7 @@ __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor_sync(unsigned mask, Eigen:
|
||||
return static_cast<Eigen::half>(__shfl_xor_sync(mask, h, laneMask, width));
|
||||
}
|
||||
|
||||
#else // HIP or CUDA SDK < 9.0
|
||||
#else // HIP
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl(Eigen::half var, int srcLane, int width = warpSize) {
|
||||
const int ivar = static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
|
||||
@@ -1072,7 +1026,7 @@ __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor(Eigen::half var, int laneM
|
||||
#endif // __shfl*
|
||||
|
||||
// ldg() has an overload for __half_raw, but we also need one for Eigen::half.
|
||||
#if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 350)) || defined(EIGEN_HIPCC)
|
||||
#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
|
||||
EIGEN_STRONG_INLINE __device__ Eigen::half __ldg(const Eigen::half* ptr) {
|
||||
return Eigen::half_impl::raw_uint16_to_half(__ldg(reinterpret_cast<const Eigen::numext::uint16_t*>(ptr)));
|
||||
}
|
||||
@@ -1095,8 +1049,7 @@ namespace internal {
|
||||
template <>
|
||||
struct cast_impl<float, half> {
|
||||
EIGEN_DEVICE_FUNC static inline half run(const float& a) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __float2half(a);
|
||||
#else
|
||||
return half(a);
|
||||
@@ -1107,8 +1060,7 @@ struct cast_impl<float, half> {
|
||||
template <>
|
||||
struct cast_impl<int, half> {
|
||||
EIGEN_DEVICE_FUNC static inline half run(const int& a) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __float2half(static_cast<float>(a));
|
||||
#else
|
||||
return half(static_cast<float>(a));
|
||||
@@ -1119,8 +1071,7 @@ struct cast_impl<int, half> {
|
||||
template <>
|
||||
struct cast_impl<half, float> {
|
||||
EIGEN_DEVICE_FUNC static inline float run(const half& a) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __half2float(a);
|
||||
#else
|
||||
return static_cast<float>(a);
|
||||
|
||||
@@ -17,19 +17,8 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Read-only data cached load available.
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 350)
|
||||
#define EIGEN_GPU_HAS_LDG 1
|
||||
#endif
|
||||
|
||||
// FP16 math available.
|
||||
#if (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530)
|
||||
#define EIGEN_CUDA_HAS_FP16_ARITHMETIC 1
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
#define EIGEN_GPU_HAS_FP16_ARITHMETIC 1
|
||||
#endif
|
||||
// Read-only data cached load (__ldg) and native FP16 arithmetic are available
|
||||
// on all supported GPU architectures (sm_70+ for CUDA, GFX906+ for HIP).
|
||||
|
||||
// We need to distinguish ‘clang as the CUDA compiler’ from ‘clang as the host compiler,
|
||||
// invoked by NVCC’ (e.g. on MacOS). The former needs to see both host and device implementation
|
||||
@@ -56,92 +45,84 @@ struct is_arithmetic<double2> {
|
||||
|
||||
template <>
|
||||
struct packet_traits<float> : default_packet_traits {
|
||||
typedef float4 type;
|
||||
typedef float4 half;
|
||||
enum {
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 1,
|
||||
size = 4,
|
||||
using type = float4;
|
||||
using half = float4;
|
||||
static constexpr int Vectorizable = 1;
|
||||
static constexpr int AlignedOnScalar = 1;
|
||||
static constexpr int size = 4;
|
||||
|
||||
HasDiv = 1,
|
||||
HasSin = 0,
|
||||
HasCos = 0,
|
||||
HasLog = 1,
|
||||
HasExp = 1,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasLGamma = 1,
|
||||
HasDiGamma = 1,
|
||||
HasZeta = 1,
|
||||
HasPolygamma = 1,
|
||||
HasErf = 1,
|
||||
HasErfc = 1,
|
||||
HasNdtri = 1,
|
||||
HasBessel = 1,
|
||||
HasIGamma = 1,
|
||||
HasIGammaDerA = 1,
|
||||
HasGammaSampleDerAlpha = 1,
|
||||
HasIGammac = 1,
|
||||
HasBetaInc = 1,
|
||||
static constexpr int HasDiv = 1;
|
||||
static constexpr int HasSin = 0;
|
||||
static constexpr int HasCos = 0;
|
||||
static constexpr int HasLog = 1;
|
||||
static constexpr int HasExp = 1;
|
||||
static constexpr int HasSqrt = 1;
|
||||
static constexpr int HasRsqrt = 1;
|
||||
static constexpr int HasLGamma = 1;
|
||||
static constexpr int HasDiGamma = 1;
|
||||
static constexpr int HasZeta = 1;
|
||||
static constexpr int HasPolygamma = 1;
|
||||
static constexpr int HasErf = 1;
|
||||
static constexpr int HasErfc = 1;
|
||||
static constexpr int HasNdtri = 1;
|
||||
static constexpr int HasBessel = 1;
|
||||
static constexpr int HasIGamma = 1;
|
||||
static constexpr int HasIGammaDerA = 1;
|
||||
static constexpr int HasGammaSampleDerAlpha = 1;
|
||||
static constexpr int HasIGammac = 1;
|
||||
static constexpr int HasBetaInc = 1;
|
||||
|
||||
HasFloor = 1,
|
||||
HasCmp = EIGEN_HAS_GPU_DEVICE_FUNCTIONS
|
||||
};
|
||||
static constexpr int HasFloor = 1;
|
||||
static constexpr int HasCmp = EIGEN_HAS_GPU_DEVICE_FUNCTIONS;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct packet_traits<double> : default_packet_traits {
|
||||
typedef double2 type;
|
||||
typedef double2 half;
|
||||
enum {
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 1,
|
||||
size = 2,
|
||||
using type = double2;
|
||||
using half = double2;
|
||||
static constexpr int Vectorizable = 1;
|
||||
static constexpr int AlignedOnScalar = 1;
|
||||
static constexpr int size = 2;
|
||||
|
||||
HasDiv = 1,
|
||||
HasLog = 1,
|
||||
HasExp = 1,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasLGamma = 1,
|
||||
HasDiGamma = 1,
|
||||
HasZeta = 1,
|
||||
HasPolygamma = 1,
|
||||
HasErf = 1,
|
||||
HasErfc = 1,
|
||||
HasNdtri = 1,
|
||||
HasBessel = 1,
|
||||
HasIGamma = 1,
|
||||
HasIGammaDerA = 1,
|
||||
HasGammaSampleDerAlpha = 1,
|
||||
HasIGammac = 1,
|
||||
HasBetaInc = 1,
|
||||
};
|
||||
static constexpr int HasDiv = 1;
|
||||
static constexpr int HasLog = 1;
|
||||
static constexpr int HasExp = 1;
|
||||
static constexpr int HasSqrt = 1;
|
||||
static constexpr int HasRsqrt = 1;
|
||||
static constexpr int HasLGamma = 1;
|
||||
static constexpr int HasDiGamma = 1;
|
||||
static constexpr int HasZeta = 1;
|
||||
static constexpr int HasPolygamma = 1;
|
||||
static constexpr int HasErf = 1;
|
||||
static constexpr int HasErfc = 1;
|
||||
static constexpr int HasNdtri = 1;
|
||||
static constexpr int HasBessel = 1;
|
||||
static constexpr int HasIGamma = 1;
|
||||
static constexpr int HasIGammaDerA = 1;
|
||||
static constexpr int HasGammaSampleDerAlpha = 1;
|
||||
static constexpr int HasIGammac = 1;
|
||||
static constexpr int HasBetaInc = 1;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unpacket_traits<float4> {
|
||||
typedef float type;
|
||||
enum {
|
||||
size = 4,
|
||||
alignment = Aligned16,
|
||||
vectorizable = true,
|
||||
masked_load_available = false,
|
||||
masked_store_available = false
|
||||
};
|
||||
typedef float4 half;
|
||||
using type = float;
|
||||
static constexpr int size = 4;
|
||||
static constexpr int alignment = Aligned16;
|
||||
static constexpr bool vectorizable = true;
|
||||
static constexpr bool masked_load_available = false;
|
||||
static constexpr bool masked_store_available = false;
|
||||
using half = float4;
|
||||
};
|
||||
template <>
|
||||
struct unpacket_traits<double2> {
|
||||
typedef double type;
|
||||
enum {
|
||||
size = 2,
|
||||
alignment = Aligned16,
|
||||
vectorizable = true,
|
||||
masked_load_available = false,
|
||||
masked_store_available = false
|
||||
};
|
||||
typedef double2 half;
|
||||
using type = double;
|
||||
static constexpr int size = 2;
|
||||
static constexpr int alignment = Aligned16;
|
||||
static constexpr bool vectorizable = true;
|
||||
static constexpr bool masked_load_available = false;
|
||||
static constexpr bool masked_store_available = false;
|
||||
using half = double2;
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -403,7 +384,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const dou
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float4 ploadt_ro<float4, Aligned>(const float* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __ldg(reinterpret_cast<const float4*>(from));
|
||||
#else
|
||||
return make_float4(from[0], from[1], from[2], from[3]);
|
||||
@@ -411,7 +392,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float4 ploadt_ro<float4, Aligned>(const fl
|
||||
}
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double2 ploadt_ro<double2, Aligned>(const double* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __ldg(reinterpret_cast<const double2*>(from));
|
||||
#else
|
||||
return make_double2(from[0], from[1]);
|
||||
@@ -420,7 +401,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double2 ploadt_ro<double2, Aligned>(const
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float4 ploadt_ro<float4, Unaligned>(const float* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return make_float4(__ldg(from + 0), __ldg(from + 1), __ldg(from + 2), __ldg(from + 3));
|
||||
#else
|
||||
return make_float4(from[0], from[1], from[2], from[3]);
|
||||
@@ -428,7 +409,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float4 ploadt_ro<float4, Unaligned>(const
|
||||
}
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double2 ploadt_ro<double2, Unaligned>(const double* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return make_double2(__ldg(from + 0), __ldg(from + 1));
|
||||
#else
|
||||
return make_double2(from[0], from[1]);
|
||||
@@ -591,23 +572,20 @@ EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<double2, 2>& kernel) {
|
||||
|
||||
#endif // defined(EIGEN_GPUCC) && defined(EIGEN_USE_GPU)
|
||||
|
||||
// Half-packet functions are not available on the host for CUDA 9.0-9.2, only
|
||||
// on device. There is no benefit to using them on the host anyways, since they are
|
||||
// emulated.
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)) && defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Half-packet functions are only available in GPU device compilation — they use
|
||||
// intrinsics (__half2, etc.) that have no host-side benefit.
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
typedef ulonglong2 Packet4h2;
|
||||
using Packet4h2 = ulonglong2;
|
||||
template <>
|
||||
struct unpacket_traits<Packet4h2> {
|
||||
typedef Eigen::half type;
|
||||
enum {
|
||||
size = 8,
|
||||
alignment = Aligned16,
|
||||
vectorizable = true,
|
||||
masked_load_available = false,
|
||||
masked_store_available = false
|
||||
};
|
||||
typedef Packet4h2 half;
|
||||
using type = Eigen::half;
|
||||
static constexpr int size = 8;
|
||||
static constexpr int alignment = Aligned16;
|
||||
static constexpr bool vectorizable = true;
|
||||
static constexpr bool masked_load_available = false;
|
||||
static constexpr bool masked_store_available = false;
|
||||
using half = Packet4h2;
|
||||
};
|
||||
template <>
|
||||
struct is_arithmetic<Packet4h2> {
|
||||
@@ -616,15 +594,13 @@ struct is_arithmetic<Packet4h2> {
|
||||
|
||||
template <>
|
||||
struct unpacket_traits<half2> {
|
||||
typedef Eigen::half type;
|
||||
enum {
|
||||
size = 2,
|
||||
alignment = Aligned16,
|
||||
vectorizable = true,
|
||||
masked_load_available = false,
|
||||
masked_store_available = false
|
||||
};
|
||||
typedef half2 half;
|
||||
using type = Eigen::half;
|
||||
static constexpr int size = 2;
|
||||
static constexpr int alignment = Aligned16;
|
||||
static constexpr bool vectorizable = true;
|
||||
static constexpr bool masked_load_available = false;
|
||||
static constexpr bool masked_store_available = false;
|
||||
using half = half2;
|
||||
};
|
||||
template <>
|
||||
struct is_arithmetic<half2> {
|
||||
@@ -633,23 +609,21 @@ struct is_arithmetic<half2> {
|
||||
|
||||
template <>
|
||||
struct packet_traits<Eigen::half> : default_packet_traits {
|
||||
typedef Packet4h2 type;
|
||||
typedef Packet4h2 half;
|
||||
enum {
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 1,
|
||||
size = 8,
|
||||
HasAdd = 1,
|
||||
HasSub = 1,
|
||||
HasMul = 1,
|
||||
HasDiv = 1,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasExp = 1,
|
||||
HasExpm1 = 1,
|
||||
HasLog = 1,
|
||||
HasLog1p = 1
|
||||
};
|
||||
using type = Packet4h2;
|
||||
using half = Packet4h2;
|
||||
static constexpr int Vectorizable = 1;
|
||||
static constexpr int AlignedOnScalar = 1;
|
||||
static constexpr int size = 8;
|
||||
static constexpr int HasAdd = 1;
|
||||
static constexpr int HasSub = 1;
|
||||
static constexpr int HasMul = 1;
|
||||
static constexpr int HasDiv = 1;
|
||||
static constexpr int HasSqrt = 1;
|
||||
static constexpr int HasRsqrt = 1;
|
||||
static constexpr int HasExp = 1;
|
||||
static constexpr int HasExpm1 = 1;
|
||||
static constexpr int HasLog = 1;
|
||||
static constexpr int HasLog1p = 1;
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -690,7 +664,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pstoreu(Eigen::half* to, const half2&
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_aligned(const Eigen::half* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Input is guaranteed to be properly aligned.
|
||||
return __ldg(reinterpret_cast<const half2*>(from));
|
||||
#else
|
||||
@@ -699,7 +673,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_aligned(const Eigen::half*
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_unaligned(const Eigen::half* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
return __halves2half2(__ldg(from + 0), __ldg(from + 1));
|
||||
#else
|
||||
return __halves2half2(*(from + 0), *(from + 1));
|
||||
@@ -745,12 +719,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void ptranspose(PacketBlock<half2, 2>& ker
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plset(const Eigen::half& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __halves2half2(a, __hadd(a, __float2half(1.0f)));
|
||||
#else
|
||||
float f = __half2float(a) + 1.0f;
|
||||
return __halves2half2(a, __float2half(f));
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pselect(const half2& mask, const half2& a, const half2& b) {
|
||||
@@ -837,89 +806,21 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pandnot(const half2& a, const half2&
|
||||
return __halves2half2(result1, result2);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 padd(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hadd2(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 + b1;
|
||||
float r2 = a2 + b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 padd(const half2& a, const half2& b) { return __hadd2(a, b); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psub(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hsub2(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 - b1;
|
||||
float r2 = a2 - b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psub(const half2& a, const half2& b) { return __hsub2(a, b); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pnegate(const half2& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hneg2(a);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
return __floats2half2_rn(-a1, -a2);
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pnegate(const half2& a) { return __hneg2(a); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pconj(const half2& a) { return a; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmul(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hmul2(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 * b1;
|
||||
float r2 = a2 * b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmul(const half2& a, const half2& b) { return __hmul2(a, b); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmadd(const half2& a, const half2& b, const half2& c) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hfma2(a, b, c);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float c1 = __low2float(c);
|
||||
float c2 = __high2float(c);
|
||||
float r1 = a1 * b1 + c1;
|
||||
float r2 = a2 * b2 + c2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pdiv(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __h2div(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 / b1;
|
||||
float r2 = a2 / b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pdiv(const half2& a, const half2& b) { return __h2div(a, b); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmin(const half2& a, const half2& b) {
|
||||
float a1 = __low2float(a);
|
||||
@@ -942,47 +843,23 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmax(const half2& a, const half2& b)
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux(const half2& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hadd(__low2half(a), __high2half(a));
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
return Eigen::half(__float2half(a1 + a2));
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_max(const half2& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
__half first = __low2half(a);
|
||||
__half second = __high2half(a);
|
||||
return __hgt(first, second) ? first : second;
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
return a1 > a2 ? __low2half(a) : __high2half(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_min(const half2& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
__half first = __low2half(a);
|
||||
__half second = __high2half(a);
|
||||
return __hlt(first, second) ? first : second;
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
return a1 < a2 ? __low2half(a) : __high2half(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_mul(const half2& a) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hmul(__low2half(a), __high2half(a));
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
return Eigen::half(__float2half(a1 * a2));
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plog1p(const half2& a) {
|
||||
@@ -1001,8 +878,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexpm1(const half2& a) {
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)) || defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plog(const half2& a) { return h2log(a); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexp(const half2& a) { return h2exp(a); }
|
||||
@@ -1010,41 +885,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexp(const half2& a) { return h2exp(
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psqrt(const half2& a) { return h2sqrt(a); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 prsqrt(const half2& a) { return h2rsqrt(a); }
|
||||
|
||||
#else
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plog(const half2& a) {
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float r1 = logf(a1);
|
||||
float r2 = logf(a2);
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexp(const half2& a) {
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float r1 = expf(a1);
|
||||
float r2 = expf(a2);
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psqrt(const half2& a) {
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float r1 = sqrtf(a1);
|
||||
float r2 = sqrtf(a2);
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 prsqrt(const half2& a) {
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float r1 = rsqrtf(a1);
|
||||
float r2 = rsqrtf(a2);
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
template <>
|
||||
@@ -1091,19 +931,17 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pstoreu<Eigen::half>(Eigen::half* to,
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet4h2 ploadt_ro<Packet4h2, Aligned>(const Eigen::half* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
Packet4h2 r;
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
r = __ldg(reinterpret_cast<const Packet4h2*>(from));
|
||||
return r;
|
||||
#else
|
||||
Packet4h2 r;
|
||||
half2* r_alias = reinterpret_cast<half2*>(&r);
|
||||
r_alias[0] = ploadt_ro_aligned(from + 0);
|
||||
r_alias[1] = ploadt_ro_aligned(from + 2);
|
||||
r_alias[2] = ploadt_ro_aligned(from + 4);
|
||||
r_alias[3] = ploadt_ro_aligned(from + 6);
|
||||
return r;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -1272,7 +1110,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 plset<Packet4h2>(const Eigen::ha
|
||||
p_alias[2] = __halves2half2(__hadd(a, __float2half(4.0f)), __hadd(a, __float2half(5.0f)));
|
||||
p_alias[3] = __halves2half2(__hadd(a, __float2half(6.0f)), __hadd(a, __float2half(7.0f)));
|
||||
return r;
|
||||
#elif defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
#elif defined(EIGEN_CUDA_ARCH)
|
||||
Packet4h2 r;
|
||||
half2* r_alias = reinterpret_cast<half2*>(&r);
|
||||
|
||||
@@ -1290,16 +1128,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 plset<Packet4h2>(const Eigen::ha
|
||||
r_alias[3] = plset(__high2half(c));
|
||||
|
||||
return r;
|
||||
|
||||
#else
|
||||
float f = __half2float(a);
|
||||
Packet4h2 r;
|
||||
half2* p_alias = reinterpret_cast<half2*>(&r);
|
||||
p_alias[0] = __halves2half2(a, __float2half(f + 1.0f));
|
||||
p_alias[1] = __halves2half2(__float2half(f + 2.0f), __float2half(f + 3.0f));
|
||||
p_alias[2] = __halves2half2(__float2half(f + 4.0f), __float2half(f + 5.0f));
|
||||
p_alias[3] = __halves2half2(__float2half(f + 6.0f), __float2half(f + 7.0f));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1533,7 +1361,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_max<Packet4h2>(const Pa
|
||||
half2 m1 = __halves2half2(predux_max(a_alias[2]), predux_max(a_alias[3]));
|
||||
__half first = predux_max(m0);
|
||||
__half second = predux_max(m1);
|
||||
#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return (__hgt(first, second) ? first : second);
|
||||
#else
|
||||
float ffirst = __half2float(first);
|
||||
@@ -1549,7 +1377,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_min<Packet4h2>(const Pa
|
||||
half2 m1 = __halves2half2(predux_min(a_alias[2]), predux_min(a_alias[3]));
|
||||
__half first = predux_min(m0);
|
||||
__half second = predux_min(m1);
|
||||
#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
return (__hlt(first, second) ? first : second);
|
||||
#else
|
||||
float ffirst = __half2float(first);
|
||||
@@ -1641,47 +1469,17 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 prsqrt<Packet4h2>(const Packet4h
|
||||
// the implementation of GPU half reduction.
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 padd<half2>(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hadd2(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 + b1;
|
||||
float r2 = a2 + b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmul<half2>(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __hmul2(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 * b1;
|
||||
float r2 = a2 * b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pdiv<half2>(const half2& a, const half2& b) {
|
||||
#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
|
||||
return __h2div(a, b);
|
||||
#else
|
||||
float a1 = __low2float(a);
|
||||
float a2 = __high2float(a);
|
||||
float b1 = __low2float(b);
|
||||
float b2 = __high2float(b);
|
||||
float r1 = a1 / b1;
|
||||
float r2 = a2 / b2;
|
||||
return __floats2half2_rn(r1, r2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -1706,11 +1504,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmax<half2>(const half2& a, const ha
|
||||
return __halves2half2(r1, r2);
|
||||
}
|
||||
|
||||
#endif // (defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)) && defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
#undef EIGEN_GPU_HAS_LDG
|
||||
#undef EIGEN_CUDA_HAS_FP16_ARITHMETIC
|
||||
#undef EIGEN_GPU_HAS_FP16_ARITHMETIC
|
||||
#endif // defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
|
||||
(defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
template <>
|
||||
struct type_casting_traits<Eigen::half, float> {
|
||||
|
||||
@@ -541,12 +541,6 @@ extern "C" {
|
||||
#if defined EIGEN_CUDACC
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <vector_types.h>
|
||||
#if EIGEN_CUDA_SDK_VER >= 70500
|
||||
#define EIGEN_HAS_CUDA_FP16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HAS_CUDA_FP16)
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_fp16.h>
|
||||
#endif
|
||||
@@ -554,7 +548,6 @@ extern "C" {
|
||||
#if defined(EIGEN_HIPCC)
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <hip/hip_vector_types.h>
|
||||
#define EIGEN_HAS_HIP_FP16
|
||||
#include <hip/hip_fp16.h>
|
||||
#define EIGEN_HAS_HIP_BF16
|
||||
#include <hip/hip_bfloat16.h>
|
||||
|
||||
@@ -84,8 +84,7 @@
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__ && defined __CUDACC__
|
||||
// MSVC 14.16 (required by CUDA 9.*) does not support the _Pragma keyword, so
|
||||
// we instead use Microsoft's __pragma extension.
|
||||
// MSVC does not support the _Pragma keyword, so we use Microsoft's __pragma extension.
|
||||
#if defined _MSC_VER
|
||||
#define EIGEN_MAKE_PRAGMA(X) __pragma(#X)
|
||||
#else
|
||||
|
||||
@@ -148,13 +148,8 @@
|
||||
#endif
|
||||
|
||||
#if defined(__NVCC__)
|
||||
#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
|
||||
// CUDA 11.4+ always defines __CUDACC_VER_MAJOR__.
|
||||
#define EIGEN_COMP_NVCC ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
|
||||
#elif defined(__CUDACC_VER__)
|
||||
#define EIGEN_COMP_NVCC __CUDACC_VER__
|
||||
#else
|
||||
#error "NVCC did not define compiler version."
|
||||
#endif
|
||||
#else
|
||||
#define EIGEN_COMP_NVCC 0
|
||||
#endif
|
||||
@@ -575,6 +570,10 @@
|
||||
#define EIGEN_CUDA_SDK_VER 0
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_CUDACC) && EIGEN_CUDA_SDK_VER > 0 && EIGEN_CUDA_SDK_VER < 110400
|
||||
#error "Eigen requires CUDA 11.4 or later."
|
||||
#endif
|
||||
|
||||
#if defined(__HIPCC__) && !defined(EIGEN_NO_HIP) && !defined(__SYCL_DEVICE_ONLY__)
|
||||
// Means the compiler is HIPCC (analogous to EIGEN_CUDACC, but for HIP)
|
||||
#define EIGEN_HIPCC __HIPCC__
|
||||
@@ -584,22 +583,20 @@
|
||||
// ++ host_defines.h which contains the defines for the __host__ and __device__ macros
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
// Eigen requires ROCm/HIP >= 5.6 (GFX906 minimum architecture).
|
||||
// This floor exists to allow simplifying shared CUDA/HIP preprocessor guards —
|
||||
// all __HIP_ARCH_HAS_WARP_SHUFFLE__, __HIP_ARCH_HAS_FP16__, etc. are always true on GFX906+.
|
||||
#if defined(HIP_VERSION_MAJOR) && (HIP_VERSION_MAJOR < 5 || (HIP_VERSION_MAJOR == 5 && HIP_VERSION_MINOR < 6))
|
||||
#error "Eigen requires ROCm/HIP >= 5.6."
|
||||
#endif
|
||||
|
||||
#if defined(__HIP_DEVICE_COMPILE__) && !defined(__SYCL_DEVICE_ONLY__)
|
||||
// analogous to EIGEN_CUDA_ARCH, but for HIP
|
||||
#define EIGEN_HIP_DEVICE_COMPILE __HIP_DEVICE_COMPILE__
|
||||
#endif
|
||||
|
||||
// For HIP (ROCm 3.5 and higher), we need to explicitly set the launch_bounds attribute
|
||||
// value to 1024. The compiler assigns a default value of 256 when the attribute is not
|
||||
// specified. This results in failures on the HIP platform, for cases when a GPU kernel
|
||||
// without an explicit launch_bounds attribute is called with a threads_per_block value
|
||||
// greater than 256.
|
||||
//
|
||||
// This is a regression in functionality and is expected to be fixed within the next
|
||||
// couple of ROCm releases (compiler will go back to using 1024 value as the default)
|
||||
//
|
||||
// In the meantime, we will use a "only enabled for HIP" macro to set the launch_bounds
|
||||
// attribute.
|
||||
// HIP compilers default to launch_bounds(256), which causes failures when kernels
|
||||
// are called with more than 256 threads per block. Explicitly set to 1024 for HIP.
|
||||
|
||||
#define EIGEN_HIP_LAUNCH_BOUNDS_1024 __launch_bounds__(1024)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user