39#include "../../InternalHeaderCheck.h"
49#if defined(EIGEN_HAS_GPU_FP16) || EIGEN_HAS_ARM64_FP16 || defined(EIGEN_HAS_BUILTIN_FLOAT16)
50#define _EIGEN_MAYBE_CONSTEXPR
52#define _EIGEN_MAYBE_CONSTEXPR constexpr
55#define F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, METHOD) \
57 EIGEN_UNUSED EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC PACKET_F16 METHOD<PACKET_F16>(const PACKET_F16& _x) { \
58 return float2half(METHOD<PACKET_F>(half2float(_x))); \
61#define EIGEN_INSTANTIATE_GENERIC_MATH_FUNCS_F16(PACKET_F, PACKET_F16) \
62 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pcos) \
63 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, psin) \
64 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, psinh) \
65 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pcosh) \
66 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pasinh) \
67 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pacosh) \
68 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pexp) \
69 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pexp2) \
70 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pexpm1) \
71 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, plog) \
72 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, plog1p) \
73 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, plog2) \
74 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, plog10) \
75 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, preciprocal) \
76 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, prsqrt) \
77 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pcbrt) \
78 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, psqrt) \
79 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, ptanh)
82#define EIGEN_INSTANTIATE_SPECIAL_FUNCS_F16(PACKET_F, PACKET_F16) \
83 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, perf) \
84 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pndtri)
86#define EIGEN_INSTANTIATE_BESSEL_FUNCS_F16(PACKET_F, PACKET_F16) \
87 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_i0) \
88 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_i0e) \
89 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_i1) \
90 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_i1e) \
91 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_j0) \
92 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_j1) \
93 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_k0) \
94 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_k0e) \
95 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_k1) \
96 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_k1e) \
97 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_y0) \
98 F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, pbessel_y1)
125#if !defined(EIGEN_GPUCC) || !defined(EIGEN_GPU_COMPILE_PHASE)
129 struct construct_from_rep_tag {};
130#if (defined(EIGEN_GPUCC) && !defined(EIGEN_GPU_COMPILE_PHASE))
136 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw() {}
138 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw() : x(0) {}
141#if EIGEN_HAS_ARM64_FP16
142 explicit EIGEN_DEVICE_FUNC __half_raw(numext::uint16_t raw) : x(numext::bit_cast<__fp16>(raw)) {}
143 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, __fp16 rep) : x{rep} {}
145#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
146 explicit EIGEN_DEVICE_FUNC __half_raw(numext::uint16_t raw) : x(numext::bit_cast<_Float16>(raw)) {}
147 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, _Float16 rep) : x{rep} {}
150 explicit EIGEN_DEVICE_FUNC
constexpr __half_raw(numext::uint16_t raw) : x(raw) {}
151 EIGEN_DEVICE_FUNC
constexpr __half_raw(construct_from_rep_tag, numext::uint16_t rep) : x{rep} {}
156#elif defined(EIGEN_HIPCC)
159#elif defined(EIGEN_CUDACC)
163#elif defined(SYCL_DEVICE_ONLY)
164using __half_raw = cl::sycl::half;
167EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x);
168EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC numext::uint16_t raw_half_as_uint16(
const __half_raw& h);
169EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(
float ff);
170EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
float half_to_float(__half_raw h);
172struct half_base :
public __half_raw {
173 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base() {}
174 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half_raw& h) : __half_raw(h) {}
176#if defined(EIGEN_GPUCC)
177#if defined(EIGEN_HIPCC)
183 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half& h)
184 : __half_raw(raw_uint16_to_half(numext::bit_cast<numext::uint16_t>(h))) {}
185#elif defined(EIGEN_CUDACC)
186 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half_base(
const __half& h) : __half_raw(*(__half_raw*)&h) {}
194struct half :
public half_impl::half_base {
197#if !defined(EIGEN_GPUCC) || !defined(EIGEN_GPU_COMPILE_PHASE)
201 using __half_raw = half_impl::__half_raw;
202#elif defined(EIGEN_HIPCC)
205#elif defined(EIGEN_CUDACC)
209 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half() {}
211 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half_raw& h) : half_impl::half_base(h) {}
213#if defined(EIGEN_GPUCC)
214#if defined(EIGEN_HIPCC)
215 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half& h) : half_impl::half_base(h) {}
216#elif defined(EIGEN_CUDACC)
217 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
const __half& h) : half_impl::half_base(h) {}
223#if EIGEN_HAS_ARM64_FP16 && !defined(EIGEN_GPU_COMPILE_PHASE)
224 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(__fp16 b)
225 : half(__half_raw(__half_raw::construct_from_rep_tag(), b)) {}
226#elif defined(EIGEN_HAS_BUILTIN_FLOAT16) && !defined(EIGEN_GPU_COMPILE_PHASE)
227 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(_Float16 b)
228 : half(__half_raw(__half_raw::construct_from_rep_tag(), b)) {}
231 explicit EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR half(
bool b)
232 : half_impl::half_base(half_impl::raw_uint16_to_half(b ? 0x3c00 : 0)) {}
234 explicit EIGEN_DEVICE_FUNC half(T val)
235 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(val))) {}
236 explicit EIGEN_DEVICE_FUNC half(
float f) : half_impl::half_base(half_impl::float_to_half_rtne(f)) {}
240 template <
typename RealScalar>
241 explicit EIGEN_DEVICE_FUNC half(std::complex<RealScalar> c)
242 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(c.real()))) {}
244 EIGEN_DEVICE_FUNC
operator float()
const {
245 return half_impl::half_to_float(*
this);
248#if defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE)
249 EIGEN_DEVICE_FUNC
operator __half()
const {
254 hr.x = half_impl::raw_half_as_uint16(*
this);
263template <
typename =
void>
264struct numeric_limits_half_impl {
265 static constexpr const bool is_specialized =
true;
266 static constexpr const bool is_signed =
true;
267 static constexpr const bool is_integer =
false;
268 static constexpr const bool is_exact =
false;
269 static constexpr const bool has_infinity =
true;
270 static constexpr const bool has_quiet_NaN =
true;
271 static constexpr const bool has_signaling_NaN =
true;
272 EIGEN_DIAGNOSTICS(push)
273 EIGEN_DISABLE_DEPRECATED_WARNING
274 static constexpr const std::float_denorm_style has_denorm = std::denorm_present;
275 static constexpr const bool has_denorm_loss =
false;
276 EIGEN_DIAGNOSTICS(pop)
277 static constexpr const std::float_round_style round_style = std::round_to_nearest;
278 static constexpr const bool is_iec559 =
true;
281 static constexpr const bool is_bounded =
true;
282 static constexpr const bool is_modulo =
false;
283 static constexpr const int digits = 11;
284 static constexpr const int digits10 =
286 static constexpr const int max_digits10 =
288 static constexpr const int radix = std::numeric_limits<float>::radix;
289 static constexpr const int min_exponent = -13;
290 static constexpr const int min_exponent10 = -4;
291 static constexpr const int max_exponent = 16;
292 static constexpr const int max_exponent10 = 4;
293 static constexpr const bool traps = std::numeric_limits<float>::traps;
296 static constexpr const bool tinyness_before = std::numeric_limits<float>::tinyness_before;
298 static _EIGEN_MAYBE_CONSTEXPR Eigen::half(min)() {
return Eigen::half_impl::raw_uint16_to_half(0x0400); }
299 static _EIGEN_MAYBE_CONSTEXPR Eigen::half lowest() {
return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
300 static _EIGEN_MAYBE_CONSTEXPR Eigen::half(max)() {
return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
301 static _EIGEN_MAYBE_CONSTEXPR Eigen::half epsilon() {
return Eigen::half_impl::raw_uint16_to_half(0x1400); }
302 static _EIGEN_MAYBE_CONSTEXPR Eigen::half round_error() {
return Eigen::half_impl::raw_uint16_to_half(0x3800); }
303 static _EIGEN_MAYBE_CONSTEXPR Eigen::half infinity() {
return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
304 static _EIGEN_MAYBE_CONSTEXPR Eigen::half quiet_NaN() {
return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
305 static _EIGEN_MAYBE_CONSTEXPR Eigen::half signaling_NaN() {
return Eigen::half_impl::raw_uint16_to_half(0x7d00); }
306 static _EIGEN_MAYBE_CONSTEXPR Eigen::half denorm_min() {
return Eigen::half_impl::raw_uint16_to_half(0x0001); }
310#if EIGEN_COMP_CXXVER < 17
312constexpr const bool numeric_limits_half_impl<T>::is_specialized;
314constexpr const bool numeric_limits_half_impl<T>::is_signed;
316constexpr const bool numeric_limits_half_impl<T>::is_integer;
318constexpr const bool numeric_limits_half_impl<T>::is_exact;
320constexpr const bool numeric_limits_half_impl<T>::has_infinity;
322constexpr const bool numeric_limits_half_impl<T>::has_quiet_NaN;
324constexpr const bool numeric_limits_half_impl<T>::has_signaling_NaN;
325EIGEN_DIAGNOSTICS(push)
326EIGEN_DISABLE_DEPRECATED_WARNING
328constexpr const std::float_denorm_style numeric_limits_half_impl<T>::has_denorm;
330constexpr const bool numeric_limits_half_impl<T>::has_denorm_loss;
331EIGEN_DIAGNOSTICS(pop)
333constexpr const std::float_round_style numeric_limits_half_impl<T>::round_style;
335constexpr const bool numeric_limits_half_impl<T>::is_iec559;
337constexpr const bool numeric_limits_half_impl<T>::is_bounded;
339constexpr const bool numeric_limits_half_impl<T>::is_modulo;
341constexpr const int numeric_limits_half_impl<T>::digits;
343constexpr const int numeric_limits_half_impl<T>::digits10;
345constexpr const int numeric_limits_half_impl<T>::max_digits10;
347constexpr const int numeric_limits_half_impl<T>::radix;
349constexpr const int numeric_limits_half_impl<T>::min_exponent;
351constexpr const int numeric_limits_half_impl<T>::min_exponent10;
353constexpr const int numeric_limits_half_impl<T>::max_exponent;
355constexpr const int numeric_limits_half_impl<T>::max_exponent10;
357constexpr const bool numeric_limits_half_impl<T>::traps;
359constexpr const bool numeric_limits_half_impl<T>::tinyness_before;
370class numeric_limits<Eigen::half> :
public Eigen::half_impl::numeric_limits_half_impl<> {};
372class numeric_limits<const Eigen::half> :
public numeric_limits<Eigen::half> {};
374class numeric_limits<volatile Eigen::half> :
public numeric_limits<Eigen::half> {};
376class numeric_limits<const volatile Eigen::half> :
public numeric_limits<Eigen::half> {};
383#if defined(EIGEN_GPU_COMPILE_PHASE)
386#define EIGEN_HAS_NATIVE_GPU_FP16
394#if defined(EIGEN_HAS_NATIVE_GPU_FP16)
395EIGEN_STRONG_INLINE __device__ half operator+(
const half& a,
const half& b) {
return __hadd(::__half(a), ::__half(b)); }
396EIGEN_STRONG_INLINE __device__ half operator*(
const half& a,
const half& b) {
return __hmul(a, b); }
397EIGEN_STRONG_INLINE __device__ half operator-(
const half& a,
const half& b) {
return __hsub(a, b); }
398EIGEN_STRONG_INLINE __device__ half operator/(
const half& a,
const half& b) {
return __hdiv(a, b); }
399EIGEN_STRONG_INLINE __device__ half operator-(
const half& a) {
return __hneg(a); }
400EIGEN_STRONG_INLINE __device__ half& operator+=(half& a,
const half& b) {
404EIGEN_STRONG_INLINE __device__ half& operator*=(half& a,
const half& b) {
408EIGEN_STRONG_INLINE __device__ half& operator-=(half& a,
const half& b) {
412EIGEN_STRONG_INLINE __device__ half& operator/=(half& a,
const half& b) {
416EIGEN_STRONG_INLINE __device__
bool operator==(
const half& a,
const half& b) {
return __heq(a, b); }
417EIGEN_STRONG_INLINE __device__
bool operator!=(
const half& a,
const half& b) {
return __hne(a, b); }
418EIGEN_STRONG_INLINE __device__
bool operator<(
const half& a,
const half& b) {
return __hlt(a, b); }
419EIGEN_STRONG_INLINE __device__
bool operator<=(
const half& a,
const half& b) {
return __hle(a, b); }
420EIGEN_STRONG_INLINE __device__
bool operator>(
const half& a,
const half& b) {
return __hgt(a, b); }
421EIGEN_STRONG_INLINE __device__
bool operator>=(
const half& a,
const half& b) {
return __hge(a, b); }
425#if (EIGEN_HAS_ARM64_FP16 || defined(EIGEN_HAS_BUILTIN_FLOAT16)) && !defined(EIGEN_GPU_COMPILE_PHASE)
431EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half half_from_rep(
decltype(__half_raw::x) rep) {
432 return half(__half_raw(__half_raw::construct_from_rep_tag(), rep));
436#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC) && !defined(EIGEN_GPU_COMPILE_PHASE)
437EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
438 return half_from_rep(vaddh_f16(a.x, b.x));
440EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
441 return half_from_rep(vmulh_f16(a.x, b.x));
443EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
444 return half_from_rep(vsubh_f16(a.x, b.x));
446EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
447 return half_from_rep(vdivh_f16(a.x, b.x));
449EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
return half_from_rep(vnegh_f16(a.x)); }
450EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
451 a = half_from_rep(vaddh_f16(a.x, b.x));
454EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
455 a = half_from_rep(vmulh_f16(a.x, b.x));
458EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
459 a = half_from_rep(vsubh_f16(a.x, b.x));
462EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
463 a = half_from_rep(vdivh_f16(a.x, b.x));
466EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
return vceqh_f16(a.x, b.x); }
467EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return !vceqh_f16(a.x, b.x); }
468EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
return vclth_f16(a.x, b.x); }
469EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
return vcleh_f16(a.x, b.x); }
470EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
return vcgth_f16(a.x, b.x); }
471EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
return vcgeh_f16(a.x, b.x); }
473#elif (EIGEN_HAS_ARM64_FP16 || defined(EIGEN_HAS_BUILTIN_FLOAT16)) && !defined(EIGEN_GPU_COMPILE_PHASE)
481#pragma clang diagnostic push
482#pragma clang diagnostic ignored "-Wdouble-promotion"
485EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
486 return half_from_rep(
static_cast<decltype(a.x)
>(a.x + b.x));
488EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
489 return half_from_rep(
static_cast<decltype(a.x)
>(a.x * b.x));
491EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
492 return half_from_rep(
static_cast<decltype(a.x)
>(a.x - b.x));
494EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
495 return half_from_rep(
static_cast<decltype(a.x)
>(a.x / b.x));
497EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
498 return half_from_rep(
static_cast<decltype(a.x)
>(-a.x));
500EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
504EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
508EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
512EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
516EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
return a.x == b.x; }
517EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return a.x != b.x; }
518EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
return a.x < b.x; }
519EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
return a.x <= b.x; }
520EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
return a.x > b.x; }
521EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
return a.x >= b.x; }
524#pragma clang diagnostic pop
530#elif !defined(EIGEN_HAS_NATIVE_GPU_FP16) || (EIGEN_COMP_CLANG && !EIGEN_COMP_NVCC)
532#if EIGEN_COMP_CLANG && defined(EIGEN_GPUCC)
534#pragma push_macro("EIGEN_DEVICE_FUNC")
535#undef EIGEN_DEVICE_FUNC
536#if defined(EIGEN_GPUCC) && defined(EIGEN_HAS_NATIVE_GPU_FP16)
537#define EIGEN_DEVICE_FUNC __host__
539#define EIGEN_DEVICE_FUNC __host__ __device__
545EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator+(
const half& a,
const half& b) {
return half(
float(a) +
float(b)); }
546EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator*(
const half& a,
const half& b) {
return half(
float(a) *
float(b)); }
547EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a,
const half& b) {
return half(
float(a) -
float(b)); }
548EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a,
const half& b) {
return half(
float(a) /
float(b)); }
549EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator-(
const half& a) {
550 return raw_uint16_to_half(
static_cast<numext::uint16_t
>(raw_half_as_uint16(a) ^ 0x8000));
552EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator+=(half& a,
const half& b) {
553 a = half(
float(a) +
float(b));
556EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator*=(half& a,
const half& b) {
557 a = half(
float(a) *
float(b));
560EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator-=(half& a,
const half& b) {
561 a = half(
float(a) -
float(b));
564EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator/=(half& a,
const half& b) {
565 a = half(
float(a) /
float(b));
582EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC int16_t mapToSigned(uint16_t a) {
585 EIGEN_OPTIMIZATION_BARRIER(a)
587 constexpr uint16_t kAbsMask = (1 << 15) - 1;
589 return (a >> 15) ? -(a & kAbsMask) : a;
591EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool isOrdered(
const half& a,
const half& b) {
592 constexpr uint16_t kInf = ((1 << 5) - 1) << 10;
593 constexpr uint16_t kAbsMask = (1 << 15) - 1;
594 return numext::maxi(a.x & kAbsMask, b.x & kAbsMask) <= kInf;
596EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator==(
const half& a,
const half& b) {
597 bool result = mapToSigned(a.x) == mapToSigned(b.x);
598 result &= isOrdered(a, b);
601EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator!=(
const half& a,
const half& b) {
return !(a == b); }
602EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<(
const half& a,
const half& b) {
603 bool result = mapToSigned(a.x) < mapToSigned(b.x);
604 result &= isOrdered(a, b);
607EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator<=(
const half& a,
const half& b) {
608 bool result = mapToSigned(a.x) <= mapToSigned(b.x);
609 result &= isOrdered(a, b);
612EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>(
const half& a,
const half& b) {
613 bool result = mapToSigned(a.x) > mapToSigned(b.x);
614 result &= isOrdered(a, b);
617EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
bool operator>=(
const half& a,
const half& b) {
618 bool result = mapToSigned(a.x) >= mapToSigned(b.x);
619 result &= isOrdered(a, b);
623#if EIGEN_COMP_CLANG && defined(EIGEN_GPUCC)
624#pragma pop_macro("EIGEN_DEVICE_FUNC")
631EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator/(
const half& a, Index b) {
632 return half(
static_cast<float>(a) /
static_cast<float>(b));
635EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a) {
640EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a) {
645EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a,
int) {
646 half original_value = a;
648 return original_value;
651EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a,
int) {
652 half original_value = a;
654 return original_value;
662EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x) {
673#if defined(EIGEN_GPUCC) && defined(EIGEN_GPU_COMPILE_PHASE)
678 return __half_raw(x);
682EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC numext::uint16_t raw_half_as_uint16(
const __half_raw& h) {
686#if EIGEN_HAS_ARM64_FP16
687 return numext::bit_cast<numext::uint16_t>(h.x);
688#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
689 return numext::bit_cast<numext::uint16_t>(h.x);
690#elif defined(SYCL_DEVICE_ONLY)
691 return numext::bit_cast<numext::uint16_t>(h);
697EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(
float ff) {
698#if defined(EIGEN_GPU_COMPILE_PHASE)
699 __half tmp_ff = __float2half(ff);
700 return *(__half_raw*)&tmp_ff;
702#elif EIGEN_HAS_ARM64_FP16
704 h.x =
static_cast<__fp16
>(ff);
707#elif defined(EIGEN_HAS_BUILTIN_FLOAT16)
709 h.x =
static_cast<_Float16
>(ff);
712#elif defined(EIGEN_HAS_FP16_C)
715 h.x =
static_cast<numext::uint16_t
>(_mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(ff), 0), 0));
719 uint32_t f_bits = Eigen::numext::bit_cast<uint32_t>(ff);
720 const uint32_t f32infty_bits = {255 << 23};
721 const uint32_t f16max_bits = {(127 + 16) << 23};
722 const uint32_t denorm_magic_bits = {((127 - 15) + (23 - 10) + 1) << 23};
723 const uint32_t sign_mask = 0x80000000u;
725 o.x =
static_cast<uint16_t
>(0x0u);
727 const uint32_t sign = f_bits & sign_mask;
735 if (f_bits >= f16max_bits) {
736 o.x = (f_bits > f32infty_bits) ? 0x7e00 : 0x7c00;
738 if (f_bits < (113 << 23)) {
742 f_bits = Eigen::numext::bit_cast<uint32_t>(Eigen::numext::bit_cast<float>(f_bits) +
743 Eigen::numext::bit_cast<float>(denorm_magic_bits));
746 o.x =
static_cast<numext::uint16_t
>(f_bits - denorm_magic_bits);
748 const uint32_t mant_odd = (f_bits >> 13) & 1;
753 f_bits += 0xc8000fffU;
757 o.x =
static_cast<numext::uint16_t
>(f_bits >> 13);
761 o.x |=
static_cast<numext::uint16_t
>(sign >> 16);
766EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
float half_to_float(__half_raw h) {
767#if defined(EIGEN_GPU_COMPILE_PHASE)
768 return __half2float(h);
769#elif EIGEN_HAS_ARM64_FP16 || defined(EIGEN_HAS_BUILTIN_FLOAT16)
770 return static_cast<float>(h.x);
771#elif defined(EIGEN_HAS_FP16_C)
774 return _mm_cvtss_f32(_mm_cvtph_ps(_mm_set1_epi16(h.x)));
776 return _cvtsh_ss(h.x);
779 const float magic = Eigen::numext::bit_cast<float>(
static_cast<uint32_t
>(113 << 23));
780 const uint32_t shifted_exp = 0x7c00 << 13;
781 uint32_t o_bits = (h.x & 0x7fff) << 13;
782 const uint32_t exp = shifted_exp & o_bits;
783 o_bits += (127 - 15) << 23;
786 if (exp == shifted_exp) {
787 o_bits += (128 - 16) << 23;
788 }
else if (exp == 0) {
791 o_bits = Eigen::numext::bit_cast<uint32_t>(Eigen::numext::bit_cast<float>(o_bits) - magic);
794 o_bits |= (h.x & 0x8000u) << 16;
795 return Eigen::numext::bit_cast<float>(o_bits);
801EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isinf)(
const half& a) {
return (raw_half_as_uint16(a) & 0x7fff) == 0x7c00; }
802EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isnan)(
const half& a) {
803#if defined(EIGEN_GPU_COMPILE_PHASE)
806 return (raw_half_as_uint16(a) & 0x7fff) > 0x7c00;
809EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool(isfinite)(
const half& a) {
810 return (raw_half_as_uint16(a) & 0x7fff) < 0x7c00;
813EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(
const half& a) {
814#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
815 return half_from_rep(vabsh_f16(a.x));
817 return raw_uint16_to_half(
static_cast<numext::uint16_t
>(raw_half_as_uint16(a) & 0x7FFF));
820EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(
const half& a) {
821#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
822 return half(hexp(::__half(a)));
824 return half(::expf(
float(a)));
827EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp2(
const half& a) {
828#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
829 return half(hexp2(::__half(a)));
831 return half(::exp2f(
float(a)));
834EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(
const half& a) {
return half(numext::expm1(
float(a))); }
836EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ldexp(
const half& a,
int exponent) {
837 return half(numext::ldexp(
float(a), exponent));
839EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(
const half& a) {
840#if defined(EIGEN_GPU_COMPILE_PHASE)
841 return half(hlog(::__half(a)));
843 return half(::logf(
float(a)));
846EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log1p(
const half& a) {
return half(numext::log1p(
float(a))); }
847EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(
const half& a) {
return half(::log10f(
float(a))); }
848EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log2(
const half& a) {
849 return half(
static_cast<float>(EIGEN_LOG2E) * ::logf(
float(a)));
852EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(
const half& a) {
853#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIP_DEVICE_COMPILE)
854 return half(hsqrt(::__half(a)));
856 return half(::sqrtf(
float(a)));
859EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(
const half& a,
const half& b) {
860 return half(::powf(
float(a),
float(b)));
862EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atan2(
const half& a,
const half& b) {
863 return half(::atan2f(
float(a),
float(b)));
865EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sin(
const half& a) {
return half(::sinf(
float(a))); }
866EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half cos(
const half& a) {
return half(::cosf(
float(a))); }
867EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tan(
const half& a) {
return half(::tanf(
float(a))); }
868EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(
const half& a) {
return half(::tanhf(
float(a))); }
869EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half asin(
const half& a) {
return half(::asinf(
float(a))); }
870EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half acos(
const half& a) {
return half(::acosf(
float(a))); }
871EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atan(
const half& a) {
return half(::atanf(
float(a))); }
872EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half atanh(
const half& a) {
return half(::atanhf(
float(a))); }
873EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(
const half& a) {
874#if (defined(EIGEN_CUDA_ARCH)) || defined(EIGEN_HIP_DEVICE_COMPILE)
875 return half(hfloor(::__half(a)));
877 return half(::floorf(
float(a)));
880EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(
const half& a) {
881#if (defined(EIGEN_CUDA_ARCH)) || defined(EIGEN_HIP_DEVICE_COMPILE)
882 return half(hceil(::__half(a)));
884 return half(::ceilf(
float(a)));
887EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half rint(
const half& a) {
return half(::rintf(
float(a))); }
888EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half round(
const half& a) {
return half(::roundf(
float(a))); }
889EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half trunc(
const half& a) {
return half(::truncf(
float(a))); }
890EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half fmod(
const half& a,
const half& b) {
891 return half(::fmodf(
float(a),
float(b)));
894EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half(min)(
const half& a,
const half& b) {
return b < a ? b : a; }
896EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half(max)(
const half& a,
const half& b) {
return a < b ? b : a; }
898EIGEN_DEVICE_FUNC
inline half fma(
const half& a,
const half& b,
const half& c) {
899#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
900 return half_from_rep(vfmah_f16(c.x, a.x, b.x));
901#elif defined(EIGEN_VECTORIZE_AVX512FP16)
903 return half(_mm_cvtsh_h(_mm_fmadd_ph(_mm_set_sh(a.x), _mm_set_sh(b.x), _mm_set_sh(c.x))));
906 return half(numext::fma(
static_cast<float>(a),
static_cast<float>(b),
static_cast<float>(c)));
911EIGEN_ALWAYS_INLINE std::ostream& operator<<(std::ostream& os,
const half& v) {
912 os << static_cast<float>(v);
925struct is_arithmetic<half> : std::true_type {};
928struct random_impl<half> {
929 enum :
int { MantissaBits = 10 };
930 using Impl = random_impl<float>;
931 static EIGEN_DEVICE_FUNC
inline half run(
const half& x,
const half& y) {
932 float result = Impl::run(x, y, MantissaBits);
935 static EIGEN_DEVICE_FUNC
inline half run() {
936 float result = Impl::run(MantissaBits);
944struct NumTraits<Eigen::half> : GenericNumTraits<Eigen::half> {
945 enum { IsSigned =
true, IsInteger =
false, IsComplex =
false, RequireInitialization =
false };
947 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half epsilon() {
949 return half_impl::raw_uint16_to_half(0x1400);
951 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half dummy_precision() {
952 return half_impl::raw_uint16_to_half(0x211f);
954 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half highest() {
955 return half_impl::raw_uint16_to_half(0x7bff);
957 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half lowest() {
958 return half_impl::raw_uint16_to_half(0xfbff);
960 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half infinity() {
961 return half_impl::raw_uint16_to_half(0x7c00);
963 EIGEN_DEVICE_FUNC _EIGEN_MAYBE_CONSTEXPR
static EIGEN_STRONG_INLINE Eigen::half quiet_NaN() {
964 return half_impl::raw_uint16_to_half(0x7e00);
970#undef _EIGEN_MAYBE_CONSTEXPR
975#if defined(EIGEN_GPU_COMPILE_PHASE)
978EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isnan)(
const Eigen::half& h) {
979 return (half_impl::isnan)(h);
983EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isinf)(
const Eigen::half& h) {
984 return (half_impl::isinf)(h);
988EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isfinite)(
const Eigen::half& h) {
989 return (half_impl::isfinite)(h);
995EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half bit_cast<Eigen::half, uint16_t>(
const uint16_t& src) {
996 return Eigen::half(Eigen::half_impl::raw_uint16_to_half(src));
1000EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC uint16_t bit_cast<uint16_t, Eigen::half>(
const Eigen::half& src) {
1001 return Eigen::half_impl::raw_half_as_uint16(src);
1004EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half nextafter(
const Eigen::half& from,
const Eigen::half& to) {
1005 if (numext::isnan EIGEN_NOT_A_MACRO(from)) {
1008 if (numext::isnan EIGEN_NOT_A_MACRO(to)) {
1014 uint16_t from_bits = numext::bit_cast<uint16_t>(from);
1015 bool from_sign = from_bits >> 15;
1016 if ((from_bits & 0x7fff) == 0) {
1019 from_bits = (to > from) ? uint16_t(0x0001) : uint16_t(0x8001);
1020 }
else if ((to > from) != from_sign) {
1026 return numext::bit_cast<Eigen::half>(from_bits);
1031EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half madd<Eigen::half>(
const Eigen::half& x,
const Eigen::half& y,
1032 const Eigen::half& z) {
1033 return Eigen::half(
static_cast<float>(x) *
static_cast<float>(y) +
static_cast<float>(z));
1042#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
1044#if defined(EIGEN_CUDACC)
1046__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_sync(
unsigned mask, Eigen::half var,
int srcLane,
1047 int width = warpSize) {
1048 const __half h = var;
1049 return static_cast<Eigen::half
>(__shfl_sync(mask, h, srcLane, width));
1052__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up_sync(
unsigned mask, Eigen::half var,
unsigned int delta,
1053 int width = warpSize) {
1054 const __half h = var;
1055 return static_cast<Eigen::half
>(__shfl_up_sync(mask, h, delta, width));
1058__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down_sync(
unsigned mask, Eigen::half var,
unsigned int delta,
1059 int width = warpSize) {
1060 const __half h = var;
1061 return static_cast<Eigen::half
>(__shfl_down_sync(mask, h, delta, width));
1064__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor_sync(
unsigned mask, Eigen::half var,
int laneMask,
1065 int width = warpSize) {
1066 const __half h = var;
1067 return static_cast<Eigen::half
>(__shfl_xor_sync(mask, h, laneMask, width));
1072__device__ EIGEN_STRONG_INLINE Eigen::half __shfl(Eigen::half var,
int srcLane,
int width = warpSize) {
1073 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1074 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl(ivar, srcLane, width)));
1077__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up(Eigen::half var,
unsigned int delta,
int width = warpSize) {
1078 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1079 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_up(ivar, delta, width)));
1082__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down(Eigen::half var,
unsigned int delta,
int width = warpSize) {
1083 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1084 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_down(ivar, delta, width)));
1087__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor(Eigen::half var,
int laneMask,
int width = warpSize) {
1088 const int ivar =
static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
1089 return Eigen::numext::bit_cast<Eigen::half>(
static_cast<Eigen::numext::uint16_t
>(__shfl_xor(ivar, laneMask, width)));
1096#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
1097EIGEN_STRONG_INLINE __device__ Eigen::half __ldg(
const Eigen::half* ptr) {
1098 return Eigen::half_impl::raw_uint16_to_half(__ldg(
reinterpret_cast<const Eigen::numext::uint16_t*
>(ptr)));
1102#if EIGEN_HAS_STD_HASH
1105struct hash<Eigen::half> {
1106 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(
const Eigen::half& a)
const {
1107 return static_cast<std::size_t
>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(a));
1117struct cast_impl<float, half> {
1118 EIGEN_DEVICE_FUNC
static inline half run(
const float& a) {
1119#if defined(EIGEN_GPU_COMPILE_PHASE)
1120 return __float2half(a);
1128struct cast_impl<int, half> {
1129 EIGEN_DEVICE_FUNC
static inline half run(
const int& a) {
1130#if defined(EIGEN_GPU_COMPILE_PHASE)
1131 return __float2half(
static_cast<float>(a));
1133 return half(
static_cast<float>(a));
1139struct cast_impl<half, float> {
1140 EIGEN_DEVICE_FUNC
static inline float run(
const half& a) {
1141#if defined(EIGEN_GPU_COMPILE_PHASE)
1142 return __half2float(a);
1144 return static_cast<float>(a);
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition NumTraits.h:233