File indexing completed on 2025-01-19 09:51:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef EIGEN_HALF_H
0037 #define EIGEN_HALF_H
0038
0039 #include <sstream>
0040
0041 #if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0042
0043
0044
0045
0046
0047
0048 #pragma push_macro("EIGEN_CONSTEXPR")
0049 #undef EIGEN_CONSTEXPR
0050 #define EIGEN_CONSTEXPR
0051 #endif
0052
0053 #define F16_PACKET_FUNCTION(PACKET_F, PACKET_F16, METHOD) \
0054 template <> \
0055 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED \
0056 PACKET_F16 METHOD<PACKET_F16>(const PACKET_F16& _x) { \
0057 return float2half(METHOD<PACKET_F>(half2float(_x))); \
0058 }
0059
0060 namespace Eigen {
0061
0062 struct half;
0063
0064 namespace half_impl {
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 #if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
0086
0087 struct __half_raw {
0088 #if (defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE))
0089
0090
0091
0092
0093
0094 EIGEN_DEVICE_FUNC __half_raw() {}
0095 #else
0096 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw() : x(0) {}
0097 #endif
0098 #if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0099 explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw(numext::uint16_t raw) : x(numext::bit_cast<__fp16>(raw)) {
0100 }
0101 __fp16 x;
0102 #else
0103 explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw(numext::uint16_t raw) : x(raw) {}
0104 numext::uint16_t x;
0105 #endif
0106 };
0107
0108 #elif defined(EIGEN_HAS_HIP_FP16)
0109
0110
0111 #elif defined(EIGEN_HAS_CUDA_FP16)
0112 #if EIGEN_CUDA_SDK_VER < 90000
0113
0114 typedef __half __half_raw;
0115 #endif
0116 #elif defined(SYCL_DEVICE_ONLY)
0117 typedef cl::sycl::half __half_raw;
0118 #endif
0119
0120 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x);
0121 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff);
0122 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h);
0123
0124 struct half_base : public __half_raw {
0125 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half_base() {}
0126 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half_base(const __half_raw& h) : __half_raw(h) {}
0127
0128 #if defined(EIGEN_HAS_GPU_FP16)
0129 #if defined(EIGEN_HAS_HIP_FP16)
0130 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half_base(const __half& h) { x = __half_as_ushort(h); }
0131 #elif defined(EIGEN_HAS_CUDA_FP16)
0132 #if EIGEN_CUDA_SDK_VER >= 90000
0133 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half_base(const __half& h) : __half_raw(*(__half_raw*)&h) {}
0134 #endif
0135 #endif
0136 #endif
0137 };
0138
0139 }
0140
0141
0142 struct half : public half_impl::half_base {
0143
0144
0145
0146 #if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
0147
0148
0149
0150 typedef half_impl::__half_raw __half_raw;
0151 #elif defined(EIGEN_HAS_HIP_FP16)
0152
0153
0154 #elif defined(EIGEN_HAS_CUDA_FP16)
0155
0156
0157
0158 #if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER < 90000
0159 typedef half_impl::__half_raw __half_raw;
0160 #endif
0161 #endif
0162
0163 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half() {}
0164
0165 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half(const __half_raw& h) : half_impl::half_base(h) {}
0166
0167 #if defined(EIGEN_HAS_GPU_FP16)
0168 #if defined(EIGEN_HAS_HIP_FP16)
0169 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half(const __half& h) : half_impl::half_base(h) {}
0170 #elif defined(EIGEN_HAS_CUDA_FP16)
0171 #if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
0172 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half(const __half& h) : half_impl::half_base(h) {}
0173 #endif
0174 #endif
0175 #endif
0176
0177
0178 explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half(bool b)
0179 : half_impl::half_base(half_impl::raw_uint16_to_half(b ? 0x3c00 : 0)) {}
0180 template<class T>
0181 explicit EIGEN_DEVICE_FUNC half(T val)
0182 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(val))) {}
0183 explicit EIGEN_DEVICE_FUNC half(float f)
0184 : half_impl::half_base(half_impl::float_to_half_rtne(f)) {}
0185
0186
0187
0188 template<typename RealScalar>
0189 explicit EIGEN_DEVICE_FUNC half(std::complex<RealScalar> c)
0190 : half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(c.real()))) {}
0191
0192 EIGEN_DEVICE_FUNC operator float() const {
0193 return half_impl::half_to_float(*this);
0194 }
0195
0196 #if defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE)
0197 EIGEN_DEVICE_FUNC operator __half() const {
0198 ::__half_raw hr;
0199 hr.x = x;
0200 return __half(hr);
0201 }
0202 #endif
0203 };
0204
0205 }
0206
0207 namespace std {
0208 template<>
0209 struct numeric_limits<Eigen::half> {
0210 static const bool is_specialized = true;
0211 static const bool is_signed = true;
0212 static const bool is_integer = false;
0213 static const bool is_exact = false;
0214 static const bool has_infinity = true;
0215 static const bool has_quiet_NaN = true;
0216 static const bool has_signaling_NaN = true;
0217 static const float_denorm_style has_denorm = denorm_present;
0218 static const bool has_denorm_loss = false;
0219 static const std::float_round_style round_style = std::round_to_nearest;
0220 static const bool is_iec559 = false;
0221 static const bool is_bounded = false;
0222 static const bool is_modulo = false;
0223 static const int digits = 11;
0224 static const int digits10 = 3;
0225 static const int max_digits10 = 5;
0226 static const int radix = 2;
0227 static const int min_exponent = -13;
0228 static const int min_exponent10 = -4;
0229 static const int max_exponent = 16;
0230 static const int max_exponent10 = 4;
0231 static const bool traps = true;
0232 static const bool tinyness_before = false;
0233
0234 static Eigen::half (min)() { return Eigen::half_impl::raw_uint16_to_half(0x400); }
0235 static Eigen::half lowest() { return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
0236 static Eigen::half (max)() { return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
0237 static Eigen::half epsilon() { return Eigen::half_impl::raw_uint16_to_half(0x0800); }
0238 static Eigen::half round_error() { return Eigen::half(0.5); }
0239 static Eigen::half infinity() { return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
0240 static Eigen::half quiet_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
0241 static Eigen::half signaling_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7d00); }
0242 static Eigen::half denorm_min() { return Eigen::half_impl::raw_uint16_to_half(0x1); }
0243 };
0244
0245
0246
0247
0248
0249 template<>
0250 struct numeric_limits<const Eigen::half> : numeric_limits<Eigen::half> {};
0251 template<>
0252 struct numeric_limits<volatile Eigen::half> : numeric_limits<Eigen::half> {};
0253 template<>
0254 struct numeric_limits<const volatile Eigen::half> : numeric_limits<Eigen::half> {};
0255 }
0256
0257 namespace Eigen {
0258
0259 namespace half_impl {
0260
0261 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && \
0262 EIGEN_CUDA_ARCH >= 530) || \
0263 (defined(EIGEN_HAS_HIP_FP16) && defined(HIP_DEVICE_COMPILE))
0264
0265
0266
0267 #define EIGEN_HAS_NATIVE_FP16
0268 #endif
0269
0270
0271
0272
0273
0274
0275 #if defined(EIGEN_HAS_NATIVE_FP16)
0276 EIGEN_STRONG_INLINE __device__ half operator + (const half& a, const half& b) {
0277 #if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
0278 return __hadd(::__half(a), ::__half(b));
0279 #else
0280 return __hadd(a, b);
0281 #endif
0282 }
0283 EIGEN_STRONG_INLINE __device__ half operator * (const half& a, const half& b) {
0284 return __hmul(a, b);
0285 }
0286 EIGEN_STRONG_INLINE __device__ half operator - (const half& a, const half& b) {
0287 return __hsub(a, b);
0288 }
0289 EIGEN_STRONG_INLINE __device__ half operator / (const half& a, const half& b) {
0290 #if defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER >= 90000
0291 return __hdiv(a, b);
0292 #else
0293 float num = __half2float(a);
0294 float denom = __half2float(b);
0295 return __float2half(num / denom);
0296 #endif
0297 }
0298 EIGEN_STRONG_INLINE __device__ half operator - (const half& a) {
0299 return __hneg(a);
0300 }
0301 EIGEN_STRONG_INLINE __device__ half& operator += (half& a, const half& b) {
0302 a = a + b;
0303 return a;
0304 }
0305 EIGEN_STRONG_INLINE __device__ half& operator *= (half& a, const half& b) {
0306 a = a * b;
0307 return a;
0308 }
0309 EIGEN_STRONG_INLINE __device__ half& operator -= (half& a, const half& b) {
0310 a = a - b;
0311 return a;
0312 }
0313 EIGEN_STRONG_INLINE __device__ half& operator /= (half& a, const half& b) {
0314 a = a / b;
0315 return a;
0316 }
0317 EIGEN_STRONG_INLINE __device__ bool operator == (const half& a, const half& b) {
0318 return __heq(a, b);
0319 }
0320 EIGEN_STRONG_INLINE __device__ bool operator != (const half& a, const half& b) {
0321 return __hne(a, b);
0322 }
0323 EIGEN_STRONG_INLINE __device__ bool operator < (const half& a, const half& b) {
0324 return __hlt(a, b);
0325 }
0326 EIGEN_STRONG_INLINE __device__ bool operator <= (const half& a, const half& b) {
0327 return __hle(a, b);
0328 }
0329 EIGEN_STRONG_INLINE __device__ bool operator > (const half& a, const half& b) {
0330 return __hgt(a, b);
0331 }
0332 EIGEN_STRONG_INLINE __device__ bool operator >= (const half& a, const half& b) {
0333 return __hge(a, b);
0334 }
0335 #endif
0336
0337 #if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0338 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator + (const half& a, const half& b) {
0339 return half(vaddh_f16(a.x, b.x));
0340 }
0341 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator * (const half& a, const half& b) {
0342 return half(vmulh_f16(a.x, b.x));
0343 }
0344 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator - (const half& a, const half& b) {
0345 return half(vsubh_f16(a.x, b.x));
0346 }
0347 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator / (const half& a, const half& b) {
0348 return half(vdivh_f16(a.x, b.x));
0349 }
0350 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator - (const half& a) {
0351 return half(vnegh_f16(a.x));
0352 }
0353 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator += (half& a, const half& b) {
0354 a = half(vaddh_f16(a.x, b.x));
0355 return a;
0356 }
0357 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator *= (half& a, const half& b) {
0358 a = half(vmulh_f16(a.x, b.x));
0359 return a;
0360 }
0361 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator -= (half& a, const half& b) {
0362 a = half(vsubh_f16(a.x, b.x));
0363 return a;
0364 }
0365 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator /= (half& a, const half& b) {
0366 a = half(vdivh_f16(a.x, b.x));
0367 return a;
0368 }
0369 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator == (const half& a, const half& b) {
0370 return vceqh_f16(a.x, b.x);
0371 }
0372 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator != (const half& a, const half& b) {
0373 return !vceqh_f16(a.x, b.x);
0374 }
0375 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator < (const half& a, const half& b) {
0376 return vclth_f16(a.x, b.x);
0377 }
0378 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator <= (const half& a, const half& b) {
0379 return vcleh_f16(a.x, b.x);
0380 }
0381 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator > (const half& a, const half& b) {
0382 return vcgth_f16(a.x, b.x);
0383 }
0384 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator >= (const half& a, const half& b) {
0385 return vcgeh_f16(a.x, b.x);
0386 }
0387
0388
0389
0390 #elif !defined(EIGEN_HAS_NATIVE_FP16) || (EIGEN_COMP_CLANG && !EIGEN_COMP_NVCC)
0391
0392 #if EIGEN_COMP_CLANG && defined(EIGEN_CUDACC)
0393
0394 #pragma push_macro("EIGEN_DEVICE_FUNC")
0395 #undef EIGEN_DEVICE_FUNC
0396 #if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_HAS_NATIVE_FP16)
0397 #define EIGEN_DEVICE_FUNC __host__
0398 #else
0399 #define EIGEN_DEVICE_FUNC __host__ __device__
0400 #endif
0401 #endif
0402
0403
0404
0405 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator + (const half& a, const half& b) {
0406 return half(float(a) + float(b));
0407 }
0408 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator * (const half& a, const half& b) {
0409 return half(float(a) * float(b));
0410 }
0411 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator - (const half& a, const half& b) {
0412 return half(float(a) - float(b));
0413 }
0414 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator / (const half& a, const half& b) {
0415 return half(float(a) / float(b));
0416 }
0417 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator - (const half& a) {
0418 half result;
0419 result.x = a.x ^ 0x8000;
0420 return result;
0421 }
0422 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator += (half& a, const half& b) {
0423 a = half(float(a) + float(b));
0424 return a;
0425 }
0426 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator *= (half& a, const half& b) {
0427 a = half(float(a) * float(b));
0428 return a;
0429 }
0430 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator -= (half& a, const half& b) {
0431 a = half(float(a) - float(b));
0432 return a;
0433 }
0434 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator /= (half& a, const half& b) {
0435 a = half(float(a) / float(b));
0436 return a;
0437 }
0438 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator == (const half& a, const half& b) {
0439 return numext::equal_strict(float(a),float(b));
0440 }
0441 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator != (const half& a, const half& b) {
0442 return numext::not_equal_strict(float(a), float(b));
0443 }
0444 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator < (const half& a, const half& b) {
0445 return float(a) < float(b);
0446 }
0447 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator <= (const half& a, const half& b) {
0448 return float(a) <= float(b);
0449 }
0450 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator > (const half& a, const half& b) {
0451 return float(a) > float(b);
0452 }
0453 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator >= (const half& a, const half& b) {
0454 return float(a) >= float(b);
0455 }
0456
0457 #if defined(__clang__) && defined(__CUDA__)
0458 #pragma pop_macro("EIGEN_DEVICE_FUNC")
0459 #endif
0460 #endif
0461
0462
0463
0464 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator / (const half& a, Index b) {
0465 return half(static_cast<float>(a) / static_cast<float>(b));
0466 }
0467
0468 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a) {
0469 a += half(1);
0470 return a;
0471 }
0472
0473 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a) {
0474 a -= half(1);
0475 return a;
0476 }
0477
0478 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a, int) {
0479 half original_value = a;
0480 ++a;
0481 return original_value;
0482 }
0483
0484 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a, int) {
0485 half original_value = a;
0486 --a;
0487 return original_value;
0488 }
0489
0490
0491
0492
0493
0494
0495 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw raw_uint16_to_half(numext::uint16_t x) {
0496
0497
0498
0499
0500
0501
0502 #if defined(EIGEN_HAS_GPU_FP16)
0503 __half_raw h;
0504 h.x = x;
0505 return h;
0506 #else
0507 return __half_raw(x);
0508 #endif
0509 }
0510
0511 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC numext::uint16_t raw_half_as_uint16(const __half_raw& h) {
0512
0513
0514
0515 #if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0516 return numext::bit_cast<numext::uint16_t>(h.x);
0517 #elif defined(SYCL_DEVICE_ONLY)
0518 return numext::bit_cast<numext::uint16_t>(h);
0519 #else
0520 return h.x;
0521 #endif
0522 }
0523
0524 union float32_bits {
0525 unsigned int u;
0526 float f;
0527 };
0528
0529 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff) {
0530 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
0531 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0532 __half tmp_ff = __float2half(ff);
0533 return *(__half_raw*)&tmp_ff;
0534
0535 #elif defined(EIGEN_HAS_FP16_C)
0536 __half_raw h;
0537 h.x = _cvtss_sh(ff, 0);
0538 return h;
0539
0540 #elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0541 __half_raw h;
0542 h.x = static_cast<__fp16>(ff);
0543 return h;
0544
0545 #else
0546 float32_bits f; f.f = ff;
0547
0548 const float32_bits f32infty = { 255 << 23 };
0549 const float32_bits f16max = { (127 + 16) << 23 };
0550 const float32_bits denorm_magic = { ((127 - 15) + (23 - 10) + 1) << 23 };
0551 unsigned int sign_mask = 0x80000000u;
0552 __half_raw o;
0553 o.x = static_cast<numext::uint16_t>(0x0u);
0554
0555 unsigned int sign = f.u & sign_mask;
0556 f.u ^= sign;
0557
0558
0559
0560
0561
0562
0563 if (f.u >= f16max.u) {
0564 o.x = (f.u > f32infty.u) ? 0x7e00 : 0x7c00;
0565 } else {
0566 if (f.u < (113 << 23)) {
0567
0568
0569
0570 f.f += denorm_magic.f;
0571
0572
0573 o.x = static_cast<numext::uint16_t>(f.u - denorm_magic.u);
0574 } else {
0575 unsigned int mant_odd = (f.u >> 13) & 1;
0576
0577
0578
0579
0580 f.u += 0xc8000fffU;
0581
0582 f.u += mant_odd;
0583
0584 o.x = static_cast<numext::uint16_t>(f.u >> 13);
0585 }
0586 }
0587
0588 o.x |= static_cast<numext::uint16_t>(sign >> 16);
0589 return o;
0590 #endif
0591 }
0592
0593 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h) {
0594 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300) || \
0595 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0596 return __half2float(h);
0597 #elif defined(EIGEN_HAS_FP16_C)
0598 return _cvtsh_ss(h.x);
0599 #elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0600 return static_cast<float>(h.x);
0601 #else
0602 const float32_bits magic = { 113 << 23 };
0603 const unsigned int shifted_exp = 0x7c00 << 13;
0604 float32_bits o;
0605
0606 o.u = (h.x & 0x7fff) << 13;
0607 unsigned int exp = shifted_exp & o.u;
0608 o.u += (127 - 15) << 23;
0609
0610
0611 if (exp == shifted_exp) {
0612 o.u += (128 - 16) << 23;
0613 } else if (exp == 0) {
0614 o.u += 1 << 23;
0615 o.f -= magic.f;
0616 }
0617
0618 o.u |= (h.x & 0x8000) << 16;
0619 return o.f;
0620 #endif
0621 }
0622
0623
0624
0625 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isinf)(const half& a) {
0626 #ifdef EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC
0627 return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) == 0x7c00;
0628 #else
0629 return (a.x & 0x7fff) == 0x7c00;
0630 #endif
0631 }
0632 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isnan)(const half& a) {
0633 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
0634 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0635 return __hisnan(a);
0636 #elif defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0637 return (numext::bit_cast<numext::uint16_t>(a.x) & 0x7fff) > 0x7c00;
0638 #else
0639 return (a.x & 0x7fff) > 0x7c00;
0640 #endif
0641 }
0642 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isfinite)(const half& a) {
0643 return !(isinf EIGEN_NOT_A_MACRO (a)) && !(isnan EIGEN_NOT_A_MACRO (a));
0644 }
0645
0646 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half& a) {
0647 #if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0648 return half(vabsh_f16(a.x));
0649 #else
0650 half result;
0651 result.x = a.x & 0x7FFF;
0652 return result;
0653 #endif
0654 }
0655 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(const half& a) {
0656 #if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
0657 defined(EIGEN_HIP_DEVICE_COMPILE)
0658 return half(hexp(a));
0659 #else
0660 return half(::expf(float(a)));
0661 #endif
0662 }
0663 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(const half& a) {
0664 return half(numext::expm1(float(a)));
0665 }
0666 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) {
0667 #if (defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
0668 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0669 return half(::hlog(a));
0670 #else
0671 return half(::logf(float(a)));
0672 #endif
0673 }
0674 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log1p(const half& a) {
0675 return half(numext::log1p(float(a)));
0676 }
0677 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(const half& a) {
0678 return half(::log10f(float(a)));
0679 }
0680 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log2(const half& a) {
0681 return half(static_cast<float>(EIGEN_LOG2E) * ::logf(float(a)));
0682 }
0683
0684 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(const half& a) {
0685 #if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
0686 defined(EIGEN_HIP_DEVICE_COMPILE)
0687 return half(hsqrt(a));
0688 #else
0689 return half(::sqrtf(float(a)));
0690 #endif
0691 }
0692 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half& a, const half& b) {
0693 return half(::powf(float(a), float(b)));
0694 }
0695 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sin(const half& a) {
0696 return half(::sinf(float(a)));
0697 }
0698 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half cos(const half& a) {
0699 return half(::cosf(float(a)));
0700 }
0701 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tan(const half& a) {
0702 return half(::tanf(float(a)));
0703 }
0704 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(const half& a) {
0705 return half(::tanhf(float(a)));
0706 }
0707 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half asin(const half& a) {
0708 return half(::asinf(float(a)));
0709 }
0710 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half acos(const half& a) {
0711 return half(::acosf(float(a)));
0712 }
0713 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) {
0714 #if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
0715 defined(EIGEN_HIP_DEVICE_COMPILE)
0716 return half(hfloor(a));
0717 #else
0718 return half(::floorf(float(a)));
0719 #endif
0720 }
0721 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
0722 #if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
0723 defined(EIGEN_HIP_DEVICE_COMPILE)
0724 return half(hceil(a));
0725 #else
0726 return half(::ceilf(float(a)));
0727 #endif
0728 }
0729 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half rint(const half& a) {
0730 return half(::rintf(float(a)));
0731 }
0732 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half round(const half& a) {
0733 return half(::roundf(float(a)));
0734 }
0735 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half fmod(const half& a, const half& b) {
0736 return half(::fmodf(float(a), float(b)));
0737 }
0738
0739 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) {
0740 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
0741 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0742 return __hlt(b, a) ? b : a;
0743 #else
0744 const float f1 = static_cast<float>(a);
0745 const float f2 = static_cast<float>(b);
0746 return f2 < f1 ? b : a;
0747 #endif
0748 }
0749 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (max)(const half& a, const half& b) {
0750 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
0751 (defined(EIGEN_HAS_HIP_FP16) && defined(EIGEN_HIP_DEVICE_COMPILE))
0752 return __hlt(a, b) ? b : a;
0753 #else
0754 const float f1 = static_cast<float>(a);
0755 const float f2 = static_cast<float>(b);
0756 return f1 < f2 ? b : a;
0757 #endif
0758 }
0759
0760 #ifndef EIGEN_NO_IO
0761 EIGEN_ALWAYS_INLINE std::ostream& operator << (std::ostream& os, const half& v) {
0762 os << static_cast<float>(v);
0763 return os;
0764 }
0765 #endif
0766
0767 }
0768
0769
0770
0771
0772 namespace internal {
0773
0774 template<>
0775 struct random_default_impl<half, false, false>
0776 {
0777 static inline half run(const half& x, const half& y)
0778 {
0779 return x + (y-x) * half(float(std::rand()) / float(RAND_MAX));
0780 }
0781 static inline half run()
0782 {
0783 return run(half(-1.f), half(1.f));
0784 }
0785 };
0786
0787 template<> struct is_arithmetic<half> { enum { value = true }; };
0788
0789 }
0790
0791 template<> struct NumTraits<Eigen::half>
0792 : GenericNumTraits<Eigen::half>
0793 {
0794 enum {
0795 IsSigned = true,
0796 IsInteger = false,
0797 IsComplex = false,
0798 RequireInitialization = false
0799 };
0800
0801 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half epsilon() {
0802 return half_impl::raw_uint16_to_half(0x0800);
0803 }
0804 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half dummy_precision() {
0805 return half_impl::raw_uint16_to_half(0x211f);
0806 }
0807 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half highest() {
0808 return half_impl::raw_uint16_to_half(0x7bff);
0809 }
0810 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half lowest() {
0811 return half_impl::raw_uint16_to_half(0xfbff);
0812 }
0813 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half infinity() {
0814 return half_impl::raw_uint16_to_half(0x7c00);
0815 }
0816 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static EIGEN_STRONG_INLINE Eigen::half quiet_NaN() {
0817 return half_impl::raw_uint16_to_half(0x7e00);
0818 }
0819 };
0820
0821 }
0822
0823 #if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
0824 #pragma pop_macro("EIGEN_CONSTEXPR")
0825 #endif
0826
0827 namespace Eigen {
0828 namespace numext {
0829
0830 #if defined(EIGEN_GPU_COMPILE_PHASE)
0831
0832 template <>
0833 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isnan)(const Eigen::half& h) {
0834 return (half_impl::isnan)(h);
0835 }
0836
0837 template <>
0838 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isinf)(const Eigen::half& h) {
0839 return (half_impl::isinf)(h);
0840 }
0841
0842 template <>
0843 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isfinite)(const Eigen::half& h) {
0844 return (half_impl::isfinite)(h);
0845 }
0846
0847 #endif
0848
0849 template <>
0850 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half bit_cast<Eigen::half, uint16_t>(const uint16_t& src) {
0851 return Eigen::half(Eigen::half_impl::raw_uint16_to_half(src));
0852 }
0853
0854 template <>
0855 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC uint16_t bit_cast<uint16_t, Eigen::half>(const Eigen::half& src) {
0856 return Eigen::half_impl::raw_half_as_uint16(src);
0857 }
0858
0859 }
0860 }
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873 #if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 300)) \
0874 || defined(EIGEN_HIPCC)
0875
0876 #if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 90000
0877
0878 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_sync(unsigned mask, Eigen::half var, int srcLane, int width=warpSize) {
0879 const __half h = var;
0880 return static_cast<Eigen::half>(__shfl_sync(mask, h, srcLane, width));
0881 }
0882
0883 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up_sync(unsigned mask, Eigen::half var, unsigned int delta, int width=warpSize) {
0884 const __half h = var;
0885 return static_cast<Eigen::half>(__shfl_up_sync(mask, h, delta, width));
0886 }
0887
0888 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down_sync(unsigned mask, Eigen::half var, unsigned int delta, int width=warpSize) {
0889 const __half h = var;
0890 return static_cast<Eigen::half>(__shfl_down_sync(mask, h, delta, width));
0891 }
0892
0893 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor_sync(unsigned mask, Eigen::half var, int laneMask, int width=warpSize) {
0894 const __half h = var;
0895 return static_cast<Eigen::half>(__shfl_xor_sync(mask, h, laneMask, width));
0896 }
0897
0898 #else
0899
0900 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl(Eigen::half var, int srcLane, int width=warpSize) {
0901 const int ivar = static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
0902 return Eigen::numext::bit_cast<Eigen::half>(static_cast<Eigen::numext::uint16_t>(__shfl(ivar, srcLane, width)));
0903 }
0904
0905 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up(Eigen::half var, unsigned int delta, int width=warpSize) {
0906 const int ivar = static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
0907 return Eigen::numext::bit_cast<Eigen::half>(static_cast<Eigen::numext::uint16_t>(__shfl_up(ivar, delta, width)));
0908 }
0909
0910 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down(Eigen::half var, unsigned int delta, int width=warpSize) {
0911 const int ivar = static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
0912 return Eigen::numext::bit_cast<Eigen::half>(static_cast<Eigen::numext::uint16_t>(__shfl_down(ivar, delta, width)));
0913 }
0914
0915 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor(Eigen::half var, int laneMask, int width=warpSize) {
0916 const int ivar = static_cast<int>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(var));
0917 return Eigen::numext::bit_cast<Eigen::half>(static_cast<Eigen::numext::uint16_t>(__shfl_xor(ivar, laneMask, width)));
0918 }
0919
0920 #endif
0921 #endif
0922
0923
0924 #if (defined(EIGEN_CUDACC) && (!defined(EIGEN_CUDA_ARCH) || EIGEN_CUDA_ARCH >= 350)) \
0925 || defined(EIGEN_HIPCC)
0926 EIGEN_STRONG_INLINE __device__ Eigen::half __ldg(const Eigen::half* ptr) {
0927 return Eigen::half_impl::raw_uint16_to_half(__ldg(reinterpret_cast<const Eigen::numext::uint16_t*>(ptr)));
0928 }
0929 #endif
0930
0931 #if EIGEN_HAS_STD_HASH
0932 namespace std {
0933 template <>
0934 struct hash<Eigen::half> {
0935 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(const Eigen::half& a) const {
0936 return static_cast<std::size_t>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(a));
0937 }
0938 };
0939 }
0940 #endif
0941
0942 #endif