1*da0073e9SAndroid Build Coastguard Worker #pragma once
2*da0073e9SAndroid Build Coastguard Worker
3*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Macros.h>
4*da0073e9SAndroid Build Coastguard Worker #include <c10/util/bit_cast.h>
5*da0073e9SAndroid Build Coastguard Worker
6*da0073e9SAndroid Build Coastguard Worker #include <cstring>
7*da0073e9SAndroid Build Coastguard Worker #include <limits>
8*da0073e9SAndroid Build Coastguard Worker
9*da0073e9SAndroid Build Coastguard Worker #ifdef __CUDACC__
10*da0073e9SAndroid Build Coastguard Worker #include <cuda_fp16.h>
11*da0073e9SAndroid Build Coastguard Worker #endif
12*da0073e9SAndroid Build Coastguard Worker
13*da0073e9SAndroid Build Coastguard Worker #ifdef __HIPCC__
14*da0073e9SAndroid Build Coastguard Worker #include <hip/hip_fp16.h>
15*da0073e9SAndroid Build Coastguard Worker #endif
16*da0073e9SAndroid Build Coastguard Worker
17*da0073e9SAndroid Build Coastguard Worker #if defined(CL_SYCL_LANGUAGE_VERSION)
18*da0073e9SAndroid Build Coastguard Worker #include <CL/sycl.hpp> // for SYCL 1.2.1
19*da0073e9SAndroid Build Coastguard Worker #elif defined(SYCL_LANGUAGE_VERSION)
20*da0073e9SAndroid Build Coastguard Worker #include <sycl/sycl.hpp> // for SYCL 2020
21*da0073e9SAndroid Build Coastguard Worker #endif
22*da0073e9SAndroid Build Coastguard Worker
23*da0073e9SAndroid Build Coastguard Worker #if (defined(CPU_CAPABILITY_AVX2) || defined(CPU_CAPABILITY_AVX512)) && \
24*da0073e9SAndroid Build Coastguard Worker !defined(__APPLE__)
25*da0073e9SAndroid Build Coastguard Worker #include <ATen/cpu/vec/vec_half.h>
26*da0073e9SAndroid Build Coastguard Worker #endif
27*da0073e9SAndroid Build Coastguard Worker
28*da0073e9SAndroid Build Coastguard Worker C10_CLANG_DIAGNOSTIC_PUSH()
29*da0073e9SAndroid Build Coastguard Worker #if C10_CLANG_HAS_WARNING("-Wimplicit-int-float-conversion")
30*da0073e9SAndroid Build Coastguard Worker C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-int-float-conversion")
31*da0073e9SAndroid Build Coastguard Worker #endif
32*da0073e9SAndroid Build Coastguard Worker
33*da0073e9SAndroid Build Coastguard Worker namespace c10 {
34*da0073e9SAndroid Build Coastguard Worker
35*da0073e9SAndroid Build Coastguard Worker #if defined(__aarch64__) && !defined(__CUDACC__)
36*da0073e9SAndroid Build Coastguard Worker /// Constructors
Half(float16_t value)37*da0073e9SAndroid Build Coastguard Worker inline Half::Half(float16_t value) : x(detail::fp16_to_bits(value)) {}
float16_t()38*da0073e9SAndroid Build Coastguard Worker inline Half::operator float16_t() const {
39*da0073e9SAndroid Build Coastguard Worker return detail::fp16_from_bits(x);
40*da0073e9SAndroid Build Coastguard Worker }
41*da0073e9SAndroid Build Coastguard Worker #else
42*da0073e9SAndroid Build Coastguard Worker
43*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::Half(float value)
44*da0073e9SAndroid Build Coastguard Worker :
45*da0073e9SAndroid Build Coastguard Worker #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
46*da0073e9SAndroid Build Coastguard Worker x(__half_as_short(__float2half(value)))
47*da0073e9SAndroid Build Coastguard Worker #elif defined(__SYCL_DEVICE_ONLY__)
48*da0073e9SAndroid Build Coastguard Worker x(c10::bit_cast<uint16_t>(sycl::half(value)))
49*da0073e9SAndroid Build Coastguard Worker #elif (defined(CPU_CAPABILITY_AVX2) || defined(CPU_CAPABILITY_AVX512)) && \
50*da0073e9SAndroid Build Coastguard Worker !defined(__APPLE__)
51*da0073e9SAndroid Build Coastguard Worker x(at::vec::float2half_scalar(value))
52*da0073e9SAndroid Build Coastguard Worker #else
53*da0073e9SAndroid Build Coastguard Worker x(detail::fp16_ieee_from_fp32_value(value))
54*da0073e9SAndroid Build Coastguard Worker #endif
55*da0073e9SAndroid Build Coastguard Worker {
56*da0073e9SAndroid Build Coastguard Worker }
57*da0073e9SAndroid Build Coastguard Worker
58*da0073e9SAndroid Build Coastguard Worker /// Implicit conversions
59*da0073e9SAndroid Build Coastguard Worker
60*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::operator float() const {
61*da0073e9SAndroid Build Coastguard Worker #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
62*da0073e9SAndroid Build Coastguard Worker return __half2float(*reinterpret_cast<const __half*>(&x));
63*da0073e9SAndroid Build Coastguard Worker #elif defined(__SYCL_DEVICE_ONLY__)
64*da0073e9SAndroid Build Coastguard Worker return float(c10::bit_cast<sycl::half>(x));
65*da0073e9SAndroid Build Coastguard Worker #elif (defined(CPU_CAPABILITY_AVX2) || defined(CPU_CAPABILITY_AVX512)) && \
66*da0073e9SAndroid Build Coastguard Worker !defined(__APPLE__)
67*da0073e9SAndroid Build Coastguard Worker return at::vec::half2float_scalar(x);
68*da0073e9SAndroid Build Coastguard Worker #elif defined(__aarch64__) && !defined(__CUDACC__)
69*da0073e9SAndroid Build Coastguard Worker return detail::native_fp16_to_fp32_value(x);
70*da0073e9SAndroid Build Coastguard Worker #else
71*da0073e9SAndroid Build Coastguard Worker return detail::fp16_ieee_to_fp32_value(x);
72*da0073e9SAndroid Build Coastguard Worker #endif
73*da0073e9SAndroid Build Coastguard Worker }
74*da0073e9SAndroid Build Coastguard Worker
75*da0073e9SAndroid Build Coastguard Worker #endif /* !defined(__aarch64__) || defined(__CUDACC__) \
76*da0073e9SAndroid Build Coastguard Worker */
77*da0073e9SAndroid Build Coastguard Worker
78*da0073e9SAndroid Build Coastguard Worker #if defined(__CUDACC__) || defined(__HIPCC__)
Half(const __half & value)79*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::Half(const __half& value) {
80*da0073e9SAndroid Build Coastguard Worker x = *reinterpret_cast<const unsigned short*>(&value);
81*da0073e9SAndroid Build Coastguard Worker }
__half()82*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::operator __half() const {
83*da0073e9SAndroid Build Coastguard Worker return *reinterpret_cast<const __half*>(&x);
84*da0073e9SAndroid Build Coastguard Worker }
85*da0073e9SAndroid Build Coastguard Worker #endif
86*da0073e9SAndroid Build Coastguard Worker
87*da0073e9SAndroid Build Coastguard Worker #ifdef SYCL_LANGUAGE_VERSION
Half(const sycl::half & value)88*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::Half(const sycl::half& value) {
89*da0073e9SAndroid Build Coastguard Worker x = *reinterpret_cast<const unsigned short*>(&value);
90*da0073e9SAndroid Build Coastguard Worker }
half()91*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half::operator sycl::half() const {
92*da0073e9SAndroid Build Coastguard Worker return *reinterpret_cast<const sycl::half*>(&x);
93*da0073e9SAndroid Build Coastguard Worker }
94*da0073e9SAndroid Build Coastguard Worker #endif
95*da0073e9SAndroid Build Coastguard Worker
96*da0073e9SAndroid Build Coastguard Worker // CUDA intrinsics
97*da0073e9SAndroid Build Coastguard Worker
98*da0073e9SAndroid Build Coastguard Worker #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 350)) || \
99*da0073e9SAndroid Build Coastguard Worker (defined(__clang__) && defined(__CUDA__))
__ldg(const Half * ptr)100*da0073e9SAndroid Build Coastguard Worker inline __device__ Half __ldg(const Half* ptr) {
101*da0073e9SAndroid Build Coastguard Worker return __ldg(reinterpret_cast<const __half*>(ptr));
102*da0073e9SAndroid Build Coastguard Worker }
103*da0073e9SAndroid Build Coastguard Worker #endif
104*da0073e9SAndroid Build Coastguard Worker
105*da0073e9SAndroid Build Coastguard Worker /// Arithmetic
106*da0073e9SAndroid Build Coastguard Worker
107*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator+(const Half& a, const Half& b) {
108*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) + static_cast<float>(b);
109*da0073e9SAndroid Build Coastguard Worker }
110*da0073e9SAndroid Build Coastguard Worker
111*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(const Half& a, const Half& b) {
112*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) - static_cast<float>(b);
113*da0073e9SAndroid Build Coastguard Worker }
114*da0073e9SAndroid Build Coastguard Worker
115*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator*(const Half& a, const Half& b) {
116*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) * static_cast<float>(b);
117*da0073e9SAndroid Build Coastguard Worker }
118*da0073e9SAndroid Build Coastguard Worker
119*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator/(const Half& a, const Half& b)
120*da0073e9SAndroid Build Coastguard Worker __ubsan_ignore_float_divide_by_zero__ {
121*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) / static_cast<float>(b);
122*da0073e9SAndroid Build Coastguard Worker }
123*da0073e9SAndroid Build Coastguard Worker
124*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(const Half& a) {
125*da0073e9SAndroid Build Coastguard Worker #if (defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530) || \
126*da0073e9SAndroid Build Coastguard Worker defined(__HIP_DEVICE_COMPILE__)
127*da0073e9SAndroid Build Coastguard Worker return __hneg(a);
128*da0073e9SAndroid Build Coastguard Worker #elif defined(__SYCL_DEVICE_ONLY__)
129*da0073e9SAndroid Build Coastguard Worker return -c10::bit_cast<sycl::half>(a);
130*da0073e9SAndroid Build Coastguard Worker #else
131*da0073e9SAndroid Build Coastguard Worker return -static_cast<float>(a);
132*da0073e9SAndroid Build Coastguard Worker #endif
133*da0073e9SAndroid Build Coastguard Worker }
134*da0073e9SAndroid Build Coastguard Worker
135*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half& operator+=(Half& a, const Half& b) {
136*da0073e9SAndroid Build Coastguard Worker a = a + b;
137*da0073e9SAndroid Build Coastguard Worker return a;
138*da0073e9SAndroid Build Coastguard Worker }
139*da0073e9SAndroid Build Coastguard Worker
140*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half& operator-=(Half& a, const Half& b) {
141*da0073e9SAndroid Build Coastguard Worker a = a - b;
142*da0073e9SAndroid Build Coastguard Worker return a;
143*da0073e9SAndroid Build Coastguard Worker }
144*da0073e9SAndroid Build Coastguard Worker
145*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half& operator*=(Half& a, const Half& b) {
146*da0073e9SAndroid Build Coastguard Worker a = a * b;
147*da0073e9SAndroid Build Coastguard Worker return a;
148*da0073e9SAndroid Build Coastguard Worker }
149*da0073e9SAndroid Build Coastguard Worker
150*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half& operator/=(Half& a, const Half& b) {
151*da0073e9SAndroid Build Coastguard Worker a = a / b;
152*da0073e9SAndroid Build Coastguard Worker return a;
153*da0073e9SAndroid Build Coastguard Worker }
154*da0073e9SAndroid Build Coastguard Worker
155*da0073e9SAndroid Build Coastguard Worker /// Arithmetic with floats
156*da0073e9SAndroid Build Coastguard Worker
157*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator+(Half a, float b) {
158*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) + b;
159*da0073e9SAndroid Build Coastguard Worker }
160*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator-(Half a, float b) {
161*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) - b;
162*da0073e9SAndroid Build Coastguard Worker }
163*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator*(Half a, float b) {
164*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) * b;
165*da0073e9SAndroid Build Coastguard Worker }
166*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator/(Half a, float b)
167*da0073e9SAndroid Build Coastguard Worker __ubsan_ignore_float_divide_by_zero__ {
168*da0073e9SAndroid Build Coastguard Worker return static_cast<float>(a) / b;
169*da0073e9SAndroid Build Coastguard Worker }
170*da0073e9SAndroid Build Coastguard Worker
171*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator+(float a, Half b) {
172*da0073e9SAndroid Build Coastguard Worker return a + static_cast<float>(b);
173*da0073e9SAndroid Build Coastguard Worker }
174*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator-(float a, Half b) {
175*da0073e9SAndroid Build Coastguard Worker return a - static_cast<float>(b);
176*da0073e9SAndroid Build Coastguard Worker }
177*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator*(float a, Half b) {
178*da0073e9SAndroid Build Coastguard Worker return a * static_cast<float>(b);
179*da0073e9SAndroid Build Coastguard Worker }
180*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float operator/(float a, Half b)
181*da0073e9SAndroid Build Coastguard Worker __ubsan_ignore_float_divide_by_zero__ {
182*da0073e9SAndroid Build Coastguard Worker return a / static_cast<float>(b);
183*da0073e9SAndroid Build Coastguard Worker }
184*da0073e9SAndroid Build Coastguard Worker
185*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float& operator+=(float& a, const Half& b) {
186*da0073e9SAndroid Build Coastguard Worker return a += static_cast<float>(b);
187*da0073e9SAndroid Build Coastguard Worker }
188*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float& operator-=(float& a, const Half& b) {
189*da0073e9SAndroid Build Coastguard Worker return a -= static_cast<float>(b);
190*da0073e9SAndroid Build Coastguard Worker }
191*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float& operator*=(float& a, const Half& b) {
192*da0073e9SAndroid Build Coastguard Worker return a *= static_cast<float>(b);
193*da0073e9SAndroid Build Coastguard Worker }
194*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE float& operator/=(float& a, const Half& b) {
195*da0073e9SAndroid Build Coastguard Worker return a /= static_cast<float>(b);
196*da0073e9SAndroid Build Coastguard Worker }
197*da0073e9SAndroid Build Coastguard Worker
198*da0073e9SAndroid Build Coastguard Worker /// Arithmetic with doubles
199*da0073e9SAndroid Build Coastguard Worker
200*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator+(Half a, double b) {
201*da0073e9SAndroid Build Coastguard Worker return static_cast<double>(a) + b;
202*da0073e9SAndroid Build Coastguard Worker }
203*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator-(Half a, double b) {
204*da0073e9SAndroid Build Coastguard Worker return static_cast<double>(a) - b;
205*da0073e9SAndroid Build Coastguard Worker }
206*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator*(Half a, double b) {
207*da0073e9SAndroid Build Coastguard Worker return static_cast<double>(a) * b;
208*da0073e9SAndroid Build Coastguard Worker }
209*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator/(Half a, double b)
210*da0073e9SAndroid Build Coastguard Worker __ubsan_ignore_float_divide_by_zero__ {
211*da0073e9SAndroid Build Coastguard Worker return static_cast<double>(a) / b;
212*da0073e9SAndroid Build Coastguard Worker }
213*da0073e9SAndroid Build Coastguard Worker
214*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator+(double a, Half b) {
215*da0073e9SAndroid Build Coastguard Worker return a + static_cast<double>(b);
216*da0073e9SAndroid Build Coastguard Worker }
217*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator-(double a, Half b) {
218*da0073e9SAndroid Build Coastguard Worker return a - static_cast<double>(b);
219*da0073e9SAndroid Build Coastguard Worker }
220*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator*(double a, Half b) {
221*da0073e9SAndroid Build Coastguard Worker return a * static_cast<double>(b);
222*da0073e9SAndroid Build Coastguard Worker }
223*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE double operator/(double a, Half b)
224*da0073e9SAndroid Build Coastguard Worker __ubsan_ignore_float_divide_by_zero__ {
225*da0073e9SAndroid Build Coastguard Worker return a / static_cast<double>(b);
226*da0073e9SAndroid Build Coastguard Worker }
227*da0073e9SAndroid Build Coastguard Worker
228*da0073e9SAndroid Build Coastguard Worker /// Arithmetic with ints
229*da0073e9SAndroid Build Coastguard Worker
230*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator+(Half a, int b) {
231*da0073e9SAndroid Build Coastguard Worker return a + static_cast<Half>(b);
232*da0073e9SAndroid Build Coastguard Worker }
233*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(Half a, int b) {
234*da0073e9SAndroid Build Coastguard Worker return a - static_cast<Half>(b);
235*da0073e9SAndroid Build Coastguard Worker }
236*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator*(Half a, int b) {
237*da0073e9SAndroid Build Coastguard Worker return a * static_cast<Half>(b);
238*da0073e9SAndroid Build Coastguard Worker }
239*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator/(Half a, int b) {
240*da0073e9SAndroid Build Coastguard Worker return a / static_cast<Half>(b);
241*da0073e9SAndroid Build Coastguard Worker }
242*da0073e9SAndroid Build Coastguard Worker
243*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator+(int a, Half b) {
244*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) + b;
245*da0073e9SAndroid Build Coastguard Worker }
246*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(int a, Half b) {
247*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) - b;
248*da0073e9SAndroid Build Coastguard Worker }
249*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator*(int a, Half b) {
250*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) * b;
251*da0073e9SAndroid Build Coastguard Worker }
252*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator/(int a, Half b) {
253*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) / b;
254*da0073e9SAndroid Build Coastguard Worker }
255*da0073e9SAndroid Build Coastguard Worker
256*da0073e9SAndroid Build Coastguard Worker //// Arithmetic with int64_t
257*da0073e9SAndroid Build Coastguard Worker
258*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator+(Half a, int64_t b) {
259*da0073e9SAndroid Build Coastguard Worker return a + static_cast<Half>(b);
260*da0073e9SAndroid Build Coastguard Worker }
261*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(Half a, int64_t b) {
262*da0073e9SAndroid Build Coastguard Worker return a - static_cast<Half>(b);
263*da0073e9SAndroid Build Coastguard Worker }
264*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator*(Half a, int64_t b) {
265*da0073e9SAndroid Build Coastguard Worker return a * static_cast<Half>(b);
266*da0073e9SAndroid Build Coastguard Worker }
267*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator/(Half a, int64_t b) {
268*da0073e9SAndroid Build Coastguard Worker return a / static_cast<Half>(b);
269*da0073e9SAndroid Build Coastguard Worker }
270*da0073e9SAndroid Build Coastguard Worker
271*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator+(int64_t a, Half b) {
272*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) + b;
273*da0073e9SAndroid Build Coastguard Worker }
274*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator-(int64_t a, Half b) {
275*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) - b;
276*da0073e9SAndroid Build Coastguard Worker }
277*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator*(int64_t a, Half b) {
278*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) * b;
279*da0073e9SAndroid Build Coastguard Worker }
280*da0073e9SAndroid Build Coastguard Worker inline C10_HOST_DEVICE Half operator/(int64_t a, Half b) {
281*da0073e9SAndroid Build Coastguard Worker return static_cast<Half>(a) / b;
282*da0073e9SAndroid Build Coastguard Worker }
283*da0073e9SAndroid Build Coastguard Worker
284*da0073e9SAndroid Build Coastguard Worker /// NOTE: we do not define comparisons directly and instead rely on the implicit
285*da0073e9SAndroid Build Coastguard Worker /// conversion from c10::Half to float.
286*da0073e9SAndroid Build Coastguard Worker
287*da0073e9SAndroid Build Coastguard Worker } // namespace c10
288*da0073e9SAndroid Build Coastguard Worker
289*da0073e9SAndroid Build Coastguard Worker namespace std {
290*da0073e9SAndroid Build Coastguard Worker
291*da0073e9SAndroid Build Coastguard Worker template <>
292*da0073e9SAndroid Build Coastguard Worker class numeric_limits<c10::Half> {
293*da0073e9SAndroid Build Coastguard Worker public:
294*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_specialized = true;
295*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_signed = true;
296*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_integer = false;
297*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_exact = false;
298*da0073e9SAndroid Build Coastguard Worker static constexpr bool has_infinity = true;
299*da0073e9SAndroid Build Coastguard Worker static constexpr bool has_quiet_NaN = true;
300*da0073e9SAndroid Build Coastguard Worker static constexpr bool has_signaling_NaN = true;
301*da0073e9SAndroid Build Coastguard Worker static constexpr auto has_denorm = numeric_limits<float>::has_denorm;
302*da0073e9SAndroid Build Coastguard Worker static constexpr auto has_denorm_loss =
303*da0073e9SAndroid Build Coastguard Worker numeric_limits<float>::has_denorm_loss;
304*da0073e9SAndroid Build Coastguard Worker static constexpr auto round_style = numeric_limits<float>::round_style;
305*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_iec559 = true;
306*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_bounded = true;
307*da0073e9SAndroid Build Coastguard Worker static constexpr bool is_modulo = false;
308*da0073e9SAndroid Build Coastguard Worker static constexpr int digits = 11;
309*da0073e9SAndroid Build Coastguard Worker static constexpr int digits10 = 3;
310*da0073e9SAndroid Build Coastguard Worker static constexpr int max_digits10 = 5;
311*da0073e9SAndroid Build Coastguard Worker static constexpr int radix = 2;
312*da0073e9SAndroid Build Coastguard Worker static constexpr int min_exponent = -13;
313*da0073e9SAndroid Build Coastguard Worker static constexpr int min_exponent10 = -4;
314*da0073e9SAndroid Build Coastguard Worker static constexpr int max_exponent = 16;
315*da0073e9SAndroid Build Coastguard Worker static constexpr int max_exponent10 = 4;
316*da0073e9SAndroid Build Coastguard Worker static constexpr auto traps = numeric_limits<float>::traps;
317*da0073e9SAndroid Build Coastguard Worker static constexpr auto tinyness_before =
318*da0073e9SAndroid Build Coastguard Worker numeric_limits<float>::tinyness_before;
min()319*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half min() {
320*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x0400, c10::Half::from_bits());
321*da0073e9SAndroid Build Coastguard Worker }
lowest()322*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half lowest() {
323*da0073e9SAndroid Build Coastguard Worker return c10::Half(0xFBFF, c10::Half::from_bits());
324*da0073e9SAndroid Build Coastguard Worker }
max()325*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half max() {
326*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x7BFF, c10::Half::from_bits());
327*da0073e9SAndroid Build Coastguard Worker }
epsilon()328*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half epsilon() {
329*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x1400, c10::Half::from_bits());
330*da0073e9SAndroid Build Coastguard Worker }
round_error()331*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half round_error() {
332*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x3800, c10::Half::from_bits());
333*da0073e9SAndroid Build Coastguard Worker }
infinity()334*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half infinity() {
335*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x7C00, c10::Half::from_bits());
336*da0073e9SAndroid Build Coastguard Worker }
quiet_NaN()337*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half quiet_NaN() {
338*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x7E00, c10::Half::from_bits());
339*da0073e9SAndroid Build Coastguard Worker }
signaling_NaN()340*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half signaling_NaN() {
341*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x7D00, c10::Half::from_bits());
342*da0073e9SAndroid Build Coastguard Worker }
denorm_min()343*da0073e9SAndroid Build Coastguard Worker static constexpr c10::Half denorm_min() {
344*da0073e9SAndroid Build Coastguard Worker return c10::Half(0x0001, c10::Half::from_bits());
345*da0073e9SAndroid Build Coastguard Worker }
346*da0073e9SAndroid Build Coastguard Worker };
347*da0073e9SAndroid Build Coastguard Worker
348*da0073e9SAndroid Build Coastguard Worker } // namespace std
349*da0073e9SAndroid Build Coastguard Worker
350*da0073e9SAndroid Build Coastguard Worker C10_CLANG_DIAGNOSTIC_POP()
351