38#include "../../InternalHeaderCheck.h"
48#if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
49#define _EIGEN_MAYBE_CONSTEXPR
51#define _EIGEN_MAYBE_CONSTEXPR constexpr
54#define F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, METHOD) \
56 EIGEN_UNUSED EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC PACKET_F16 METHOD<PACKET_F16>(const PACKET_F16& _x) { \
57 return float2half(METHOD<PACKET_F>(half2float(_x))); \
85#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
89 struct construct_from_rep_tag {};
90#if (defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE))
96 EIGEN_DEVICE_FUNC __half_raw() {}
98 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw() : x(0) {}
101#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
102 explicit EIGEN_DEVICE_FUNC __half_raw(numext::uint16_t raw) : x(numext::bit_cast<__fp16>(raw)) {}
103 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, __fp16 rep) : x{rep} {}
105#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
106 explicit EIGEN_DEVICE_FUNC __half_raw(numext::uint16_t raw) : x(numext::bit_cast<_Float16>(raw)) {}
107 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, _Float16 rep) : x{rep} {}
110 explicit EIGEN_DEVICE_FUNC
constexpr __half_raw(numext::uint16_t raw) : x(raw) {}
111 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, numext::uint16_t rep) : x{rep} {}
116#elif defined(EIGEN_HAS_HIP_FP16)
119#elif defined(EIGEN_HAS_CUDA_FP16)
122#if EIGEN_CUDA_SDK_VER < 90000
124typedef __half __half_raw;
127#elif defined(SYCL_DEVICE_ONLY)
128typedef cl::sycl::half __half_raw;
131EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x);
132EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(
float ff);
133EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
float half_to_float(__half_raw h);
135struct half_base :
public __half_raw {
136 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base() {}
137 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half_raw& h) : __half_raw(h) {}
139#if defined(EIGEN_HAS_GPU_FP16)
140#if defined(EIGEN_HAS_HIP_FP16)
141 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half& h) { x = __half_as_ushort(h); }
142#elif defined(EIGEN_HAS_CUDA_FP16)
143#if EIGEN_CUDA_SDK_VER >= 90000
144 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half& h) : __half_raw(*(__half_raw*)&h) {}
153struct half :
public half_impl::half_base {
156#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
160 typedef half_impl::__half_raw __half_raw;
161#elif defined(EIGEN_HAS_HIP_FP16)
164#elif defined(EIGEN_HAS_CUDA_FP16)
168#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER < 90000
169 typedef half_impl::__half_raw __half_raw;
173 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half() {}
175 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half_raw& h) : half_impl::half_base(h) {}
177#if defined(EIGEN_HAS_GPU_FP16)
178#if defined(EIGEN_HAS_HIP_FP16)
179 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half& h) : half_impl::half_base(h) {}
180#elif defined(EIGEN_HAS_CUDA_FP16)
181#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
182 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half& h) : half_impl::half_base(h) {}
187#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
188 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(__fp16 b)
189 : half(__half_raw(__half_raw::construct_from_rep_tag(), b)) {}
190#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
191 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(_Float16 b)
192 : half(__half_raw(__half_raw::construct_from_rep_tag(), b)) {}
195 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
bool b)
196 : half_impl::half_base(half_impl::raw_uint16_to_half(b ? 0x3c00 : 0)) {}
198 explicit EIGEN_DEVICE_FUNC half(T val)
199 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(val))) {}
200 explicit EIGEN_DEVICE_FUNC half(
float f) : half_impl::half_base(half_impl::float_to_half_rtne(f)) {}
204 template <
typename RealScalar>
205 explicit EIGEN_DEVICE_FUNC half(std::complex<RealScalar> c)
206 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(c.
real()))) {}
208 EIGEN_DEVICE_FUNC
operator float()
const {
209 return half_impl::half_to_float(*
this);
212#if defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE)
213 EIGEN_DEVICE_FUNC
operator __half()
const {
224template <
typename =
void>
225struct numeric_limits_half_impl {
226 static constexpr const bool is_specialized =
true;
227 static constexpr const bool is_signed =
true;
228 static constexpr const bool is_integer =
false;
229 static constexpr const bool is_exact =
false;
230 static constexpr const bool has_infinity =
true;
231 static constexpr const bool has_quiet_NaN =
true;
232 static constexpr const bool has_signaling_NaN =
true;
233 EIGEN_DIAGNOSTICS(push)
234 EIGEN_DISABLE_DEPRECATED_WARNING
235 static constexpr const std::float_denorm_style has_denorm = std::denorm_present;
236 static constexpr const bool has_denorm_loss =
false;
237 EIGEN_DIAGNOSTICS(pop)
238 static constexpr const std::float_round_style round_style = std::round_to_nearest;
239 static constexpr const bool is_iec559 =
true;
242 static constexpr const bool is_bounded =
true;
243 static constexpr const bool is_modulo =
false;
244 static constexpr const int digits = 11;
245 static constexpr const int digits10 =
247 static constexpr const int max_digits10 =
249 static constexpr const int radix = std::numeric_limits<float>::radix;
250 static constexpr const int min_exponent = -13;
251 static constexpr const int min_exponent10 = -4;
252 static constexpr const int max_exponent = 16;
253 static constexpr const int max_exponent10 = 4;
254 static constexpr const bool traps = std::numeric_limits<float>::traps;
257 static constexpr const bool tinyness_before = std::numeric_limits<float>::tinyness_before;
259 static _EIGEN_MAYBE_CONSTEXPR Eigen::half(min)() {
return Eigen::half_impl::raw_uint16_to_half(0x0400); }
260 static _EIGEN_MAYBE_CONSTEXPR Eigen::half lowest() {
return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
261 static _EIGEN_MAYBE_CONSTEXPR Eigen::half(max)() {
return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
262 static _EIGEN_MAYBE_CONSTEXPR Eigen::half epsilon() {
return Eigen::half_impl::raw_uint16_to_half(0x1400); }
263 static _EIGEN_MAYBE_CONSTEXPR Eigen::half round_error() {
return Eigen::half_impl::raw_uint16_to_half(0x3800); }
264 static _EIGEN_MAYBE_CONSTEXPR Eigen::half infinity() {
return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
265 static _EIGEN_MAYBE_CONSTEXPR Eigen::half quiet_NaN() {
return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
266 static _EIGEN_MAYBE_CONSTEXPR Eigen::half signaling_NaN() {
return Eigen::half_impl::raw_uint16_to_half(0x7d00); }
267 static _EIGEN_MAYBE_CONSTEXPR Eigen::half denorm_min() {
return Eigen::half_impl::raw_uint16_to_half(0x0001); }
271constexpr const bool numeric_limits_half_impl<T>::is_specialized;
273constexpr const bool numeric_limits_half_impl<T>::is_signed;
275constexpr const bool numeric_limits_half_impl<T>::is_integer;
277constexpr const bool numeric_limits_half_impl<T>::is_exact;
279constexpr const bool numeric_limits_half_impl<T>::has_infinity;
281constexpr const bool numeric_limits_half_impl<T>::has_quiet_NaN;
283constexpr const bool numeric_limits_half_impl<T>::has_signaling_NaN;
284EIGEN_DIAGNOSTICS(push)
285EIGEN_DISABLE_DEPRECATED_WARNING
287constexpr const std::float_denorm_style numeric_limits_half_impl<T>::has_denorm;
289constexpr const bool numeric_limits_half_impl<T>::has_denorm_loss;
290EIGEN_DIAGNOSTICS(pop)
292constexpr const std::float_round_style numeric_limits_half_impl<T>::round_style;
294constexpr const bool numeric_limits_half_impl<T>::is_iec559;
296constexpr const bool numeric_limits_half_impl<T>::is_bounded;
298constexpr const bool numeric_limits_half_impl<T>::is_modulo;
300constexpr const int numeric_limits_half_impl<T>::digits;
302constexpr const int numeric_limits_half_impl<T>::digits10;
304constexpr const int numeric_limits_half_impl<T>::max_digits10;
306constexpr const int numeric_limits_half_impl<T>::radix;
308constexpr const int numeric_limits_half_impl<T>::min_exponent;
310constexpr const int numeric_limits_half_impl<T>::min_exponent10;
312constexpr const int numeric_limits_half_impl<T>::max_exponent;
314constexpr const int numeric_limits_half_impl<T>::max_exponent10;
316constexpr const bool numeric_limits_half_impl<T>::traps;
318constexpr const bool numeric_limits_half_impl<T>::tinyness_before;
328class numeric_limits<Eigen::half> :
public Eigen::half_impl::numeric_limits_half_impl<> {};
330class numeric_limits<const Eigen::half> :
public numeric_limits<Eigen::half> {};
332class numeric_limits<volatile Eigen::half> :
public numeric_limits<Eigen::half> {};
334class numeric_limits<const volatile Eigen::half> :
public numeric_limits<Eigen::half> {};
341#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
342 (defined(EIGEN_HAS_HIP_FP16) && defined(HIP_DEVICE_COMPILE))
345#define EIGEN_HAS_NATIVE_GPU_FP16
353#if defined(EIGEN_HAS_NATIVE_GPU_FP16)
354EIGEN_STRONG_INLINE __device__ half operator+(
const half& a,
const half& b) {
355#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
356 return __hadd(::__half(a), ::__half(b));
361EIGEN_STRONG_INLINE __device__ half operator*(
const half& a,
const half& b) {
return __hmul(a, b); }
362EIGEN_STRONG_INLINE __device__ half operator-(
const half& a,
const half& b) {
return __hsub(a, b); }
363EIGEN_STRONG_INLINE __device__ half operator/(
const half& a,
const half& b) {
364#if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
367 float num = __half2float(a);
368 float denom = __half2float(b);
369 return __float2half(num / denom);
372EIGEN_STRONG_INLINE __device__ half operator-(
const half& a) {
return __hneg(a); }
373EIGEN_STRONG_INLINE __device__ half& operator+=(half& a,
const half& b) {
377EIGEN_STRONG_INLINE __device__ half& operator*=(half& a,
const half& b) {
381EIGEN_STRONG_INLINE __device__ half& operator-=(half& a,
const half& b) {
385EIGEN_STRONG_INLINE __device__ half& operator/=(half& a,
const half& b) {
389EIGEN_STRONG_INLINE __device__
bool operator==(
const half& a,
const half& b) {
return __heq(a, b); }
390EIGEN_STRONG_INLINE __device__
bool operator!=(
const half& a,
const half& b) {
return __hne(a, b); }
391EIGEN_STRONG_INLINE __device__
bool operator<(
const half& a,
const half& b) {
return __hlt(a, b); }
392EIGEN_STRONG_INLINE __device__
bool operator<=(
const half& a,
const half& b) {
return __hle(a, b); }
393EIGEN_STRONG_INLINE __device__
bool operator>(
const half& a,
const half& b) {
return __hgt(a, b); }
394EIGEN_STRONG_INLINE __device__
bool operator>=(
const half& a,
const half& b) {
return __hge(a, b); }
398#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) && !defined(EIGEN_GPU_COMPILE_PHASE)
399EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
return half(vaddh_f16(a.x, b.x)); }
400EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
return half(vmulh_f16(a.x, b.x)); }
401EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
return half(vsubh_f16(a.x, b.x)); }
402EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
return half(vdivh_f16(a.x, b.x)); }
403EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
return half(vnegh_f16(a.x)); }
404EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
405 a = half(vaddh_f16(a.x, b.x));
408EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
409 a = half(vmulh_f16(a.x, b.x));
412EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
413 a = half(vsubh_f16(a.x, b.x));
416EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
417 a = half(vdivh_f16(a.x, b.x));
420EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
return vceqh_f16(a.x, b.x); }
421EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return !vceqh_f16(a.x, b.x); }
422EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
return vclth_f16(a.x, b.x); }
423EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
return vcleh_f16(a.x, b.x); }
424EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
return vcgth_f16(a.x, b.x); }
425EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
return vcgeh_f16(a.x, b.x); }
427#elif defined(EIGEN_HAS_BUILTIN_FLOAT16) && !defined(EIGEN_GPU_COMPILE_PHASE)
429EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
return half(a.x + b.x); }
430EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
return half(a.x * b.x); }
431EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
return half(a.x - b.x); }
432EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
return half(a.x / b.x); }
433EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
return half(-a.x); }
434EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
438EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
442EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
446EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
450EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
return a.x == b.x; }
451EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return a.x != b.x; }
452EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
return a.x < b.x; }
453EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
return a.x <= b.x; }
454EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
return a.x > b.x; }
455EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
return a.x >= b.x; }
460#elif !defined(EIGEN_HAS_NATIVE_GPU_FP16) || (EIGEN_COMP_CLANG && !EIGEN_COMP_NVCC)
462#if EIGEN_COMP_CLANG && defined(EIGEN_GPUCC)
464#pragma push_macro("EIGEN_DEVICE_FUNC")
465#undef EIGEN_DEVICE_FUNC
466#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_HAS_NATIVE_GPU_FP16)
467#define EIGEN_DEVICE_FUNC __host__
469#define EIGEN_DEVICE_FUNC __host__ __device__
475EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
return half(
float(a) +
float(b)); }
476EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
return half(
float(a) *
float(b)); }
477EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
return half(
float(a) -
float(b)); }
478EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
return half(
float(a) /
float(b)); }
479EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
481 result.x = a.x ^ 0x8000;
484EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
485 a = half(
float(a) +
float(b));
488EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
489 a = half(
float(a) *
float(b));
492EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
493 a = half(
float(a) -
float(b));
496EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
497 a = half(
float(a) /
float(b));
514EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC int16_t mapToSigned(uint16_t a) {
515 constexpr uint16_t kAbsMask = (1 << 15) - 1;
517 return (a >> 15) ? -(a & kAbsMask) : a;
519EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool isOrdered(
const half& a,
const half& b) {
520 constexpr uint16_t kInf = ((1 << 5) - 1) << 10;
521 constexpr uint16_t kAbsMask = (1 << 15) - 1;
522 return numext::maxi(a.x & kAbsMask, b.x & kAbsMask) <= kInf;
524EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
525 bool result = mapToSigned(a.x) == mapToSigned(b.x);
526 result &= isOrdered(a, b);
529EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return !(a == b); }
530EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
531 bool result = mapToSigned(a.x) < mapToSigned(b.x);
532 result &= isOrdered(a, b);
535EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
536 bool result = mapToSigned(a.x) <= mapToSigned(b.x);
537 result &= isOrdered(a, b);
540EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
541 bool result = mapToSigned(a.x) > mapToSigned(b.x);
542 result &= isOrdered(a, b);
545EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
546 bool result = mapToSigned(a.x) >= mapToSigned(b.x);
547 result &= isOrdered(a, b);
551#if EIGEN_COMP_CLANG && defined(EIGEN_GPUCC)
552#pragma pop_macro("EIGEN_DEVICE_FUNC")
559EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
Index b) {
560 return half(
static_cast<float>(a) /
static_cast<float>(b));
563EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a) {
568EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a) {
573EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a,
int) {
574 half original_value = a;
576 return original_value;
579EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a,
int) {
580 half original_value = a;
582 return original_value;
590EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x) {
597#if defined(EIGEN_HAS_GPU_FP16)
602 return __half_raw(x);
606EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC numext::uint16_t raw_half_as_uint16(
const __half_raw& h) {
610#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
611 return numext::bit_cast<numext::uint16_t>(h.x);
612#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
613 return numext::bit_cast<numext::uint16_t>(h.x);
614#elif defined(SYCL_DEVICE_ONLY)
615 return numext::bit_cast<numext::uint16_t>(h);
621EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(
float ff) {
622#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
623 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
624 __half tmp_ff = __float2half(ff);
625 return *(__half_raw*)&tmp_ff;
627#elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
629 h.x =
static_cast<__fp16
>(ff);
632#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
634 h.x =
static_cast<_Float16
>(ff);
637#elif defined(EIGEN_HAS_FP16_C)
641 h.x = _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(ff), 0), 0);
643 h.x = _cvtss_sh(ff, 0);
648 uint32_t f_bits = Eigen::numext::bit_cast<uint32_t>(ff);
649 const uint32_t f32infty_bits = {255 << 23};
650 const uint32_t f16max_bits = {(127 + 16) << 23};
651 const uint32_t denorm_magic_bits = {((127 - 15) + (23 - 10) + 1) << 23};
652 const uint32_t sign_mask = 0x80000000u;
654 o.x =
static_cast<uint16_t
>(0x0u);
656 const uint32_t
sign = f_bits & sign_mask;
664 if (f_bits >= f16max_bits) {
665 o.x = (f_bits > f32infty_bits) ? 0x7e00 : 0x7c00;
667 if (f_bits < (113 << 23)) {
671 f_bits = Eigen::numext::bit_cast<uint32_t>(Eigen::numext::bit_cast<float>(f_bits) +
672 Eigen::numext::bit_cast<float>(denorm_magic_bits));
675 o.x =
static_cast<numext::uint16_t
>(f_bits - denorm_magic_bits);
677 const uint32_t mant_odd = (f_bits >> 13) & 1;
682 f_bits += 0xc8000fffU;
686 o.x =
static_cast<numext::uint16_t
>(f_bits >> 13);
690 o.x |=
static_cast<numext::uint16_t
>(
sign >> 16);
695EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
float half_to_float(__half_raw h) {
696#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
697 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
698 return __half2float(h);
699#elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
700 return static_cast<float>(h.x);
701#elif defined(EIGEN_HAS_FP16_C)
704 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_set1_epi16(h.x)));
706 return _cvtsh_ss(h.x);
709 const float magic = Eigen::numext::bit_cast<float>(
static_cast<uint32_t
>(113 << 23));
710 const uint32_t shifted_exp = 0x7c00 << 13;
711 uint32_t o_bits = (h.x & 0x7fff) << 13;
712 const uint32_t exp = shifted_exp & o_bits;
713 o_bits += (127 - 15) << 23;
716 if (exp == shifted_exp) {
717 o_bits += (128 - 16) << 23;
718 }
else if (exp == 0) {
721 o_bits = Eigen::numext::bit_cast<uint32_t>(Eigen::numext::bit_cast<float>(o_bits) - magic);
724 o_bits |= (h.x & 0x8000) << 16;
725 return Eigen::numext::bit_cast<float>(o_bits);
731EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isinf)(
const half& a) {
732#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
733 return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) == 0x7c00;
735 return (a.x & 0x7fff) == 0x7c00;
738EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isnan)(
const half& a) {
739#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
740 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
742#elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
743 return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) > 0x7c00;
745 return (a.x & 0x7fff) > 0x7c00;
748EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isfinite)(
const half& a) {
749#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) || defined(EIGEN_HAS_BUILTIN_FLOAT16)
750 return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) < 0x7c00;
752 return (a.x & 0x7fff) < 0x7c00;
756EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(
const half& a) {
757#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
758 return half(vabsh_f16(a.x));
759#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
762 numext::bit_cast<_Float16>(
static_cast<numext::uint16_t
>(numext::bit_cast<numext::uint16_t>(a.x) & 0x7FFF));
766 result.x = a.x & 0x7FFF;
770EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(
const half& a) {
771#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
772 defined(EIGEN_HIP_DEVICE_COMPILE)
773 return half(hexp(a));
775 return half(::expf(
float(a)));
778EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp2(
const half& a) {
779#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
780 defined(EIGEN_HIP_DEVICE_COMPILE)
781 return half(hexp2(a));
783 return half(::exp2f(
float(a)));
786EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(
const half& a) {
return half(numext::expm1(
float(a))); }
787EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(
const half& a) {
788#if (defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && \
789 EIGEN_CUDA_ARCH >= 530) || \
790 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
791 return half(hlog(a));
793 return half(::logf(
float(a)));
796EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log1p(
const half& a) {
return half(numext::log1p(
float(a))); }
797EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(
const half& a) {
return half(::log10f(
float(a))); }
798EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log2(
const half& a) {
799 return half(
static_cast<float>(EIGEN_LOG2E) * ::logf(
float(a)));
802EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(
const half& a) {
803#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
804 defined(EIGEN_HIP_DEVICE_COMPILE)
805 return half(hsqrt(a));
807 return half(::sqrtf(
float(a)));
810EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(
const half& a,
const half& b) {
811 return half(::powf(
float(a),
float(b)));
813EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atan2(
const half& a,
const half& b) {
814 return half(::atan2f(
float(a),
float(b)));
816EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sin(
const half& a) {
return half(::sinf(
float(a))); }
817EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half cos(
const half& a) {
return half(::cosf(
float(a))); }
818EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tan(
const half& a) {
return half(::tanf(
float(a))); }
819EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(
const half& a) {
return half(::tanhf(
float(a))); }
820EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half asin(
const half& a) {
return half(::asinf(
float(a))); }
821EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half acos(
const half& a) {
return half(::acosf(
float(a))); }
822EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atan(
const half& a) {
return half(::atanf(
float(a))); }
823EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atanh(
const half& a) {
return half(::atanhf(
float(a))); }
824EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(
const half& a) {
825#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
826 defined(EIGEN_HIP_DEVICE_COMPILE)
827 return half(hfloor(a));
829 return half(::floorf(
float(a)));
832EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(
const half& a) {
833#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
834 defined(EIGEN_HIP_DEVICE_COMPILE)
835 return half(hceil(a));
837 return half(::ceilf(
float(a)));
840EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half rint(
const half& a) {
return half(::rintf(
float(a))); }
841EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half round(
const half& a) {
return half(::roundf(
float(a))); }
842EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half trunc(
const half& a) {
return half(::truncf(
float(a))); }
843EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half fmod(
const half& a,
const half& b) {
844 return half(::fmodf(
float(a),
float(b)));
847EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half(min)(
const half& a,
const half& b) {
return b < a ? b : a; }
849EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half(max)(
const half& a,
const half& b) {
return a < b ? b : a; }
851EIGEN_DEVICE_FUNC
inline half fma(
const half& a,
const half& b,
const half& c) {
852#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
853 return half(vfmah_f16(c.x, a.x, b.x));
854#elif defined(EIGEN_VECTORIZE_AVX512FP16)
856 return half(_mm_cvtsh_h(_mm_fmadd_ph(_mm_set_sh(a.x), _mm_set_sh(b.x), _mm_set_sh(c.x))));
859 return half(numext::fma(
static_cast<float>(a),
static_cast<float>(b),
static_cast<float>(c)));
864EIGEN_ALWAYS_INLINE std::ostream& operator<<(std::ostream& os,
const half& v) {
865 os << static_cast<float>(v);
878struct is_arithmetic<half> {
879 enum { value =
true };
883struct random_impl<half> {
884 enum :
int { MantissaBits = 10 };
885 using Impl = random_impl<float>;
886 static EIGEN_DEVICE_FUNC
inline half run(
const half& x,
const half& y) {
887 float result = Impl::run(x, y, MantissaBits);
890 static EIGEN_DEVICE_FUNC
inline half run() {
891 float result = Impl::run(MantissaBits);
899struct NumTraits<Eigen::half> : GenericNumTraits<Eigen::half> {
900 enum { IsSigned =
true, IsInteger =
false, IsComplex =
false, RequireInitialization =
false };
902 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half epsilon() {
903 return half_impl::raw_uint16_to_half(0x0800);
905 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half dummy_precision() {
906 return half_impl::raw_uint16_to_half(0x211f);
908 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half highest() {
909 return half_impl::raw_uint16_to_half(0x7bff);
911 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half lowest() {
912 return half_impl::raw_uint16_to_half(0xfbff);
914 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half infinity() {
915 return half_impl::raw_uint16_to_half(0x7c00);
917 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half quiet_NaN() {
918 return half_impl::raw_uint16_to_half(0x7e00);
924#undef _EIGEN_MAYBE_CONSTEXPR
929#if defined(EIGEN_GPU_COMPILE_PHASE)
932EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isnan)(
const Eigen::half& h) {
933 return (half_impl::isnan)(h);
937EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isinf)(
const Eigen::half& h) {
938 return (half_impl::isinf)(h);
942EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isfinite)(
const Eigen::half& h) {
943 return (half_impl::isfinite)(h);
949EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half bit_cast<Eigen::half, uint16_t>(
const uint16_t& src) {
950 return Eigen::half(Eigen::half_impl::raw_uint16_to_half(src));
954EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC uint16_t bit_cast<uint16_t, Eigen::half>(
const Eigen::half& src) {
955 return Eigen::half_impl::raw_half_as_uint16(src);
960EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half madd<Eigen::half>(
const Eigen::half& x,
const Eigen::half& y,
const Eigen::half& z) {
961 return Eigen::half(
static_cast<float>(x) *
static_cast<float>(y) +
static_cast<float>(z));
978#if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 300)) || defined(EIGEN_HIPCC)
980#if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 90000
982__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_sync(
unsigned mask, Eigen::half var,
int srcLane,
983 int width = warpSize) {
984 const __half h = var;
985 return static_cast<Eigen::half
>(__shfl_sync(mask, h, srcLane, width));
988__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up_sync(
unsigned mask, Eigen::half var,
unsigned int delta,
989 int width = warpSize) {
990 const __half h = var;
991 return static_cast<Eigen::half
>(__shfl_up_sync(mask, h, delta, width));
994__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down_sync(
unsigned mask, Eigen::half var,
unsigned int delta,
995 int width = warpSize) {
996 const __half h = var;
997 return static_cast<Eigen::half
>(__shfl_down_sync(mask, h, delta, width));
1000__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor_sync(
unsigned mask, Eigen::half var,
int laneMask,
1001 int width = warpSize) {
1002 const __half h = var;
1003 return static_cast<Eigen::half
>(__shfl_xor_sync(mask, h, laneMask, width));
1008__device__ EIGEN_STRONG_INLINE Eigen::half __shfl(Eigen::half var,
int srcLane,
int width = warpSize) {
1009 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1010 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl(ivar, srcLane, width)));
1013__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up(Eigen::half var,
unsigned int delta,
int width = warpSize) {
1014 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1015 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_up(ivar, delta, width)));
1018__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down(Eigen::half var,
unsigned int delta,
int width = warpSize) {
1019 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1020 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_down(ivar, delta, width)));
1023__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor(Eigen::half var,
int laneMask,
int width = warpSize) {
1024 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1025 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_xor(ivar, laneMask, width)));
1032#if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 350)) || defined(EIGEN_HIPCC)
1033EIGEN_STRONG_INLINE __device__ Eigen::half __ldg(
const Eigen::half* ptr) {
1034 return Eigen::half_impl::raw_uint16_to_half(__ldg(
reinterpret_cast<const Eigen::numext::uint16_t*
>(ptr)));
1038#if EIGEN_HAS_STD_HASH
1041struct hash<Eigen::half> {
1042 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(
const Eigen::half& a)
const {
1043 return static_cast<std::size_t
>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(a));
1053struct cast_impl<float, half> {
1054 EIGEN_DEVICE_FUNC
static inline half run(
const float& a) {
1055#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
1056 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
1057 return __float2half(a);
1065struct cast_impl<int, half> {
1066 EIGEN_DEVICE_FUNC
static inline half run(
const int& a) {
1067#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
1068 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
1069 return __float2half(
static_cast<float>(a));
1071 return half(
static_cast<float>(a));
1077struct cast_impl<half, float> {
1078 EIGEN_DEVICE_FUNC
static inline float run(
const half& a) {
1079#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
1080 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
1081 return __half2float(a);
1083 return static_cast<float>(a);
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sign_op< typename Derived::Scalar >, const Derived > sign(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition NumTraits.h:232