numba-cuda 0.9.0__py3-none-any.whl → 0.10.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- numba_cuda/VERSION +1 -1
- numba_cuda/numba/cuda/compiler.py +35 -3
- numba_cuda/numba/cuda/cuda_bf16.py +5155 -0
- numba_cuda/numba/cuda/cuda_paths.py +2 -0
- numba_cuda/numba/cuda/cudadecl.py +0 -42
- numba_cuda/numba/cuda/cudadrv/linkable_code.py +11 -2
- numba_cuda/numba/cuda/cudadrv/nvrtc.py +10 -3
- numba_cuda/numba/cuda/cudaimpl.py +0 -63
- numba_cuda/numba/cuda/debuginfo.py +92 -2
- numba_cuda/numba/cuda/decorators.py +27 -1
- numba_cuda/numba/cuda/device_init.py +4 -5
- numba_cuda/numba/cuda/dispatcher.py +4 -3
- numba_cuda/numba/cuda/extending.py +54 -0
- numba_cuda/numba/cuda/include/11/cuda_bf16.h +3749 -0
- numba_cuda/numba/cuda/include/11/cuda_bf16.hpp +2683 -0
- numba_cuda/numba/cuda/{cuda_fp16.h → include/11/cuda_fp16.h} +550 -387
- numba_cuda/numba/cuda/{cuda_fp16.hpp → include/11/cuda_fp16.hpp} +465 -316
- numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
- numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
- numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
- numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
- numba_cuda/numba/cuda/intrinsic_wrapper.py +0 -39
- numba_cuda/numba/cuda/intrinsics.py +172 -1
- numba_cuda/numba/cuda/lowering.py +43 -0
- numba_cuda/numba/cuda/stubs.py +0 -11
- numba_cuda/numba/cuda/target.py +28 -0
- numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +4 -2
- numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +257 -0
- numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +46 -0
- numba_cuda/numba/cuda/tests/cudapy/test_enums.py +18 -0
- numba_cuda/numba/cuda/tests/cudapy/test_extending.py +4 -2
- numba_cuda/numba/cuda/tests/cudapy/test_inline.py +156 -0
- numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +50 -5
- numba_cuda/numba/cuda/vector_types.py +3 -1
- numba_cuda/numba/cuda/vectorizers.py +1 -1
- {numba_cuda-0.9.0.dist-info → numba_cuda-0.10.1.dist-info}/METADATA +1 -1
- {numba_cuda-0.9.0.dist-info → numba_cuda-0.10.1.dist-info}/RECORD +43 -33
- {numba_cuda-0.9.0.dist-info → numba_cuda-0.10.1.dist-info}/WHEEL +1 -1
- {numba_cuda-0.9.0.dist-info → numba_cuda-0.10.1.dist-info}/licenses/LICENSE +0 -0
- {numba_cuda-0.9.0.dist-info → numba_cuda-0.10.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,3865 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 1993-2024 NVIDIA Corporation. All rights reserved.
|
3
|
+
*
|
4
|
+
* NOTICE TO LICENSEE:
|
5
|
+
*
|
6
|
+
* This source code and/or documentation ("Licensed Deliverables") are
|
7
|
+
* subject to NVIDIA intellectual property rights under U.S. and
|
8
|
+
* international Copyright laws.
|
9
|
+
*
|
10
|
+
* These Licensed Deliverables contained herein is PROPRIETARY and
|
11
|
+
* CONFIDENTIAL to NVIDIA and is being provided under the terms and
|
12
|
+
* conditions of a form of NVIDIA software license agreement by and
|
13
|
+
* between NVIDIA and Licensee ("License Agreement") or electronically
|
14
|
+
* accepted by Licensee. Notwithstanding any terms or conditions to
|
15
|
+
* the contrary in the License Agreement, reproduction or disclosure
|
16
|
+
* of the Licensed Deliverables to any third party without the express
|
17
|
+
* written consent of NVIDIA is prohibited.
|
18
|
+
*
|
19
|
+
* NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
|
20
|
+
* LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE
|
21
|
+
* SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE. IT IS
|
22
|
+
* PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
|
23
|
+
* NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED
|
24
|
+
* DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
|
25
|
+
* NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
26
|
+
* NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
|
27
|
+
* LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
|
28
|
+
* SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
|
29
|
+
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
30
|
+
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
31
|
+
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
32
|
+
* OF THESE LICENSED DELIVERABLES.
|
33
|
+
*
|
34
|
+
* U.S. Government End Users. These Licensed Deliverables are a
|
35
|
+
* "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT
|
36
|
+
* 1995), consisting of "commercial computer software" and "commercial
|
37
|
+
* computer software documentation" as such terms are used in 48
|
38
|
+
* C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government
|
39
|
+
* only as a commercial end item. Consistent with 48 C.F.R.12.212 and
|
40
|
+
* 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all
|
41
|
+
* U.S. Government End Users acquire the Licensed Deliverables with
|
42
|
+
* only those rights set forth herein.
|
43
|
+
*
|
44
|
+
* Any use of the Licensed Deliverables in individual and commercial
|
45
|
+
* software must include, in the user documentation and internal
|
46
|
+
* comments to the code, the above Disclaimer and U.S. Government End
|
47
|
+
* Users Notice.
|
48
|
+
*/
|
49
|
+
|
50
|
+
#if !defined(__CUDA_BF16_HPP__)
|
51
|
+
#define __CUDA_BF16_HPP__
|
52
|
+
|
53
|
+
#if !defined(__CUDA_BF16_H__)
|
54
|
+
#error "Do not include this file directly. Instead, include cuda_bf16.h."
|
55
|
+
#endif
|
56
|
+
|
57
|
+
#if !defined(IF_DEVICE_OR_CUDACC)
|
58
|
+
#if defined(__CUDACC__)
|
59
|
+
#define IF_DEVICE_OR_CUDACC(d, c, f) NV_IF_ELSE_TARGET(NV_IS_DEVICE, d, c)
|
60
|
+
#else
|
61
|
+
#define IF_DEVICE_OR_CUDACC(d, c, f) NV_IF_ELSE_TARGET(NV_IS_DEVICE, d, f)
|
62
|
+
#endif
|
63
|
+
#endif
|
64
|
+
|
65
|
+
/* All other definitions in this file are only visible to C++ compilers */
|
66
|
+
#if defined(__cplusplus)
|
67
|
+
/**
|
68
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
69
|
+
* \brief Defines floating-point positive infinity value for the \p nv_bfloat16 data type
|
70
|
+
*/
|
71
|
+
#define CUDART_INF_BF16 __ushort_as_bfloat16((unsigned short)0x7F80U)
|
72
|
+
/**
|
73
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
74
|
+
* \brief Defines canonical NaN value for the \p nv_bfloat16 data type
|
75
|
+
*/
|
76
|
+
#define CUDART_NAN_BF16 __ushort_as_bfloat16((unsigned short)0x7FFFU)
|
77
|
+
/**
|
78
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
79
|
+
* \brief Defines a minimum representable (denormalized) value for the \p nv_bfloat16 data type
|
80
|
+
*/
|
81
|
+
#define CUDART_MIN_DENORM_BF16 __ushort_as_bfloat16((unsigned short)0x0001U)
|
82
|
+
/**
|
83
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
84
|
+
* \brief Defines a maximum representable value for the \p nv_bfloat16 data type
|
85
|
+
*/
|
86
|
+
#define CUDART_MAX_NORMAL_BF16 __ushort_as_bfloat16((unsigned short)0x7F7FU)
|
87
|
+
/**
|
88
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
89
|
+
* \brief Defines a negative zero value for the \p nv_bfloat16 data type
|
90
|
+
*/
|
91
|
+
#define CUDART_NEG_ZERO_BF16 __ushort_as_bfloat16((unsigned short)0x8000U)
|
92
|
+
/**
|
93
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
94
|
+
* \brief Defines a positive zero value for the \p nv_bfloat16 data type
|
95
|
+
*/
|
96
|
+
#define CUDART_ZERO_BF16 __ushort_as_bfloat16((unsigned short)0x0000U)
|
97
|
+
/**
|
98
|
+
* \ingroup CUDA_MATH_INTRINSIC_BFLOAT16_CONSTANTS
|
99
|
+
* \brief Defines a value of 1.0 for the \p nv_bfloat16 data type
|
100
|
+
*/
|
101
|
+
#define CUDART_ONE_BF16 __ushort_as_bfloat16((unsigned short)0x3F80U)
|
102
|
+
|
103
|
+
#if !(defined __DOXYGEN_ONLY__)
|
104
|
+
|
105
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(const __nv_bfloat16_raw &hr) { __x = hr.x; return *this; }
|
106
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ volatile __nv_bfloat16 &__nv_bfloat16::operator=(const __nv_bfloat16_raw &hr) volatile { __x = hr.x; return *this; }
|
107
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ volatile __nv_bfloat16 &__nv_bfloat16::operator=(const volatile __nv_bfloat16_raw &hr) volatile { __x = hr.x; return *this; }
|
108
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator __nv_bfloat16_raw() const { __nv_bfloat16_raw ret; ret.x = __x; return ret; }
|
109
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator __nv_bfloat16_raw() const volatile { __nv_bfloat16_raw ret; ret.x = __x; return ret; }
|
110
|
+
|
111
|
+
#if !defined(__CUDA_NO_BFLOAT16_CONVERSIONS__)
|
112
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator float() const { return __bfloat162float(*this); }
|
113
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(const float f) { __x = __float2bfloat16(f).__x; return *this; }
|
114
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(const double f) { __x = __double2bfloat16(f).__x; return *this; }
|
115
|
+
|
116
|
+
/*
|
117
|
+
* Implicit type conversions to/from integer types were only available to nvcc compilation.
|
118
|
+
* Introducing them for all compilers is a potentially breaking change that may affect
|
119
|
+
* overloads resolution and will require users to update their code.
|
120
|
+
* Define __CUDA_BF16_DISABLE_IMPLICIT_INTEGER_CONVERTS_FOR_HOST_COMPILERS__ to opt-out.
|
121
|
+
*/
|
122
|
+
#if !(defined __CUDA_BF16_DISABLE_IMPLICIT_INTEGER_CONVERTS_FOR_HOST_COMPILERS__) || (defined __CUDACC__)
|
123
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator signed char() const { return __bfloat162char_rz(*this); }
|
124
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator unsigned char() const { return __bfloat162uchar_rz(*this); }
|
125
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator char() const {
|
126
|
+
char value;
|
127
|
+
/* Suppress VS warning: warning C4127: conditional expression is constant */
|
128
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
129
|
+
#pragma warning (push)
|
130
|
+
#pragma warning (disable: 4127)
|
131
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
132
|
+
if (((char)-1) < (char)0)
|
133
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
134
|
+
#pragma warning (pop)
|
135
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
136
|
+
{
|
137
|
+
value = static_cast<char>(__bfloat162char_rz(*this));
|
138
|
+
}
|
139
|
+
else
|
140
|
+
{
|
141
|
+
value = static_cast<char>(__bfloat162uchar_rz(*this));
|
142
|
+
}
|
143
|
+
return value;
|
144
|
+
}
|
145
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator short() const { return __bfloat162short_rz(*this); }
|
146
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator unsigned short() const { return __bfloat162ushort_rz(*this); }
|
147
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator int() const { return __bfloat162int_rz(*this); }
|
148
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator unsigned int() const { return __bfloat162uint_rz(*this); }
|
149
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator long() const {
|
150
|
+
long retval;
|
151
|
+
/* Suppress VS warning: warning C4127: conditional expression is constant */
|
152
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
153
|
+
#pragma warning (push)
|
154
|
+
#pragma warning (disable: 4127)
|
155
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
156
|
+
if (sizeof(long) == sizeof(long long))
|
157
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
158
|
+
#pragma warning (pop)
|
159
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
160
|
+
{
|
161
|
+
retval = static_cast<long>(__bfloat162ll_rz(*this));
|
162
|
+
}
|
163
|
+
else
|
164
|
+
{
|
165
|
+
retval = static_cast<long>(__bfloat162int_rz(*this));
|
166
|
+
}
|
167
|
+
return retval;
|
168
|
+
}
|
169
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator unsigned long() const {
|
170
|
+
unsigned long retval;
|
171
|
+
/* Suppress VS warning: warning C4127: conditional expression is constant */
|
172
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
173
|
+
#pragma warning (push)
|
174
|
+
#pragma warning (disable: 4127)
|
175
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
176
|
+
if (sizeof(unsigned long) == sizeof(unsigned long long))
|
177
|
+
#if defined(_MSC_VER) && !defined(__CUDA_ARCH__)
|
178
|
+
#pragma warning (pop)
|
179
|
+
#endif /* _MSC_VER && !defined(__CUDA_ARCH__) */
|
180
|
+
{
|
181
|
+
retval = static_cast<unsigned long>(__bfloat162ull_rz(*this));
|
182
|
+
}
|
183
|
+
else
|
184
|
+
{
|
185
|
+
retval = static_cast<unsigned long>(__bfloat162uint_rz(*this));
|
186
|
+
}
|
187
|
+
return retval;
|
188
|
+
}
|
189
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator long long() const { return __bfloat162ll_rz(*this); }
|
190
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16::operator unsigned long long() const { return __bfloat162ull_rz(*this); }
|
191
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(short val) { __x = __short2bfloat16_rn(val).__x; return *this; }
|
192
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(unsigned short val) { __x = __ushort2bfloat16_rn(val).__x; return *this; }
|
193
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(int val) { __x = __int2bfloat16_rn(val).__x; return *this; }
|
194
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(unsigned int val) { __x = __uint2bfloat16_rn(val).__x; return *this; }
|
195
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(long long val) { __x = __ll2bfloat16_rn(val).__x; return *this; }
|
196
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat16 &__nv_bfloat16::operator=(unsigned long long val) { __x = __ull2bfloat16_rn(val).__x; return *this; }
|
197
|
+
#endif /* !(defined __CUDA_BF16_DISABLE_IMPLICIT_INTEGER_CONVERTS_FOR_HOST_COMPILERS__) || (defined __CUDACC__) */
|
198
|
+
#endif /* !defined(__CUDA_NO_BFLOAT16_CONVERSIONS__) */
|
199
|
+
|
200
|
+
|
201
|
+
#if !defined(__CUDA_NO_BFLOAT16_OPERATORS__)
|
202
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator+(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hadd(lh, rh); }
|
203
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator-(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hsub(lh, rh); }
|
204
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator*(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hmul(lh, rh); }
|
205
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator/(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hdiv(lh, rh); }
|
206
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator+=(__nv_bfloat16 &lh, const __nv_bfloat16 &rh) { lh = __hadd(lh, rh); return lh; }
|
207
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator-=(__nv_bfloat16 &lh, const __nv_bfloat16 &rh) { lh = __hsub(lh, rh); return lh; }
|
208
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator*=(__nv_bfloat16 &lh, const __nv_bfloat16 &rh) { lh = __hmul(lh, rh); return lh; }
|
209
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator/=(__nv_bfloat16 &lh, const __nv_bfloat16 &rh) { lh = __hdiv(lh, rh); return lh; }
|
210
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator++(__nv_bfloat16 &h) { __nv_bfloat16_raw one; one.x = 0x3F80U; h += one; return h; }
|
211
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 &operator--(__nv_bfloat16 &h) { __nv_bfloat16_raw one; one.x = 0x3F80U; h -= one; return h; }
|
212
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator++(__nv_bfloat16 &h, const int ignored)
|
213
|
+
{
|
214
|
+
// ignored on purpose. Parameter only needed to distinguish the function declaration from other types of operators.
|
215
|
+
static_cast<void>(ignored);
|
216
|
+
|
217
|
+
const __nv_bfloat16 ret = h;
|
218
|
+
__nv_bfloat16_raw one;
|
219
|
+
one.x = 0x3F80U;
|
220
|
+
h += one;
|
221
|
+
return ret;
|
222
|
+
}
|
223
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator--(__nv_bfloat16 &h, const int ignored)
|
224
|
+
{
|
225
|
+
// ignored on purpose. Parameter only needed to distinguish the function declaration from other types of operators.
|
226
|
+
static_cast<void>(ignored);
|
227
|
+
|
228
|
+
const __nv_bfloat16 ret = h;
|
229
|
+
__nv_bfloat16_raw one;
|
230
|
+
one.x = 0x3F80U;
|
231
|
+
h -= one;
|
232
|
+
return ret;
|
233
|
+
}
|
234
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator+(const __nv_bfloat16 &h) { return h; }
|
235
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat16 operator-(const __nv_bfloat16 &h) { return __hneg(h); }
|
236
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator==(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __heq(lh, rh); }
|
237
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator!=(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hneu(lh, rh); }
|
238
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator> (const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hgt(lh, rh); }
|
239
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator< (const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hlt(lh, rh); }
|
240
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator>=(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hge(lh, rh); }
|
241
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator<=(const __nv_bfloat16 &lh, const __nv_bfloat16 &rh) { return __hle(lh, rh); }
|
242
|
+
#endif /* !defined(__CUDA_NO_BFLOAT16_OPERATORS__) */
|
243
|
+
|
244
|
+
#if defined(__CPP_VERSION_AT_LEAST_11_BF16)
|
245
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162::__nv_bfloat162(__nv_bfloat162 &&src) {
|
246
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
247
|
+
__BFLOAT162_TO_UI(*this) = std::move(__BFLOAT162_TO_CUI(src));
|
248
|
+
,
|
249
|
+
this->x = src.x;
|
250
|
+
this->y = src.y;
|
251
|
+
)
|
252
|
+
}
|
253
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162 &__nv_bfloat162::operator=(__nv_bfloat162 &&src) {
|
254
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
255
|
+
__BFLOAT162_TO_UI(*this) = std::move(__BFLOAT162_TO_CUI(src));
|
256
|
+
,
|
257
|
+
this->x = src.x;
|
258
|
+
this->y = src.y;
|
259
|
+
)
|
260
|
+
return *this;
|
261
|
+
}
|
262
|
+
#else
|
263
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162::__nv_bfloat162() { }
|
264
|
+
#endif /* defined(__CPP_VERSION_AT_LEAST_11_BF16) */
|
265
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162::__nv_bfloat162(const __nv_bfloat162 &src) {
|
266
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
267
|
+
__BFLOAT162_TO_UI(*this) = __BFLOAT162_TO_CUI(src);
|
268
|
+
,
|
269
|
+
this->x = src.x;
|
270
|
+
this->y = src.y;
|
271
|
+
)
|
272
|
+
}
|
273
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162 &__nv_bfloat162::operator=(const __nv_bfloat162 &src) {
|
274
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
275
|
+
__BFLOAT162_TO_UI(*this) = __BFLOAT162_TO_CUI(src);
|
276
|
+
,
|
277
|
+
this->x = src.x;
|
278
|
+
this->y = src.y;
|
279
|
+
)
|
280
|
+
return *this;
|
281
|
+
}
|
282
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162::__nv_bfloat162(const __nv_bfloat162_raw &h2r ) {
|
283
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
284
|
+
__BFLOAT162_TO_UI(*this) = __BFLOAT162_TO_CUI(h2r);
|
285
|
+
,
|
286
|
+
__nv_bfloat16_raw tr;
|
287
|
+
tr.x = h2r.x;
|
288
|
+
this->x = static_cast<__nv_bfloat16>(tr);
|
289
|
+
tr.x = h2r.y;
|
290
|
+
this->y = static_cast<__nv_bfloat16>(tr);
|
291
|
+
)
|
292
|
+
}
|
293
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162 &__nv_bfloat162::operator=(const __nv_bfloat162_raw &h2r) {
|
294
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
295
|
+
__BFLOAT162_TO_UI(*this) = __BFLOAT162_TO_CUI(h2r);
|
296
|
+
,
|
297
|
+
__nv_bfloat16_raw tr;
|
298
|
+
tr.x = h2r.x;
|
299
|
+
this->x = static_cast<__nv_bfloat16>(tr);
|
300
|
+
tr.x = h2r.y;
|
301
|
+
this->y = static_cast<__nv_bfloat16>(tr);
|
302
|
+
)
|
303
|
+
return *this;
|
304
|
+
}
|
305
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_INLINE__ __nv_bfloat162::operator __nv_bfloat162_raw() const {
|
306
|
+
__nv_bfloat162_raw ret;
|
307
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
308
|
+
ret.x = 0U;
|
309
|
+
ret.y = 0U;
|
310
|
+
__BFLOAT162_TO_UI(ret) = __BFLOAT162_TO_CUI(*this);
|
311
|
+
,
|
312
|
+
ret.x = static_cast<__nv_bfloat16_raw>(this->x).x;
|
313
|
+
ret.y = static_cast<__nv_bfloat16_raw>(this->y).x;
|
314
|
+
)
|
315
|
+
return ret;
|
316
|
+
}
|
317
|
+
|
318
|
+
#if !defined(__CUDA_NO_BFLOAT162_OPERATORS__)
|
319
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator+(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hadd2(lh, rh); }
|
320
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator-(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hsub2(lh, rh); }
|
321
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator*(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hmul2(lh, rh); }
|
322
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator/(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __h2div(lh, rh); }
|
323
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162& operator+=(__nv_bfloat162 &lh, const __nv_bfloat162 &rh) { lh = __hadd2(lh, rh); return lh; }
|
324
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162& operator-=(__nv_bfloat162 &lh, const __nv_bfloat162 &rh) { lh = __hsub2(lh, rh); return lh; }
|
325
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162& operator*=(__nv_bfloat162 &lh, const __nv_bfloat162 &rh) { lh = __hmul2(lh, rh); return lh; }
|
326
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162& operator/=(__nv_bfloat162 &lh, const __nv_bfloat162 &rh) { lh = __h2div(lh, rh); return lh; }
|
327
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 &operator++(__nv_bfloat162 &h) { __nv_bfloat162_raw one; one.x = 0x3F80U; one.y = 0x3F80U; h = __hadd2(h, one); return h; }
|
328
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 &operator--(__nv_bfloat162 &h) { __nv_bfloat162_raw one; one.x = 0x3F80U; one.y = 0x3F80U; h = __hsub2(h, one); return h; }
|
329
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator++(__nv_bfloat162 &h, const int ignored)
|
330
|
+
{
|
331
|
+
// ignored on purpose. Parameter only needed to distinguish the function declaration from other types of operators.
|
332
|
+
static_cast<void>(ignored);
|
333
|
+
|
334
|
+
const __nv_bfloat162 ret = h;
|
335
|
+
__nv_bfloat162_raw one;
|
336
|
+
one.x = 0x3F80U;
|
337
|
+
one.y = 0x3F80U;
|
338
|
+
h = __hadd2(h, one);
|
339
|
+
return ret;
|
340
|
+
}
|
341
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator--(__nv_bfloat162 &h, const int ignored)
|
342
|
+
{
|
343
|
+
// ignored on purpose. Parameter only needed to distinguish the function declaration from other types of operators.
|
344
|
+
static_cast<void>(ignored);
|
345
|
+
|
346
|
+
const __nv_bfloat162 ret = h;
|
347
|
+
__nv_bfloat162_raw one;
|
348
|
+
one.x = 0x3F80U;
|
349
|
+
one.y = 0x3F80U;
|
350
|
+
h = __hsub2(h, one);
|
351
|
+
return ret;
|
352
|
+
}
|
353
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator+(const __nv_bfloat162 &h) { return h; }
|
354
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ __nv_bfloat162 operator-(const __nv_bfloat162 &h) { return __hneg2(h); }
|
355
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator==(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hbeq2(lh, rh); }
|
356
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator!=(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hbneu2(lh, rh); }
|
357
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator>(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hbgt2(lh, rh); }
|
358
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator<(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hblt2(lh, rh); }
|
359
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator>=(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hbge2(lh, rh); }
|
360
|
+
__CUDA_HOSTDEVICE__ __CUDA_BF16_FORCEINLINE__ bool operator<=(const __nv_bfloat162 &lh, const __nv_bfloat162 &rh) { return __hble2(lh, rh); }
|
361
|
+
#endif /* !defined(__CUDA_NO_BFLOAT162_OPERATORS__) */
|
362
|
+
|
363
|
+
/* Restore warning for multiple assignment operators */
|
364
|
+
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
365
|
+
#pragma warning( pop )
|
366
|
+
#endif /* defined(_MSC_VER) && _MSC_VER >= 1500 */
|
367
|
+
|
368
|
+
/* Restore -Weffc++ warnings from here on */
|
369
|
+
#if defined(__GNUC__)
|
370
|
+
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
371
|
+
#pragma GCC diagnostic pop
|
372
|
+
#endif /* __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) */
|
373
|
+
#endif /* defined(__GNUC__) */
|
374
|
+
|
375
|
+
#undef __CUDA_HOSTDEVICE__
|
376
|
+
#undef __CUDA_ALIGN__
|
377
|
+
|
378
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __internal_float_as_uint(const float f)
|
379
|
+
{
|
380
|
+
unsigned int u;
|
381
|
+
IF_DEVICE_OR_CUDACC(
|
382
|
+
u = __float_as_uint(f);
|
383
|
+
,
|
384
|
+
memcpy(&u, &f, sizeof(f));
|
385
|
+
,
|
386
|
+
std::memcpy(&u, &f, sizeof(f));
|
387
|
+
)
|
388
|
+
return u;
|
389
|
+
}
|
390
|
+
|
391
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __internal_uint_as_float(const unsigned int u)
|
392
|
+
{
|
393
|
+
float f;
|
394
|
+
IF_DEVICE_OR_CUDACC(
|
395
|
+
f = __uint_as_float(u);
|
396
|
+
,
|
397
|
+
memcpy(&f, &u, sizeof(u));
|
398
|
+
,
|
399
|
+
std::memcpy(&f, &u, sizeof(u));
|
400
|
+
)
|
401
|
+
return f;
|
402
|
+
}
|
403
|
+
|
404
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned short __internal_float2bfloat16(const float f, unsigned int &sign, unsigned int &remainder)
|
405
|
+
{
|
406
|
+
unsigned int x;
|
407
|
+
|
408
|
+
x = __internal_float_as_uint(f);
|
409
|
+
|
410
|
+
if ((x & 0x7fffffffU) > 0x7f800000U) {
|
411
|
+
sign = 0U;
|
412
|
+
remainder = 0U;
|
413
|
+
return static_cast<unsigned short>(0x7fffU);
|
414
|
+
}
|
415
|
+
sign = x >> 31U;
|
416
|
+
remainder = x << 16U;
|
417
|
+
return static_cast<unsigned short>(x >> 16U);
|
418
|
+
}
|
419
|
+
|
420
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __internal_double2float_rn(const double x)
|
421
|
+
{
|
422
|
+
float r;
|
423
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
424
|
+
asm("cvt.rn.f32.f64 %0, %1;" : "=f"(r) : "d"(x));
|
425
|
+
,
|
426
|
+
r = static_cast<float>(x);
|
427
|
+
)
|
428
|
+
return r;
|
429
|
+
}
|
430
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ double __internal_float2double(const float x)
|
431
|
+
{
|
432
|
+
double r;
|
433
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
434
|
+
asm("cvt.f64.f32 %0, %1;" : "=d"(r) : "f"(x));
|
435
|
+
,
|
436
|
+
r = static_cast<double>(x);
|
437
|
+
)
|
438
|
+
return r;
|
439
|
+
}
|
440
|
+
|
441
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __double2bfloat16(const double x)
|
442
|
+
{
|
443
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
444
|
+
__nv_bfloat16 val;
|
445
|
+
asm("{ cvt.rn.bf16.f64 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "d"(x));
|
446
|
+
return val;
|
447
|
+
,
|
448
|
+
float f = __internal_double2float_rn(x);
|
449
|
+
const double d = __internal_float2double(f);
|
450
|
+
unsigned int u = __internal_float_as_uint(f);
|
451
|
+
|
452
|
+
bool x_is_not_nan = ((u << (unsigned)1U) <= (unsigned)0xFF000000U);
|
453
|
+
|
454
|
+
|
455
|
+
if ((x > 0.0) && (d > x)) {
|
456
|
+
u--;
|
457
|
+
}
|
458
|
+
if ((x < 0.0) && (d < x)) {
|
459
|
+
u--;
|
460
|
+
}
|
461
|
+
if ((d != x) && x_is_not_nan) {
|
462
|
+
u |= 1U;
|
463
|
+
}
|
464
|
+
|
465
|
+
f = __internal_uint_as_float(u);
|
466
|
+
|
467
|
+
return __float2bfloat16(f);
|
468
|
+
)
|
469
|
+
}
|
470
|
+
|
471
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __float2bfloat16(const float a)
|
472
|
+
{
|
473
|
+
__nv_bfloat16 val;
|
474
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
475
|
+
asm("{ cvt.rn.bf16.f32 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "f"(a));
|
476
|
+
,
|
477
|
+
__nv_bfloat16_raw r;
|
478
|
+
unsigned int sign = 0U;
|
479
|
+
unsigned int remainder = 0U;
|
480
|
+
r.x = __internal_float2bfloat16(a, sign, remainder);
|
481
|
+
if ((remainder > 0x80000000U) || ((remainder == 0x80000000U) && ((r.x & 0x1U) != 0U))) {
|
482
|
+
r.x++;
|
483
|
+
}
|
484
|
+
val = r;
|
485
|
+
)
|
486
|
+
return val;
|
487
|
+
}
|
488
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __float2bfloat16_rn(const float a)
|
489
|
+
{
|
490
|
+
__nv_bfloat16 val;
|
491
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
492
|
+
asm("{ cvt.rn.bf16.f32 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "f"(a));
|
493
|
+
,
|
494
|
+
__nv_bfloat16_raw r;
|
495
|
+
unsigned int sign = 0U;
|
496
|
+
unsigned int remainder = 0U;
|
497
|
+
r.x = __internal_float2bfloat16(a, sign, remainder);
|
498
|
+
if ((remainder > 0x80000000U) || ((remainder == 0x80000000U) && ((r.x & 0x1U) != 0U))) {
|
499
|
+
r.x++;
|
500
|
+
}
|
501
|
+
val = r;
|
502
|
+
)
|
503
|
+
return val;
|
504
|
+
}
|
505
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __float2bfloat16_rz(const float a)
|
506
|
+
{
|
507
|
+
__nv_bfloat16 val;
|
508
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
509
|
+
asm("{ cvt.rz.bf16.f32 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "f"(a));
|
510
|
+
,
|
511
|
+
__nv_bfloat16_raw r;
|
512
|
+
unsigned int sign = 0U;
|
513
|
+
unsigned int remainder = 0U;
|
514
|
+
r.x = __internal_float2bfloat16(a, sign, remainder);
|
515
|
+
val = r;
|
516
|
+
)
|
517
|
+
return val;
|
518
|
+
}
|
519
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __float2bfloat16_rd(const float a)
|
520
|
+
{
|
521
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
522
|
+
__nv_bfloat16 val;
|
523
|
+
asm("{ cvt.rm.bf16.f32 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "f"(a));
|
524
|
+
return val;
|
525
|
+
,
|
526
|
+
__nv_bfloat16 val;
|
527
|
+
__nv_bfloat16_raw r;
|
528
|
+
unsigned int sign = 0U;
|
529
|
+
unsigned int remainder = 0U;
|
530
|
+
r.x = __internal_float2bfloat16(a, sign, remainder);
|
531
|
+
if ((remainder != 0U) && (sign != 0U)) {
|
532
|
+
r.x++;
|
533
|
+
}
|
534
|
+
val = r;
|
535
|
+
return val;
|
536
|
+
)
|
537
|
+
}
|
538
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __float2bfloat16_ru(const float a)
|
539
|
+
{
|
540
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
541
|
+
__nv_bfloat16 val;
|
542
|
+
asm("{ cvt.rp.bf16.f32 %0, %1;}\n" : "=h"(__BFLOAT16_TO_US(val)) : "f"(a));
|
543
|
+
return val;
|
544
|
+
,
|
545
|
+
__nv_bfloat16 val;
|
546
|
+
__nv_bfloat16_raw r;
|
547
|
+
unsigned int sign = 0U;
|
548
|
+
unsigned int remainder = 0U;
|
549
|
+
r.x = __internal_float2bfloat16(a, sign, remainder);
|
550
|
+
if ((remainder != 0U) && (sign == 0U)) {
|
551
|
+
r.x++;
|
552
|
+
}
|
553
|
+
val = r;
|
554
|
+
return val;
|
555
|
+
)
|
556
|
+
}
|
557
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __float2bfloat162_rn(const float a)
|
558
|
+
{
|
559
|
+
__nv_bfloat162 val;
|
560
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
561
|
+
asm("{.reg .b16 low;\n"
|
562
|
+
" cvt.rn.bf16.f32 low, %1;\n"
|
563
|
+
" mov.b32 %0, {low,low};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "f"(a));
|
564
|
+
,
|
565
|
+
val = __nv_bfloat162(__float2bfloat16_rn(a), __float2bfloat16_rn(a));
|
566
|
+
)
|
567
|
+
return val;
|
568
|
+
}
|
569
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __floats2bfloat162_rn(const float a, const float b)
|
570
|
+
{
|
571
|
+
__nv_bfloat162 val;
|
572
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
573
|
+
asm("{ cvt.rn.bf16x2.f32 %0, %2, %1;}\n"
|
574
|
+
: "=r"(__BFLOAT162_TO_UI(val)) : "f"(a), "f"(b));
|
575
|
+
,
|
576
|
+
val = __nv_bfloat162(__float2bfloat16_rn(a), __float2bfloat16_rn(b));
|
577
|
+
)
|
578
|
+
return val;
|
579
|
+
}
|
580
|
+
|
581
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
582
|
+
__CUDA_BF16_DECL__ float __internal_device_bfloat162float(const unsigned short h)
|
583
|
+
{
|
584
|
+
float f;
|
585
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
586
|
+
asm("{ cvt.f32.bf16 %0, %1;}\n" : "=f"(f) : "h"(h));
|
587
|
+
,
|
588
|
+
asm("{ mov.b32 %0, {0,%1};}\n" : "=f"(f) : "h"(h));
|
589
|
+
)
|
590
|
+
return f;
|
591
|
+
}
|
592
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
593
|
+
|
594
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __internal_bfloat162float(const unsigned short h)
|
595
|
+
{
|
596
|
+
float f;
|
597
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
598
|
+
f = __internal_device_bfloat162float(h);
|
599
|
+
,
|
600
|
+
unsigned int u = static_cast<unsigned int>(h) << 16;
|
601
|
+
f = __internal_uint_as_float(u);
|
602
|
+
)
|
603
|
+
return f;
|
604
|
+
}
|
605
|
+
|
606
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __bfloat162float(const __nv_bfloat16 a)
|
607
|
+
{
|
608
|
+
return __internal_bfloat162float(static_cast<__nv_bfloat16_raw>(a).x);
|
609
|
+
}
|
610
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __low2float(const __nv_bfloat162 a)
|
611
|
+
{
|
612
|
+
return __internal_bfloat162float(static_cast<__nv_bfloat162_raw>(a).x);
|
613
|
+
}
|
614
|
+
|
615
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float __high2float(const __nv_bfloat162 a)
|
616
|
+
{
|
617
|
+
return __internal_bfloat162float(static_cast<__nv_bfloat162_raw>(a).y);
|
618
|
+
}
|
619
|
+
|
620
|
+
/* CUDA vector-types compatible vector creation function (note returns __nv_bfloat162, not nv_bfloat162) */
|
621
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 make_bfloat162(const __nv_bfloat16 x, const __nv_bfloat16 y)
|
622
|
+
{
|
623
|
+
__nv_bfloat162 t; t.x = x; t.y = y; return t;
|
624
|
+
}
|
625
|
+
|
626
|
+
/* Definitions of intrinsics */
|
627
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __float22bfloat162_rn(const float2 a)
|
628
|
+
{
|
629
|
+
__nv_bfloat162 val = __floats2bfloat162_rn(a.x, a.y);
|
630
|
+
return val;
|
631
|
+
}
|
632
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ float2 __bfloat1622float2(const __nv_bfloat162 a)
|
633
|
+
{
|
634
|
+
float hi_float;
|
635
|
+
float lo_float;
|
636
|
+
lo_float = __internal_bfloat162float(((__nv_bfloat162_raw)a).x);
|
637
|
+
hi_float = __internal_bfloat162float(((__nv_bfloat162_raw)a).y);
|
638
|
+
return make_float2(lo_float, hi_float);
|
639
|
+
}
|
640
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
641
|
+
__CUDA_BF16_DECL__ int __bfloat162int_rn(const __nv_bfloat16 h)
|
642
|
+
{
|
643
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
644
|
+
int val;
|
645
|
+
asm("{ cvt.rni.s32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
646
|
+
return val;
|
647
|
+
,
|
648
|
+
return __float2int_rn(__bfloat162float(h));
|
649
|
+
)
|
650
|
+
}
|
651
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
652
|
+
|
653
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ int __internal_bfloat162int_rz(const __nv_bfloat16 h)
|
654
|
+
{
|
655
|
+
const float f = __bfloat162float(h);
|
656
|
+
int i;
|
657
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
658
|
+
i = __float2int_rz(f);
|
659
|
+
,
|
660
|
+
const int max_val = (int)0x7fffffffU;
|
661
|
+
const int min_val = (int)0x80000000U;
|
662
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
663
|
+
// saturation fixup
|
664
|
+
if (bits > (unsigned short)0xFF00U) {
|
665
|
+
// NaN
|
666
|
+
i = 0;
|
667
|
+
} else if (f >= static_cast<float>(max_val)) {
|
668
|
+
// saturate maximum
|
669
|
+
i = max_val;
|
670
|
+
} else if (f < static_cast<float>(min_val)) {
|
671
|
+
// saturate minimum
|
672
|
+
i = min_val;
|
673
|
+
} else {
|
674
|
+
i = static_cast<int>(f);
|
675
|
+
}
|
676
|
+
)
|
677
|
+
return i;
|
678
|
+
}
|
679
|
+
|
680
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ int __bfloat162int_rz(const __nv_bfloat16 h)
|
681
|
+
{
|
682
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
683
|
+
int val;
|
684
|
+
asm("{ cvt.rzi.s32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
685
|
+
return val;
|
686
|
+
,
|
687
|
+
return __internal_bfloat162int_rz(h);
|
688
|
+
)
|
689
|
+
}
|
690
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
691
|
+
__CUDA_BF16_DECL__ int __bfloat162int_rd(const __nv_bfloat16 h)
|
692
|
+
{
|
693
|
+
int val;
|
694
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
695
|
+
asm("{ cvt.rmi.s32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
696
|
+
,
|
697
|
+
const float f = __bfloat162float(h);
|
698
|
+
asm("cvt.rmi.s32.f32 %0, %1;" : "=r"(val) : "f"(f));
|
699
|
+
)
|
700
|
+
return val;
|
701
|
+
}
|
702
|
+
__CUDA_BF16_DECL__ int __bfloat162int_ru(const __nv_bfloat16 h)
|
703
|
+
{
|
704
|
+
int val;
|
705
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
706
|
+
asm("{ cvt.rpi.s32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
707
|
+
,
|
708
|
+
const float f = __bfloat162float(h);
|
709
|
+
asm("cvt.rpi.s32.f32 %0, %1;" : "=r"(val) : "f"(f));
|
710
|
+
)
|
711
|
+
return val;
|
712
|
+
}
|
713
|
+
|
714
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_int2bfloat16_rn(const int i)
|
715
|
+
{
|
716
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
717
|
+
__nv_bfloat16 val;
|
718
|
+
asm("cvt.rn.bf16.s32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
719
|
+
return val;
|
720
|
+
,
|
721
|
+
const float ru = __int2float_ru(i);
|
722
|
+
const float rd = __int2float_rd(i);
|
723
|
+
float rz = __int2float_rz(i);
|
724
|
+
if (ru != rd) {
|
725
|
+
rz = __uint_as_float(__float_as_uint(rz) | 1U);
|
726
|
+
}
|
727
|
+
return __float2bfloat16_rn(rz);
|
728
|
+
)
|
729
|
+
}
|
730
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
731
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __int2bfloat16_rn(const int i)
|
732
|
+
{
|
733
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
734
|
+
return __internal_device_int2bfloat16_rn(i);
|
735
|
+
,
|
736
|
+
const double d = static_cast<double>(i);
|
737
|
+
return __double2bfloat16(d);
|
738
|
+
)
|
739
|
+
}
|
740
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ signed char __bfloat162char_rz(const __nv_bfloat16 h)
|
741
|
+
{
|
742
|
+
signed char i;
|
743
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
744
|
+
unsigned short tmp = 0;
|
745
|
+
asm("{ .reg.b8 myreg;\n"
|
746
|
+
" cvt.rzi.s8.bf16 myreg, %1;\n"
|
747
|
+
" mov.b16 %0, {myreg, 0};\n}"
|
748
|
+
:"=h"(tmp) : "h"(__BFLOAT16_TO_CUS(h)));
|
749
|
+
const unsigned char u = static_cast<unsigned char>(tmp);
|
750
|
+
i = static_cast<signed char>(u);
|
751
|
+
,
|
752
|
+
const float f = __bfloat162float(h);
|
753
|
+
const signed char max_val = (signed char)0x7fU;
|
754
|
+
const signed char min_val = (signed char)0x80U;
|
755
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
756
|
+
// saturation fixup
|
757
|
+
if (bits > (unsigned short)0xFF00U) {
|
758
|
+
// NaN
|
759
|
+
i = 0;
|
760
|
+
} else if (f > static_cast<float>(max_val)) {
|
761
|
+
// saturate maximum
|
762
|
+
i = max_val;
|
763
|
+
} else if (f < static_cast<float>(min_val)) {
|
764
|
+
// saturate minimum
|
765
|
+
i = min_val;
|
766
|
+
} else {
|
767
|
+
// normal value, conversion is well-defined
|
768
|
+
i = static_cast<signed char>(f);
|
769
|
+
}
|
770
|
+
)
|
771
|
+
return i;
|
772
|
+
}
|
773
|
+
|
774
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned char __bfloat162uchar_rz(const __nv_bfloat16 h)
|
775
|
+
{
|
776
|
+
unsigned char i;
|
777
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
778
|
+
unsigned short tmp = 0;
|
779
|
+
asm("{ .reg.b8 myreg;\n"
|
780
|
+
" cvt.rzi.u8.bf16 myreg, %1;\n"
|
781
|
+
" mov.b16 %0, {myreg, 0};\n}"
|
782
|
+
:"=h"(tmp) : "h"(__BFLOAT16_TO_CUS(h)));
|
783
|
+
i = static_cast<unsigned char>(tmp);
|
784
|
+
,
|
785
|
+
const float f = __bfloat162float(h);
|
786
|
+
const unsigned char max_val = 0xffU;
|
787
|
+
const unsigned char min_val = 0U;
|
788
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
789
|
+
// saturation fixup
|
790
|
+
if (bits > (unsigned short)0xFF00U) {
|
791
|
+
// NaN
|
792
|
+
i = 0U;
|
793
|
+
} else if (f > static_cast<float>(max_val)) {
|
794
|
+
// saturate maximum
|
795
|
+
i = max_val;
|
796
|
+
} else if (f < static_cast<float>(min_val)) {
|
797
|
+
// saturate minimum
|
798
|
+
i = min_val;
|
799
|
+
} else {
|
800
|
+
// normal value, conversion is well-defined
|
801
|
+
i = static_cast<unsigned char>(f);
|
802
|
+
}
|
803
|
+
)
|
804
|
+
return i;
|
805
|
+
}
|
806
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
807
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __int2bfloat16_rz(const int i)
|
808
|
+
{
|
809
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
810
|
+
__nv_bfloat16 val;
|
811
|
+
asm("cvt.rz.bf16.s32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
812
|
+
return val;
|
813
|
+
,
|
814
|
+
return __float2bfloat16_rz(__int2float_rz(i));
|
815
|
+
)
|
816
|
+
}
|
817
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __int2bfloat16_rd(const int i)
|
818
|
+
{
|
819
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
820
|
+
__nv_bfloat16 val;
|
821
|
+
asm("cvt.rm.bf16.s32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
822
|
+
return val;
|
823
|
+
,
|
824
|
+
return __float2bfloat16_rd(__int2float_rd(i));
|
825
|
+
)
|
826
|
+
}
|
827
|
+
|
828
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __int2bfloat16_ru(const int i)
|
829
|
+
{
|
830
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
831
|
+
__nv_bfloat16 val;
|
832
|
+
asm("cvt.rp.bf16.s32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
833
|
+
return val;
|
834
|
+
,
|
835
|
+
return __float2bfloat16_ru(__int2float_ru(i));
|
836
|
+
)
|
837
|
+
}
|
838
|
+
|
839
|
+
__CUDA_BF16_DECL__ short int __bfloat162short_rn(const __nv_bfloat16 h)
|
840
|
+
{
|
841
|
+
short int val;
|
842
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
843
|
+
asm("cvt.rni.s16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
844
|
+
,
|
845
|
+
asm("{ .reg.f32 f;\n"
|
846
|
+
" mov.b32 f, {0,%1};\n"
|
847
|
+
" cvt.rni.s16.f32 %0,f;\n}"
|
848
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
849
|
+
)
|
850
|
+
return val;
|
851
|
+
}
|
852
|
+
|
853
|
+
__CUDA_BF16_DECL__ short int __internal_device_bfloat162short_rz(const __nv_bfloat16 h)
|
854
|
+
{
|
855
|
+
short int val;
|
856
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
857
|
+
asm("cvt.rzi.s16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
858
|
+
,
|
859
|
+
asm("{ .reg.f32 f;\n"
|
860
|
+
" mov.b32 f, {0,%1};\n"
|
861
|
+
" cvt.rzi.s16.f32 %0,f;\n}"
|
862
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
863
|
+
)
|
864
|
+
return val;
|
865
|
+
}
|
866
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
867
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ short int __bfloat162short_rz(const __nv_bfloat16 h)
|
868
|
+
{
|
869
|
+
short int val;
|
870
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
871
|
+
val = __internal_device_bfloat162short_rz(h);
|
872
|
+
,
|
873
|
+
const float f = __bfloat162float(h);
|
874
|
+
const short int max_val = (short int)0x7fffU;
|
875
|
+
const short int min_val = (short int)0x8000U;
|
876
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
877
|
+
// saturation fixup
|
878
|
+
if (bits > (unsigned short)0xFF00U) {
|
879
|
+
// NaN
|
880
|
+
val = 0;
|
881
|
+
} else if (f > static_cast<float>(max_val)) {
|
882
|
+
// saturate maximum
|
883
|
+
val = max_val;
|
884
|
+
} else if (f < static_cast<float>(min_val)) {
|
885
|
+
// saturate minimum
|
886
|
+
val = min_val;
|
887
|
+
} else {
|
888
|
+
val = static_cast<short int>(f);
|
889
|
+
}
|
890
|
+
)
|
891
|
+
return val;
|
892
|
+
}
|
893
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
894
|
+
__CUDA_BF16_DECL__ short int __bfloat162short_rd(const __nv_bfloat16 h)
|
895
|
+
{
|
896
|
+
short int val;
|
897
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
898
|
+
asm("cvt.rmi.s16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
899
|
+
,
|
900
|
+
asm("{ .reg.f32 f;\n"
|
901
|
+
" mov.b32 f, {0,%1};\n"
|
902
|
+
" cvt.rmi.s16.f32 %0,f;\n}"
|
903
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
904
|
+
)
|
905
|
+
return val;
|
906
|
+
}
|
907
|
+
__CUDA_BF16_DECL__ short int __bfloat162short_ru(const __nv_bfloat16 h)
|
908
|
+
{
|
909
|
+
short int val;
|
910
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
911
|
+
asm("cvt.rpi.s16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
912
|
+
,
|
913
|
+
asm("{ .reg.f32 f;\n"
|
914
|
+
" mov.b32 f, {0,%1};\n"
|
915
|
+
" cvt.rpi.s16.f32 %0,f;\n}"
|
916
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
917
|
+
)
|
918
|
+
return val;
|
919
|
+
}
|
920
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
921
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __short2bfloat16_rn(const short int i)
|
922
|
+
{
|
923
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
924
|
+
__nv_bfloat16 val;
|
925
|
+
asm("cvt.rn.bf16.s16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
926
|
+
return val;
|
927
|
+
,
|
928
|
+
const float f = static_cast<float>(i);
|
929
|
+
return __float2bfloat16_rn(f);
|
930
|
+
)
|
931
|
+
}
|
932
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
933
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __short2bfloat16_rz(const short int i)
|
934
|
+
{
|
935
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
936
|
+
__nv_bfloat16 val;
|
937
|
+
asm("cvt.rz.bf16.s16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
938
|
+
return val;
|
939
|
+
,
|
940
|
+
return __float2bfloat16_rz(__int2float_rz(static_cast<int>(i)));
|
941
|
+
)
|
942
|
+
}
|
943
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __short2bfloat16_rd(const short int i)
|
944
|
+
{
|
945
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
946
|
+
__nv_bfloat16 val;
|
947
|
+
asm("cvt.rm.bf16.s16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
948
|
+
return val;
|
949
|
+
,
|
950
|
+
return __float2bfloat16_rd(__int2float_rd(static_cast<int>(i)));
|
951
|
+
)
|
952
|
+
}
|
953
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __short2bfloat16_ru(const short int i)
|
954
|
+
{
|
955
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
956
|
+
__nv_bfloat16 val;
|
957
|
+
asm("cvt.rp.bf16.s16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
958
|
+
return val;
|
959
|
+
,
|
960
|
+
return __float2bfloat16_ru(__int2float_ru(static_cast<int>(i)));
|
961
|
+
)
|
962
|
+
}
|
963
|
+
|
964
|
+
__CUDA_BF16_DECL__ unsigned int __bfloat162uint_rn(const __nv_bfloat16 h)
|
965
|
+
{
|
966
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
967
|
+
unsigned int val;
|
968
|
+
asm("{ cvt.rni.u32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
969
|
+
return val;
|
970
|
+
,
|
971
|
+
return __float2uint_rn(__bfloat162float(h));
|
972
|
+
)
|
973
|
+
}
|
974
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
975
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __internal_bfloat162uint_rz(const __nv_bfloat16 h)
|
976
|
+
{
|
977
|
+
const float f = __bfloat162float(h);
|
978
|
+
unsigned int i;
|
979
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
980
|
+
i = __float2uint_rz(f);
|
981
|
+
,
|
982
|
+
const unsigned int max_val = 0xffffffffU;
|
983
|
+
const unsigned int min_val = 0U;
|
984
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
985
|
+
// saturation fixup
|
986
|
+
if (bits > (unsigned short)0xFF00U) {
|
987
|
+
// NaN
|
988
|
+
i = 0U;
|
989
|
+
} else if (f >= static_cast<float>(max_val)) {
|
990
|
+
// saturate maximum
|
991
|
+
i = max_val;
|
992
|
+
} else if (f < static_cast<float>(min_val)) {
|
993
|
+
// saturate minimum
|
994
|
+
i = min_val;
|
995
|
+
} else {
|
996
|
+
i = static_cast<unsigned int>(f);
|
997
|
+
}
|
998
|
+
)
|
999
|
+
return i;
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __bfloat162uint_rz(const __nv_bfloat16 h)
|
1003
|
+
{
|
1004
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1005
|
+
unsigned int val;
|
1006
|
+
asm("{ cvt.rzi.u32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
1007
|
+
return val;
|
1008
|
+
,
|
1009
|
+
return __internal_bfloat162uint_rz(h);
|
1010
|
+
)
|
1011
|
+
}
|
1012
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1013
|
+
__CUDA_BF16_DECL__ unsigned int __bfloat162uint_rd(const __nv_bfloat16 h)
|
1014
|
+
{
|
1015
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1016
|
+
unsigned int val;
|
1017
|
+
asm("{ cvt.rmi.u32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
1018
|
+
return val;
|
1019
|
+
,
|
1020
|
+
return __float2uint_rd(__bfloat162float(h));
|
1021
|
+
)
|
1022
|
+
}
|
1023
|
+
__CUDA_BF16_DECL__ unsigned int __bfloat162uint_ru(const __nv_bfloat16 h)
|
1024
|
+
{
|
1025
|
+
unsigned int val;
|
1026
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1027
|
+
asm("{ cvt.rpi.u32.bf16 %0, %1;}\n" : "=r"(val) : "h"(__BFLOAT16_TO_CUS(h)));
|
1028
|
+
,
|
1029
|
+
const float f = __bfloat162float(h);
|
1030
|
+
asm("cvt.rpi.u32.f32 %0, %1;" : "=r"(val) : "f"(f));
|
1031
|
+
)
|
1032
|
+
return val;
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_uint2bfloat16_rn(const unsigned int i)
|
1036
|
+
{
|
1037
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1038
|
+
__nv_bfloat16 val;
|
1039
|
+
asm("cvt.rn.bf16.u32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
1040
|
+
return val;
|
1041
|
+
,
|
1042
|
+
const float ru = __uint2float_ru(i);
|
1043
|
+
const float rd = __uint2float_rd(i);
|
1044
|
+
float rz = __uint2float_rz(i);
|
1045
|
+
if (ru != rd) {
|
1046
|
+
rz = __uint_as_float(__float_as_uint(rz) | 1U);
|
1047
|
+
}
|
1048
|
+
return __float2bfloat16_rn(rz);
|
1049
|
+
)
|
1050
|
+
}
|
1051
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1052
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __uint2bfloat16_rn(const unsigned int i)
|
1053
|
+
{
|
1054
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1055
|
+
return __internal_device_uint2bfloat16_rn(i);
|
1056
|
+
,
|
1057
|
+
const double d = static_cast<double>(i);
|
1058
|
+
return __double2bfloat16(d);
|
1059
|
+
)
|
1060
|
+
}
|
1061
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1062
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __uint2bfloat16_rz(const unsigned int i)
|
1063
|
+
{
|
1064
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1065
|
+
__nv_bfloat16 val;
|
1066
|
+
asm("cvt.rz.bf16.u32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
1067
|
+
return val;
|
1068
|
+
,
|
1069
|
+
return __float2bfloat16_rz(__uint2float_rz(i));
|
1070
|
+
)
|
1071
|
+
}
|
1072
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __uint2bfloat16_rd(const unsigned int i)
|
1073
|
+
{
|
1074
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1075
|
+
__nv_bfloat16 val;
|
1076
|
+
asm("cvt.rm.bf16.u32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
1077
|
+
return val;
|
1078
|
+
,
|
1079
|
+
return __float2bfloat16_rd(__uint2float_rd(i));
|
1080
|
+
)
|
1081
|
+
}
|
1082
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __uint2bfloat16_ru(const unsigned int i)
|
1083
|
+
{
|
1084
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1085
|
+
__nv_bfloat16 val;
|
1086
|
+
asm("cvt.rp.bf16.u32 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "r"(i));
|
1087
|
+
return val;
|
1088
|
+
,
|
1089
|
+
return __float2bfloat16_ru(__uint2float_ru(i));
|
1090
|
+
)
|
1091
|
+
}
|
1092
|
+
|
1093
|
+
__CUDA_BF16_DECL__ unsigned short int __bfloat162ushort_rn(const __nv_bfloat16 h)
|
1094
|
+
{
|
1095
|
+
unsigned short int val;
|
1096
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1097
|
+
asm("cvt.rni.u16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1098
|
+
,
|
1099
|
+
asm("{ .reg.f32 f;\n"
|
1100
|
+
" mov.b32 f, {0,%1};\n"
|
1101
|
+
" cvt.rni.u16.f32 %0,f;\n}"
|
1102
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1103
|
+
)
|
1104
|
+
return val;
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
__CUDA_BF16_DECL__ unsigned short int __internal_device_bfloat162ushort_rz(const __nv_bfloat16 h)
|
1108
|
+
{
|
1109
|
+
unsigned short int val;
|
1110
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1111
|
+
asm("cvt.rzi.u16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1112
|
+
,
|
1113
|
+
asm("{ .reg.f32 f;\n"
|
1114
|
+
" mov.b32 f, {0,%1};\n"
|
1115
|
+
" cvt.rzi.u16.f32 %0,f;\n}"
|
1116
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1117
|
+
)
|
1118
|
+
return val;
|
1119
|
+
}
|
1120
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1121
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned short int __bfloat162ushort_rz(const __nv_bfloat16 h)
|
1122
|
+
{
|
1123
|
+
unsigned short int val;
|
1124
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1125
|
+
val = __internal_device_bfloat162ushort_rz(h);
|
1126
|
+
,
|
1127
|
+
const float f = __bfloat162float(h);
|
1128
|
+
const unsigned short int max_val = 0xffffU;
|
1129
|
+
const unsigned short int min_val = 0U;
|
1130
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
1131
|
+
// saturation fixup
|
1132
|
+
if (bits > (unsigned short)0xFF00U) {
|
1133
|
+
// NaN
|
1134
|
+
val = 0U;
|
1135
|
+
} else if (f > static_cast<float>(max_val)) {
|
1136
|
+
// saturate maximum
|
1137
|
+
val = max_val;
|
1138
|
+
} else if (f < static_cast<float>(min_val)) {
|
1139
|
+
// saturate minimum
|
1140
|
+
val = min_val;
|
1141
|
+
} else {
|
1142
|
+
val = static_cast<unsigned short int>(f);
|
1143
|
+
}
|
1144
|
+
)
|
1145
|
+
return val;
|
1146
|
+
}
|
1147
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1148
|
+
__CUDA_BF16_DECL__ unsigned short int __bfloat162ushort_rd(const __nv_bfloat16 h)
|
1149
|
+
{
|
1150
|
+
unsigned short int val;
|
1151
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1152
|
+
asm("cvt.rmi.u16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1153
|
+
,
|
1154
|
+
asm("{ .reg.f32 f;\n"
|
1155
|
+
" mov.b32 f, {0,%1};\n"
|
1156
|
+
" cvt.rmi.u16.f32 %0,f;\n}"
|
1157
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1158
|
+
)
|
1159
|
+
return val;
|
1160
|
+
}
|
1161
|
+
__CUDA_BF16_DECL__ unsigned short int __bfloat162ushort_ru(const __nv_bfloat16 h)
|
1162
|
+
{
|
1163
|
+
unsigned short int val;
|
1164
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1165
|
+
asm("cvt.rpi.u16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1166
|
+
,
|
1167
|
+
asm("{ .reg.f32 f;\n"
|
1168
|
+
" mov.b32 f, {0,%1};\n"
|
1169
|
+
" cvt.rpi.u16.f32 %0,f;\n}"
|
1170
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1171
|
+
)
|
1172
|
+
return val;
|
1173
|
+
}
|
1174
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1175
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __ushort2bfloat16_rn(const unsigned short int i)
|
1176
|
+
{
|
1177
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1178
|
+
__nv_bfloat16 val;
|
1179
|
+
asm("cvt.rn.bf16.u16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
1180
|
+
return val;
|
1181
|
+
,
|
1182
|
+
const float f = static_cast<float>(i);
|
1183
|
+
return __float2bfloat16_rn(f);
|
1184
|
+
)
|
1185
|
+
}
|
1186
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1187
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ushort2bfloat16_rz(const unsigned short int i)
|
1188
|
+
{
|
1189
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1190
|
+
__nv_bfloat16 val;
|
1191
|
+
asm("cvt.rz.bf16.u16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
1192
|
+
return val;
|
1193
|
+
,
|
1194
|
+
return __float2bfloat16_rz(__uint2float_rz(static_cast<unsigned int>(i)));
|
1195
|
+
)
|
1196
|
+
}
|
1197
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ushort2bfloat16_rd(const unsigned short int i)
|
1198
|
+
{
|
1199
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1200
|
+
__nv_bfloat16 val;
|
1201
|
+
asm("cvt.rm.bf16.u16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
1202
|
+
return val;
|
1203
|
+
,
|
1204
|
+
return __float2bfloat16_rd(__uint2float_rd(static_cast<unsigned int>(i)));
|
1205
|
+
)
|
1206
|
+
}
|
1207
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ushort2bfloat16_ru(const unsigned short int i)
|
1208
|
+
{
|
1209
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1210
|
+
__nv_bfloat16 val;
|
1211
|
+
asm("cvt.rp.bf16.u16 %0, %1;" : "=h"(__BFLOAT16_TO_US(val)) : "h"(i));
|
1212
|
+
return val;
|
1213
|
+
,
|
1214
|
+
return __float2bfloat16_ru(__uint2float_ru(static_cast<unsigned int>(i)));
|
1215
|
+
)
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
__CUDA_BF16_DECL__ unsigned long long int __bfloat162ull_rn(const __nv_bfloat16 h)
|
1219
|
+
{
|
1220
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1221
|
+
unsigned long long int i;
|
1222
|
+
asm("cvt.rni.u64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1223
|
+
return i;
|
1224
|
+
,
|
1225
|
+
return __float2ull_rn(__bfloat162float(h));
|
1226
|
+
)
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
__CUDA_BF16_DECL__ unsigned long long int __internal_device_bfloat162ull_rz(const __nv_bfloat16 h)
|
1230
|
+
{
|
1231
|
+
unsigned long long int i;
|
1232
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1233
|
+
asm("cvt.rzi.u64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1234
|
+
,
|
1235
|
+
const float f = __bfloat162float(h);
|
1236
|
+
i = __float2ull_rz(f);
|
1237
|
+
)
|
1238
|
+
return i;
|
1239
|
+
}
|
1240
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1241
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned long long int __bfloat162ull_rz(const __nv_bfloat16 h)
|
1242
|
+
{
|
1243
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1244
|
+
return __internal_device_bfloat162ull_rz(h);
|
1245
|
+
,
|
1246
|
+
const float f = __bfloat162float(h);
|
1247
|
+
unsigned long long int i;
|
1248
|
+
const unsigned long long int max_val = 0xffffffffffffffffULL;
|
1249
|
+
const unsigned long long int min_val = 0ULL;
|
1250
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
1251
|
+
// saturation fixup
|
1252
|
+
if (bits > (unsigned short)0xFF00U) {
|
1253
|
+
// NaN
|
1254
|
+
i = 0x8000000000000000ULL;
|
1255
|
+
} else if (f >= static_cast<float>(max_val)) {
|
1256
|
+
// saturate maximum
|
1257
|
+
i = max_val;
|
1258
|
+
} else if (f < static_cast<float>(min_val)) {
|
1259
|
+
// saturate minimum
|
1260
|
+
i = min_val;
|
1261
|
+
} else {
|
1262
|
+
i = static_cast<unsigned long long int>(f);
|
1263
|
+
}
|
1264
|
+
return i;
|
1265
|
+
)
|
1266
|
+
}
|
1267
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1268
|
+
__CUDA_BF16_DECL__ unsigned long long int __bfloat162ull_rd(const __nv_bfloat16 h)
|
1269
|
+
{
|
1270
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1271
|
+
unsigned long long int i;
|
1272
|
+
asm("cvt.rmi.u64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1273
|
+
return i;
|
1274
|
+
,
|
1275
|
+
return __float2ull_rd(__bfloat162float(h));
|
1276
|
+
)
|
1277
|
+
}
|
1278
|
+
__CUDA_BF16_DECL__ unsigned long long int __bfloat162ull_ru(const __nv_bfloat16 h)
|
1279
|
+
{
|
1280
|
+
unsigned long long int i;
|
1281
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1282
|
+
asm("cvt.rpi.u64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1283
|
+
,
|
1284
|
+
const float f = __bfloat162float(h);
|
1285
|
+
asm("cvt.rpi.u64.f32 %0, %1;" : "=l"(i) : "f"(f));
|
1286
|
+
)
|
1287
|
+
return i;
|
1288
|
+
}
|
1289
|
+
|
1290
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_ull2bfloat16_rn(const unsigned long long int i)
|
1291
|
+
{
|
1292
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1293
|
+
__nv_bfloat16 h;
|
1294
|
+
asm("cvt.rn.bf16.u64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1295
|
+
return h;
|
1296
|
+
,
|
1297
|
+
const float ru = __ull2float_ru(i);
|
1298
|
+
const float rd = __ull2float_rd(i);
|
1299
|
+
float rz = __ull2float_rz(i);
|
1300
|
+
if (ru != rd) {
|
1301
|
+
rz = __uint_as_float(__float_as_uint(rz) | 1U);
|
1302
|
+
}
|
1303
|
+
return __float2bfloat16_rn(rz);
|
1304
|
+
)
|
1305
|
+
}
|
1306
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1307
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __ull2bfloat16_rn(const unsigned long long int i)
|
1308
|
+
{
|
1309
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1310
|
+
return __internal_device_ull2bfloat16_rn(i);
|
1311
|
+
,
|
1312
|
+
float f = static_cast<float>(i);
|
1313
|
+
const unsigned long long int uf = static_cast<unsigned long long int>(f);
|
1314
|
+
unsigned int u = __internal_float_as_uint(f);
|
1315
|
+
// round up happened here
|
1316
|
+
// note: no need to handle round up to f == 0x1.p64 specially
|
1317
|
+
if (uf > i) {
|
1318
|
+
u--;
|
1319
|
+
}
|
1320
|
+
if (uf != i) {
|
1321
|
+
u |= 1U;
|
1322
|
+
}
|
1323
|
+
f = __internal_uint_as_float(u);
|
1324
|
+
return __float2bfloat16_rn(f);
|
1325
|
+
)
|
1326
|
+
}
|
1327
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1328
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ull2bfloat16_rz(const unsigned long long int i)
|
1329
|
+
{
|
1330
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1331
|
+
__nv_bfloat16 h;
|
1332
|
+
asm("cvt.rz.bf16.u64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1333
|
+
return h;
|
1334
|
+
,
|
1335
|
+
return __float2bfloat16_rz(__ull2float_rz(i));
|
1336
|
+
)
|
1337
|
+
}
|
1338
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ull2bfloat16_rd(const unsigned long long int i)
|
1339
|
+
{
|
1340
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1341
|
+
__nv_bfloat16 h;
|
1342
|
+
asm("cvt.rm.bf16.u64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1343
|
+
return h;
|
1344
|
+
,
|
1345
|
+
return __float2bfloat16_rd(__ull2float_rd(i));
|
1346
|
+
)
|
1347
|
+
}
|
1348
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ull2bfloat16_ru(const unsigned long long int i)
|
1349
|
+
{
|
1350
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1351
|
+
__nv_bfloat16 h;
|
1352
|
+
asm("cvt.rp.bf16.u64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1353
|
+
return h;
|
1354
|
+
,
|
1355
|
+
return __float2bfloat16_ru(__ull2float_ru(i));
|
1356
|
+
)
|
1357
|
+
}
|
1358
|
+
__CUDA_BF16_DECL__ long long int __bfloat162ll_rn(const __nv_bfloat16 h)
|
1359
|
+
{
|
1360
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1361
|
+
long long int i;
|
1362
|
+
asm("cvt.rni.s64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1363
|
+
return i;
|
1364
|
+
,
|
1365
|
+
return __float2ll_rn(__bfloat162float(h));
|
1366
|
+
)
|
1367
|
+
}
|
1368
|
+
|
1369
|
+
__CUDA_BF16_DECL__ long long int __internal_device_bfloat162ll_rz(const __nv_bfloat16 h)
|
1370
|
+
{
|
1371
|
+
long long int i;
|
1372
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1373
|
+
asm("cvt.rzi.s64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1374
|
+
,
|
1375
|
+
const float f = __bfloat162float(h);
|
1376
|
+
i = __float2ll_rz(f);
|
1377
|
+
)
|
1378
|
+
return i;
|
1379
|
+
}
|
1380
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1381
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ long long int __bfloat162ll_rz(const __nv_bfloat16 h)
|
1382
|
+
{
|
1383
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1384
|
+
return __internal_device_bfloat162ll_rz(h);
|
1385
|
+
,
|
1386
|
+
long long int i;
|
1387
|
+
const float f = __bfloat162float(h);
|
1388
|
+
const long long int max_val = (long long int)0x7fffffffffffffffULL;
|
1389
|
+
const long long int min_val = (long long int)0x8000000000000000ULL;
|
1390
|
+
const unsigned short bits = static_cast<unsigned short>(static_cast<__nv_bfloat16_raw>(h).x << 1U);
|
1391
|
+
// saturation fixup
|
1392
|
+
if (bits > (unsigned short)0xFF00U) {
|
1393
|
+
// NaN
|
1394
|
+
i = min_val;
|
1395
|
+
} else if (f >= static_cast<float>(max_val)) {
|
1396
|
+
// saturate maximum
|
1397
|
+
i = max_val;
|
1398
|
+
} else if (f < static_cast<float>(min_val)) {
|
1399
|
+
// saturate minimum
|
1400
|
+
i = min_val;
|
1401
|
+
} else {
|
1402
|
+
i = static_cast<long long int>(f);
|
1403
|
+
}
|
1404
|
+
return i;
|
1405
|
+
)
|
1406
|
+
}
|
1407
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1408
|
+
__CUDA_BF16_DECL__ long long int __bfloat162ll_rd(const __nv_bfloat16 h)
|
1409
|
+
{
|
1410
|
+
long long int i;
|
1411
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1412
|
+
asm("cvt.rmi.s64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1413
|
+
,
|
1414
|
+
const float f = __bfloat162float(h);
|
1415
|
+
asm("cvt.rmi.s64.f32 %0, %1;" : "=l"(i) : "f"(f));
|
1416
|
+
)
|
1417
|
+
return i;
|
1418
|
+
}
|
1419
|
+
__CUDA_BF16_DECL__ long long int __bfloat162ll_ru(const __nv_bfloat16 h)
|
1420
|
+
{
|
1421
|
+
long long int i;
|
1422
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1423
|
+
asm("cvt.rpi.s64.bf16 %0, %1;" : "=l"(i) : "h"(__BFLOAT16_TO_CUS(h)));
|
1424
|
+
,
|
1425
|
+
const float f = __bfloat162float(h);
|
1426
|
+
asm("cvt.rpi.s64.f32 %0, %1;" : "=l"(i) : "f"(f));
|
1427
|
+
)
|
1428
|
+
return i;
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_ll2bfloat16_rn(const long long int i)
|
1432
|
+
{
|
1433
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1434
|
+
__nv_bfloat16 h;
|
1435
|
+
asm("cvt.rn.bf16.s64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1436
|
+
return h;
|
1437
|
+
,
|
1438
|
+
const float ru = __ll2float_ru(i);
|
1439
|
+
const float rd = __ll2float_rd(i);
|
1440
|
+
float rz = __ll2float_rz(i);
|
1441
|
+
if (ru != rd) {
|
1442
|
+
rz = __uint_as_float(__float_as_uint(rz) | 1U);
|
1443
|
+
}
|
1444
|
+
return __float2bfloat16_rn(rz);
|
1445
|
+
)
|
1446
|
+
}
|
1447
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1448
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __ll2bfloat16_rn(const long long int i)
|
1449
|
+
{
|
1450
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1451
|
+
return __internal_device_ll2bfloat16_rn(i);
|
1452
|
+
,
|
1453
|
+
float f = static_cast<float>(i);
|
1454
|
+
const long long int lf = static_cast<long long int>(f);
|
1455
|
+
unsigned int u = __internal_float_as_uint(f);
|
1456
|
+
|
1457
|
+
if ((f > 0.0f) && (lf > i)) {
|
1458
|
+
u--;
|
1459
|
+
}
|
1460
|
+
if ((f < 0.0f) && (lf < i)) {
|
1461
|
+
u--;
|
1462
|
+
}
|
1463
|
+
if (lf != i) {
|
1464
|
+
u |= 1U;
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
f = __internal_uint_as_float(u);
|
1468
|
+
return __float2bfloat16_rn(f);
|
1469
|
+
)
|
1470
|
+
}
|
1471
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1472
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ll2bfloat16_rz(const long long int i)
|
1473
|
+
{
|
1474
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1475
|
+
__nv_bfloat16 h;
|
1476
|
+
asm("cvt.rz.bf16.s64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1477
|
+
return h;
|
1478
|
+
,
|
1479
|
+
return __float2bfloat16_rz(__ll2float_rz(i));
|
1480
|
+
)
|
1481
|
+
}
|
1482
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ll2bfloat16_rd(const long long int i)
|
1483
|
+
{
|
1484
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1485
|
+
__nv_bfloat16 h;
|
1486
|
+
asm("cvt.rm.bf16.s64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1487
|
+
return h;
|
1488
|
+
,
|
1489
|
+
return __float2bfloat16_rd(__ll2float_rd(i));
|
1490
|
+
)
|
1491
|
+
}
|
1492
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ll2bfloat16_ru(const long long int i)
|
1493
|
+
{
|
1494
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1495
|
+
__nv_bfloat16 h;
|
1496
|
+
asm("cvt.rp.bf16.s64 %0, %1;" : "=h"(__BFLOAT16_TO_US(h)) : "l"(i));
|
1497
|
+
return h;
|
1498
|
+
,
|
1499
|
+
return __float2bfloat16_ru(__ll2float_ru(i));
|
1500
|
+
)
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 htrunc(const __nv_bfloat16 h)
|
1504
|
+
{
|
1505
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1506
|
+
__nv_bfloat16 r;
|
1507
|
+
asm("cvt.rzi.bf16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1508
|
+
return r;
|
1509
|
+
,
|
1510
|
+
return __float2bfloat16_rz(truncf(__bfloat162float(h)));
|
1511
|
+
)
|
1512
|
+
}
|
1513
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hceil(const __nv_bfloat16 h)
|
1514
|
+
{
|
1515
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1516
|
+
__nv_bfloat16 r;
|
1517
|
+
asm("cvt.rpi.bf16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1518
|
+
return r;
|
1519
|
+
,
|
1520
|
+
float fh = __bfloat162float(h);
|
1521
|
+
asm( "{ cvt.rpi.f32.f32 %0, %0; }\n"
|
1522
|
+
:"+f"(fh));
|
1523
|
+
return __float2bfloat16_rz(fh);
|
1524
|
+
)
|
1525
|
+
}
|
1526
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hfloor(const __nv_bfloat16 h)
|
1527
|
+
{
|
1528
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1529
|
+
__nv_bfloat16 r;
|
1530
|
+
asm("cvt.rmi.bf16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1531
|
+
return r;
|
1532
|
+
,
|
1533
|
+
float fh = __bfloat162float(h);
|
1534
|
+
asm( "{ cvt.rmi.f32.f32 %0, %0; }\n"
|
1535
|
+
:"+f"(fh));
|
1536
|
+
return __float2bfloat16_rz(fh);
|
1537
|
+
)
|
1538
|
+
}
|
1539
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hrint(const __nv_bfloat16 h)
|
1540
|
+
{
|
1541
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
1542
|
+
__nv_bfloat16 r;
|
1543
|
+
asm("cvt.rni.bf16.bf16 %0, %1;" : "=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(h)));
|
1544
|
+
return r;
|
1545
|
+
,
|
1546
|
+
return __float2bfloat16_rz(rintf(__bfloat162float(h)));
|
1547
|
+
)
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2trunc(const __nv_bfloat162 h)
|
1551
|
+
{
|
1552
|
+
const __nv_bfloat16 low = htrunc(h.x);
|
1553
|
+
const __nv_bfloat16 high = htrunc(h.y);
|
1554
|
+
return __nv_bfloat162(low, high);
|
1555
|
+
}
|
1556
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2ceil(const __nv_bfloat162 h)
|
1557
|
+
{
|
1558
|
+
const __nv_bfloat16 low = hceil(h.x);
|
1559
|
+
const __nv_bfloat16 high = hceil(h.y);
|
1560
|
+
return __nv_bfloat162(low, high);
|
1561
|
+
}
|
1562
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2floor(const __nv_bfloat162 h)
|
1563
|
+
{
|
1564
|
+
const __nv_bfloat16 low = hfloor(h.x);
|
1565
|
+
const __nv_bfloat16 high = hfloor(h.y);
|
1566
|
+
return __nv_bfloat162(low, high);
|
1567
|
+
}
|
1568
|
+
|
1569
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2rint(const __nv_bfloat162 h)
|
1570
|
+
{
|
1571
|
+
return __halves2bfloat162(hrint(__low2bfloat16(h)), hrint(__high2bfloat16(h)));
|
1572
|
+
}
|
1573
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
1574
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __lows2bfloat162(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1575
|
+
{
|
1576
|
+
__nv_bfloat162 val;
|
1577
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1578
|
+
asm("{.reg .b16 alow,ahigh,blow,bhigh;\n"
|
1579
|
+
" mov.b32 {alow,ahigh}, %1;\n"
|
1580
|
+
" mov.b32 {blow,bhigh}, %2;\n"
|
1581
|
+
" mov.b32 %0, {alow,blow};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)), "r"(__BFLOAT162_TO_CUI(b)));
|
1582
|
+
,
|
1583
|
+
val.x = a.x;
|
1584
|
+
val.y = b.x;
|
1585
|
+
)
|
1586
|
+
return val;
|
1587
|
+
}
|
1588
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __highs2bfloat162(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1589
|
+
{
|
1590
|
+
__nv_bfloat162 val;
|
1591
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1592
|
+
asm("{.reg .b16 alow,ahigh,blow,bhigh;\n"
|
1593
|
+
" mov.b32 {alow,ahigh}, %1;\n"
|
1594
|
+
" mov.b32 {blow,bhigh}, %2;\n"
|
1595
|
+
" mov.b32 %0, {ahigh,bhigh};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)), "r"(__BFLOAT162_TO_CUI(b)));
|
1596
|
+
,
|
1597
|
+
val.x = a.y;
|
1598
|
+
val.y = b.y;
|
1599
|
+
)
|
1600
|
+
return val;
|
1601
|
+
}
|
1602
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __low2bfloat16(const __nv_bfloat162 a)
|
1603
|
+
{
|
1604
|
+
__nv_bfloat16 ret;
|
1605
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1606
|
+
asm("{.reg .b16 low,high;\n"
|
1607
|
+
" mov.b32 {low,high}, %1;\n"
|
1608
|
+
" mov.b16 %0, low;}" : "=h"(__BFLOAT16_TO_US(ret)) : "r"(__BFLOAT162_TO_CUI(a)));
|
1609
|
+
,
|
1610
|
+
ret = a.x;
|
1611
|
+
)
|
1612
|
+
return ret;
|
1613
|
+
}
|
1614
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ int __hisinf(const __nv_bfloat16 a)
|
1615
|
+
{
|
1616
|
+
int retval;
|
1617
|
+
const __nv_bfloat16_raw araw = __nv_bfloat16_raw(a);
|
1618
|
+
if (araw.x == 0xFF80U) {
|
1619
|
+
retval = -1;
|
1620
|
+
} else if (araw.x == 0x7F80U) {
|
1621
|
+
retval = 1;
|
1622
|
+
} else {
|
1623
|
+
retval = 0;
|
1624
|
+
}
|
1625
|
+
return retval;
|
1626
|
+
}
|
1627
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __low2bfloat162(const __nv_bfloat162 a)
|
1628
|
+
{
|
1629
|
+
__nv_bfloat162 val;
|
1630
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1631
|
+
asm("{.reg .b16 low,high;\n"
|
1632
|
+
" mov.b32 {low,high}, %1;\n"
|
1633
|
+
" mov.b32 %0, {low,low};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
1634
|
+
,
|
1635
|
+
val.x = a.x;
|
1636
|
+
val.y = a.x;
|
1637
|
+
)
|
1638
|
+
return val;
|
1639
|
+
}
|
1640
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __high2bfloat162(const __nv_bfloat162 a)
|
1641
|
+
{
|
1642
|
+
__nv_bfloat162 val;
|
1643
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1644
|
+
asm("{.reg .b16 low,high;\n"
|
1645
|
+
" mov.b32 {low,high}, %1;\n"
|
1646
|
+
" mov.b32 %0, {high,high};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
1647
|
+
,
|
1648
|
+
val.x = a.y;
|
1649
|
+
val.y = a.y;
|
1650
|
+
)
|
1651
|
+
return val;
|
1652
|
+
}
|
1653
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __high2bfloat16(const __nv_bfloat162 a)
|
1654
|
+
{
|
1655
|
+
__nv_bfloat16 ret;
|
1656
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1657
|
+
asm("{.reg .b16 low,high;\n"
|
1658
|
+
" mov.b32 {low,high}, %1;\n"
|
1659
|
+
" mov.b16 %0, high;}" : "=h"(__BFLOAT16_TO_US(ret)) : "r"(__BFLOAT162_TO_CUI(a)));
|
1660
|
+
,
|
1661
|
+
ret = a.y;
|
1662
|
+
)
|
1663
|
+
return ret;
|
1664
|
+
}
|
1665
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __halves2bfloat162(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
1666
|
+
{
|
1667
|
+
__nv_bfloat162 val;
|
1668
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1669
|
+
asm("{ mov.b32 %0, {%1,%2};}\n"
|
1670
|
+
: "=r"(__BFLOAT162_TO_UI(val)) : "h"(__BFLOAT16_TO_CUS(a)), "h"(__BFLOAT16_TO_CUS(b)));
|
1671
|
+
,
|
1672
|
+
val.x = a;
|
1673
|
+
val.y = b;
|
1674
|
+
)
|
1675
|
+
return val;
|
1676
|
+
}
|
1677
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __bfloat162bfloat162(const __nv_bfloat16 a)
|
1678
|
+
{
|
1679
|
+
__nv_bfloat162 val;
|
1680
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1681
|
+
asm("{ mov.b32 %0, {%1,%1};}\n"
|
1682
|
+
: "=r"(__BFLOAT162_TO_UI(val)) : "h"(__BFLOAT16_TO_CUS(a)));
|
1683
|
+
,
|
1684
|
+
val.x = a;
|
1685
|
+
val.y = a;
|
1686
|
+
)
|
1687
|
+
return val;
|
1688
|
+
}
|
1689
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __lowhigh2highlow(const __nv_bfloat162 a)
|
1690
|
+
{
|
1691
|
+
__nv_bfloat162 val;
|
1692
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1693
|
+
asm("{.reg .b16 low,high;\n"
|
1694
|
+
" mov.b32 {low,high}, %1;\n"
|
1695
|
+
" mov.b32 %0, {high,low};}\n" : "=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
1696
|
+
,
|
1697
|
+
val.x = a.y;
|
1698
|
+
val.y = a.x;
|
1699
|
+
)
|
1700
|
+
return val;
|
1701
|
+
}
|
1702
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ short int __bfloat16_as_short(const __nv_bfloat16 h)
|
1703
|
+
{
|
1704
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1705
|
+
return static_cast<short int>(__BFLOAT16_TO_CUS(h));
|
1706
|
+
,
|
1707
|
+
return static_cast<short int>(__nv_bfloat16_raw(h).x);
|
1708
|
+
)
|
1709
|
+
}
|
1710
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned short int __bfloat16_as_ushort(const __nv_bfloat16 h)
|
1711
|
+
{
|
1712
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1713
|
+
return __BFLOAT16_TO_CUS(h);
|
1714
|
+
,
|
1715
|
+
return __nv_bfloat16_raw(h).x;
|
1716
|
+
)
|
1717
|
+
}
|
1718
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __short_as_bfloat16(const short int i)
|
1719
|
+
{
|
1720
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1721
|
+
__nv_bfloat16 h;
|
1722
|
+
__BFLOAT16_TO_US(h) = static_cast<unsigned short int>(i);
|
1723
|
+
return h;
|
1724
|
+
,
|
1725
|
+
__nv_bfloat16_raw hr;
|
1726
|
+
hr.x = static_cast<unsigned short int>(i);
|
1727
|
+
return __nv_bfloat16(hr);
|
1728
|
+
)
|
1729
|
+
}
|
1730
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __ushort_as_bfloat16(const unsigned short int i)
|
1731
|
+
{
|
1732
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
1733
|
+
__nv_bfloat16 h;
|
1734
|
+
__BFLOAT16_TO_US(h) = i;
|
1735
|
+
return h;
|
1736
|
+
,
|
1737
|
+
__nv_bfloat16_raw hr;
|
1738
|
+
hr.x = i;
|
1739
|
+
return __nv_bfloat16(hr);
|
1740
|
+
)
|
1741
|
+
}
|
1742
|
+
|
1743
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 300))) || defined(_NVHPC_CUDA)
|
1744
|
+
/******************************************************************************
|
1745
|
+
* __nv_bfloat16, __nv_bfloat162 warp shuffle *
|
1746
|
+
******************************************************************************/
|
1747
|
+
#define __SHUFFLE_SYNC_BFLOAT162_MACRO(name, var, delta, c, mask) /* do */ {\
|
1748
|
+
__nv_bfloat162 r; \
|
1749
|
+
asm volatile ("{" __CUDA_BF16_STRINGIFY(name) " %0,%1,%2,%3,%4;\n}" \
|
1750
|
+
:"=r"(__BFLOAT162_TO_UI(r)): "r"(__BFLOAT162_TO_CUI(var)), "r"(delta), "r"(c), "r"(mask)); \
|
1751
|
+
return r; \
|
1752
|
+
} /* while(0) */
|
1753
|
+
|
1754
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __shfl_sync(const unsigned int mask, const __nv_bfloat162 var, const int srcLane, const int width)
|
1755
|
+
{
|
1756
|
+
unsigned int warp_size;
|
1757
|
+
asm("{mov.u32 %0, WARP_SZ;\n}" : "=r"(warp_size));
|
1758
|
+
const unsigned int c = ((warp_size - static_cast<unsigned>(width)) << 8U) | 0x1fU;
|
1759
|
+
__SHUFFLE_SYNC_BFLOAT162_MACRO(shfl.sync.idx.b32, var, srcLane, c, mask)
|
1760
|
+
}
|
1761
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __shfl_up_sync(const unsigned int mask, const __nv_bfloat162 var, const unsigned int delta, const int width)
|
1762
|
+
{
|
1763
|
+
unsigned int warp_size;
|
1764
|
+
asm("{mov.u32 %0, WARP_SZ;\n}" : "=r"(warp_size));
|
1765
|
+
const unsigned int c = (warp_size - static_cast<unsigned>(width)) << 8U;
|
1766
|
+
__SHUFFLE_SYNC_BFLOAT162_MACRO(shfl.sync.up.b32, var, delta, c, mask)
|
1767
|
+
}
|
1768
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __shfl_down_sync(const unsigned int mask, const __nv_bfloat162 var, const unsigned int delta, const int width)
|
1769
|
+
{
|
1770
|
+
unsigned int warp_size;
|
1771
|
+
asm("{mov.u32 %0, WARP_SZ;\n}" : "=r"(warp_size));
|
1772
|
+
const unsigned int c = ((warp_size - static_cast<unsigned>(width)) << 8U) | 0x1fU;
|
1773
|
+
__SHUFFLE_SYNC_BFLOAT162_MACRO(shfl.sync.down.b32, var, delta, c, mask)
|
1774
|
+
}
|
1775
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __shfl_xor_sync(const unsigned int mask, const __nv_bfloat162 var, const int laneMask, const int width)
|
1776
|
+
{
|
1777
|
+
unsigned int warp_size;
|
1778
|
+
asm("{mov.u32 %0, WARP_SZ;\n}" : "=r"(warp_size));
|
1779
|
+
const unsigned int c = ((warp_size - static_cast<unsigned>(width)) << 8U) | 0x1fU;
|
1780
|
+
__SHUFFLE_SYNC_BFLOAT162_MACRO(shfl.sync.bfly.b32, var, laneMask, c, mask)
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
#undef __SHUFFLE_SYNC_BFLOAT162_MACRO
|
1784
|
+
|
1785
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __shfl_sync(const unsigned int mask, const __nv_bfloat16 var, const int srcLane, const int width)
|
1786
|
+
{
|
1787
|
+
const __nv_bfloat162 temp1 = __halves2bfloat162(var, var);
|
1788
|
+
const __nv_bfloat162 temp2 = __shfl_sync(mask, temp1, srcLane, width);
|
1789
|
+
return __low2bfloat16(temp2);
|
1790
|
+
}
|
1791
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __shfl_up_sync(const unsigned int mask, const __nv_bfloat16 var, const unsigned int delta, const int width)
|
1792
|
+
{
|
1793
|
+
const __nv_bfloat162 temp1 = __halves2bfloat162(var, var);
|
1794
|
+
const __nv_bfloat162 temp2 = __shfl_up_sync(mask, temp1, delta, width);
|
1795
|
+
return __low2bfloat16(temp2);
|
1796
|
+
}
|
1797
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __shfl_down_sync(const unsigned int mask, const __nv_bfloat16 var, const unsigned int delta, const int width)
|
1798
|
+
{
|
1799
|
+
const __nv_bfloat162 temp1 = __halves2bfloat162(var, var);
|
1800
|
+
const __nv_bfloat162 temp2 = __shfl_down_sync(mask, temp1, delta, width);
|
1801
|
+
return __low2bfloat16(temp2);
|
1802
|
+
}
|
1803
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __shfl_xor_sync(const unsigned int mask, const __nv_bfloat16 var, const int laneMask, const int width)
|
1804
|
+
{
|
1805
|
+
const __nv_bfloat162 temp1 = __halves2bfloat162(var, var);
|
1806
|
+
const __nv_bfloat162 temp2 = __shfl_xor_sync(mask, temp1, laneMask, width);
|
1807
|
+
return __low2bfloat16(temp2);
|
1808
|
+
}
|
1809
|
+
|
1810
|
+
/******************************************************************************
|
1811
|
+
* __nv_bfloat16 and __nv_bfloat162 __ldg,__ldcg,__ldca,__ldcs *
|
1812
|
+
******************************************************************************/
|
1813
|
+
|
1814
|
+
#if (defined(_MSC_VER) && defined(_WIN64)) || defined(__LP64__) || defined(__CUDACC_RTC__)
|
1815
|
+
#define __LDG_PTR "l"
|
1816
|
+
#else
|
1817
|
+
#define __LDG_PTR "r"
|
1818
|
+
#endif /*(defined(_MSC_VER) && defined(_WIN64)) || defined(__LP64__) || defined(__CUDACC_RTC__)*/
|
1819
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldg(const __nv_bfloat162 *const ptr)
|
1820
|
+
{
|
1821
|
+
__nv_bfloat162 ret;
|
1822
|
+
asm ("ld.global.nc.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr));
|
1823
|
+
return ret;
|
1824
|
+
}
|
1825
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldg(const __nv_bfloat16 *const ptr)
|
1826
|
+
{
|
1827
|
+
__nv_bfloat16 ret;
|
1828
|
+
asm ("ld.global.nc.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr));
|
1829
|
+
return ret;
|
1830
|
+
}
|
1831
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldcg(const __nv_bfloat162 *const ptr)
|
1832
|
+
{
|
1833
|
+
__nv_bfloat162 ret;
|
1834
|
+
asm ("ld.global.cg.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr));
|
1835
|
+
return ret;
|
1836
|
+
}
|
1837
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldcg(const __nv_bfloat16 *const ptr)
|
1838
|
+
{
|
1839
|
+
__nv_bfloat16 ret;
|
1840
|
+
asm ("ld.global.cg.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr));
|
1841
|
+
return ret;
|
1842
|
+
}
|
1843
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldca(const __nv_bfloat162 *const ptr)
|
1844
|
+
{
|
1845
|
+
__nv_bfloat162 ret;
|
1846
|
+
asm ("ld.global.ca.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr));
|
1847
|
+
return ret;
|
1848
|
+
}
|
1849
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldca(const __nv_bfloat16 *const ptr)
|
1850
|
+
{
|
1851
|
+
__nv_bfloat16 ret;
|
1852
|
+
asm ("ld.global.ca.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr));
|
1853
|
+
return ret;
|
1854
|
+
}
|
1855
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldcs(const __nv_bfloat162 *const ptr)
|
1856
|
+
{
|
1857
|
+
__nv_bfloat162 ret;
|
1858
|
+
asm ("ld.global.cs.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr));
|
1859
|
+
return ret;
|
1860
|
+
}
|
1861
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldcs(const __nv_bfloat16 *const ptr)
|
1862
|
+
{
|
1863
|
+
__nv_bfloat16 ret;
|
1864
|
+
asm ("ld.global.cs.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr));
|
1865
|
+
return ret;
|
1866
|
+
}
|
1867
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldlu(const __nv_bfloat162 *const ptr)
|
1868
|
+
{
|
1869
|
+
__nv_bfloat162 ret;
|
1870
|
+
asm ("ld.global.lu.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr) : "memory");
|
1871
|
+
return ret;
|
1872
|
+
}
|
1873
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldlu(const __nv_bfloat16 *const ptr)
|
1874
|
+
{
|
1875
|
+
__nv_bfloat16 ret;
|
1876
|
+
asm ("ld.global.lu.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr) : "memory");
|
1877
|
+
return ret;
|
1878
|
+
}
|
1879
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __ldcv(const __nv_bfloat162 *const ptr)
|
1880
|
+
{
|
1881
|
+
__nv_bfloat162 ret;
|
1882
|
+
asm ("ld.global.cv.b32 %0, [%1];" : "=r"(__BFLOAT162_TO_UI(ret)) : __LDG_PTR(ptr) : "memory");
|
1883
|
+
return ret;
|
1884
|
+
}
|
1885
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __ldcv(const __nv_bfloat16 *const ptr)
|
1886
|
+
{
|
1887
|
+
__nv_bfloat16 ret;
|
1888
|
+
asm ("ld.global.cv.b16 %0, [%1];" : "=h"(__BFLOAT16_TO_US(ret)) : __LDG_PTR(ptr) : "memory");
|
1889
|
+
return ret;
|
1890
|
+
}
|
1891
|
+
|
1892
|
+
__CUDA_BF16_DECL__ void __stwb(__nv_bfloat162 *const ptr, const __nv_bfloat162 value)
|
1893
|
+
{
|
1894
|
+
asm ("st.global.wb.b32 [%0], %1;" :: __LDG_PTR(ptr), "r"(__BFLOAT162_TO_CUI(value)) : "memory");
|
1895
|
+
}
|
1896
|
+
__CUDA_BF16_DECL__ void __stwb(__nv_bfloat16 *const ptr, const __nv_bfloat16 value)
|
1897
|
+
{
|
1898
|
+
asm ("st.global.wb.b16 [%0], %1;" :: __LDG_PTR(ptr), "h"(__BFLOAT16_TO_CUS(value)) : "memory");
|
1899
|
+
}
|
1900
|
+
__CUDA_BF16_DECL__ void __stcg(__nv_bfloat162 *const ptr, const __nv_bfloat162 value)
|
1901
|
+
{
|
1902
|
+
asm ("st.global.cg.b32 [%0], %1;" :: __LDG_PTR(ptr), "r"(__BFLOAT162_TO_CUI(value)) : "memory");
|
1903
|
+
}
|
1904
|
+
__CUDA_BF16_DECL__ void __stcg(__nv_bfloat16 *const ptr, const __nv_bfloat16 value)
|
1905
|
+
{
|
1906
|
+
asm ("st.global.cg.b16 [%0], %1;" :: __LDG_PTR(ptr), "h"(__BFLOAT16_TO_CUS(value)) : "memory");
|
1907
|
+
}
|
1908
|
+
__CUDA_BF16_DECL__ void __stcs(__nv_bfloat162 *const ptr, const __nv_bfloat162 value)
|
1909
|
+
{
|
1910
|
+
asm ("st.global.cs.b32 [%0], %1;" :: __LDG_PTR(ptr), "r"(__BFLOAT162_TO_CUI(value)) : "memory");
|
1911
|
+
}
|
1912
|
+
__CUDA_BF16_DECL__ void __stcs(__nv_bfloat16 *const ptr, const __nv_bfloat16 value)
|
1913
|
+
{
|
1914
|
+
asm ("st.global.cs.b16 [%0], %1;" :: __LDG_PTR(ptr), "h"(__BFLOAT16_TO_CUS(value)) : "memory");
|
1915
|
+
}
|
1916
|
+
__CUDA_BF16_DECL__ void __stwt(__nv_bfloat162 *const ptr, const __nv_bfloat162 value)
|
1917
|
+
{
|
1918
|
+
asm ("st.global.wt.b32 [%0], %1;" :: __LDG_PTR(ptr), "r"(__BFLOAT162_TO_CUI(value)) : "memory");
|
1919
|
+
}
|
1920
|
+
__CUDA_BF16_DECL__ void __stwt(__nv_bfloat16 *const ptr, const __nv_bfloat16 value)
|
1921
|
+
{
|
1922
|
+
asm ("st.global.wt.b16 [%0], %1;" :: __LDG_PTR(ptr), "h"(__BFLOAT16_TO_CUS(value)) : "memory");
|
1923
|
+
}
|
1924
|
+
|
1925
|
+
#undef __LDG_PTR
|
1926
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 300))) || defined(_NVHPC_CUDA) */
|
1927
|
+
/******************************************************************************
|
1928
|
+
* __nv_bfloat162 comparison *
|
1929
|
+
******************************************************************************/
|
1930
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
1931
|
+
#define __COMPARISON_OP_BFLOAT162_MACRO(name) {\
|
1932
|
+
__nv_bfloat162 val; \
|
1933
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,\
|
1934
|
+
asm( "{ " __CUDA_BF16_STRINGIFY(name) ".bf16x2.bf16x2 %0,%1,%2;\n}" \
|
1935
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b))); \
|
1936
|
+
,\
|
1937
|
+
asm( "{.reg .b32 low_a,low_b,high_a,high_b,high_res,low_res;\n"\
|
1938
|
+
" and.b32 high_a, %1, 0xffff0000U;\n"\
|
1939
|
+
" and.b32 high_b, %2, 0xffff0000U;\n"\
|
1940
|
+
" shl.b32 low_a, %1, 16;\n"\
|
1941
|
+
" shl.b32 low_b, %2, 16;\n"\
|
1942
|
+
" " __CUDA_BF16_STRINGIFY(name) ".f32.f32 low_res, low_a, low_b;\n"\
|
1943
|
+
" " __CUDA_BF16_STRINGIFY(name) ".f32.f32 high_res, high_a, high_b;\n"\
|
1944
|
+
" shr.u32 low_res, low_res, 16;\n"\
|
1945
|
+
" or.b32 %0, high_res, low_res;}\n"\
|
1946
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b))); \
|
1947
|
+
)\
|
1948
|
+
return val; \
|
1949
|
+
}
|
1950
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_heq2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1951
|
+
{
|
1952
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.eq)
|
1953
|
+
}
|
1954
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hne2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1955
|
+
{
|
1956
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.ne)
|
1957
|
+
}
|
1958
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hle2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1959
|
+
{
|
1960
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.le)
|
1961
|
+
}
|
1962
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hge2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1963
|
+
{
|
1964
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.ge)
|
1965
|
+
}
|
1966
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hlt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1967
|
+
{
|
1968
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.lt)
|
1969
|
+
}
|
1970
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hgt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1971
|
+
{
|
1972
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.gt)
|
1973
|
+
}
|
1974
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hequ2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1975
|
+
{
|
1976
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.equ)
|
1977
|
+
}
|
1978
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hneu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1979
|
+
{
|
1980
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.neu)
|
1981
|
+
}
|
1982
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hleu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1983
|
+
{
|
1984
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.leu)
|
1985
|
+
}
|
1986
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hgeu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1987
|
+
{
|
1988
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.geu)
|
1989
|
+
}
|
1990
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hltu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1991
|
+
{
|
1992
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.ltu)
|
1993
|
+
}
|
1994
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hgtu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
1995
|
+
{
|
1996
|
+
__COMPARISON_OP_BFLOAT162_MACRO(set.gtu)
|
1997
|
+
}
|
1998
|
+
#undef __COMPARISON_OP_BFLOAT162_MACRO
|
1999
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
2000
|
+
|
2001
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __heq2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2002
|
+
{
|
2003
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2004
|
+
return __internal_device_heq2(a, b);
|
2005
|
+
,
|
2006
|
+
__nv_bfloat162_raw val;
|
2007
|
+
val.x = __heq(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2008
|
+
val.y = __heq(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2009
|
+
return __nv_bfloat162(val);
|
2010
|
+
)
|
2011
|
+
}
|
2012
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hne2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2013
|
+
{
|
2014
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2015
|
+
return __internal_device_hne2(a, b);
|
2016
|
+
,
|
2017
|
+
__nv_bfloat162_raw val;
|
2018
|
+
val.x = __hne(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2019
|
+
val.y = __hne(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2020
|
+
return __nv_bfloat162(val);
|
2021
|
+
)
|
2022
|
+
}
|
2023
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hle2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2024
|
+
{
|
2025
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2026
|
+
return __internal_device_hle2(a, b);
|
2027
|
+
,
|
2028
|
+
__nv_bfloat162_raw val;
|
2029
|
+
val.x = __hle(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2030
|
+
val.y = __hle(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2031
|
+
return __nv_bfloat162(val);
|
2032
|
+
)
|
2033
|
+
}
|
2034
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hge2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2035
|
+
{
|
2036
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2037
|
+
return __internal_device_hge2(a, b);
|
2038
|
+
,
|
2039
|
+
__nv_bfloat162_raw val;
|
2040
|
+
val.x = __hge(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2041
|
+
val.y = __hge(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2042
|
+
return __nv_bfloat162(val);
|
2043
|
+
)
|
2044
|
+
}
|
2045
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hlt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2046
|
+
{
|
2047
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2048
|
+
return __internal_device_hlt2(a, b);
|
2049
|
+
,
|
2050
|
+
__nv_bfloat162_raw val;
|
2051
|
+
val.x = __hlt(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2052
|
+
val.y = __hlt(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2053
|
+
return __nv_bfloat162(val);
|
2054
|
+
)
|
2055
|
+
}
|
2056
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hgt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2057
|
+
{
|
2058
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2059
|
+
return __internal_device_hgt2(a, b);
|
2060
|
+
,
|
2061
|
+
__nv_bfloat162_raw val;
|
2062
|
+
val.x = __hgt(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2063
|
+
val.y = __hgt(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2064
|
+
return __nv_bfloat162(val);
|
2065
|
+
)
|
2066
|
+
}
|
2067
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hequ2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2068
|
+
{
|
2069
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2070
|
+
return __internal_device_hequ2(a, b);
|
2071
|
+
,
|
2072
|
+
__nv_bfloat162_raw val;
|
2073
|
+
val.x = __hequ(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2074
|
+
val.y = __hequ(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2075
|
+
return __nv_bfloat162(val);
|
2076
|
+
)
|
2077
|
+
}
|
2078
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hneu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2079
|
+
{
|
2080
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2081
|
+
return __internal_device_hneu2(a, b);
|
2082
|
+
,
|
2083
|
+
__nv_bfloat162_raw val;
|
2084
|
+
val.x = __hneu(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2085
|
+
val.y = __hneu(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2086
|
+
return __nv_bfloat162(val);
|
2087
|
+
)
|
2088
|
+
}
|
2089
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hleu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2090
|
+
{
|
2091
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2092
|
+
return __internal_device_hleu2(a, b);
|
2093
|
+
,
|
2094
|
+
__nv_bfloat162_raw val;
|
2095
|
+
val.x = __hleu(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2096
|
+
val.y = __hleu(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2097
|
+
return __nv_bfloat162(val);
|
2098
|
+
)
|
2099
|
+
}
|
2100
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hgeu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2101
|
+
{
|
2102
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2103
|
+
return __internal_device_hgeu2(a, b);
|
2104
|
+
,
|
2105
|
+
__nv_bfloat162_raw val;
|
2106
|
+
val.x = __hgeu(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2107
|
+
val.y = __hgeu(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2108
|
+
return __nv_bfloat162(val);
|
2109
|
+
)
|
2110
|
+
}
|
2111
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hltu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2112
|
+
{
|
2113
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2114
|
+
return __internal_device_hltu2(a, b);
|
2115
|
+
,
|
2116
|
+
__nv_bfloat162_raw val;
|
2117
|
+
val.x = __hltu(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2118
|
+
val.y = __hltu(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2119
|
+
return __nv_bfloat162(val);
|
2120
|
+
)
|
2121
|
+
}
|
2122
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hgtu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2123
|
+
{
|
2124
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2125
|
+
return __internal_device_hgtu2(a, b);
|
2126
|
+
,
|
2127
|
+
__nv_bfloat162_raw val;
|
2128
|
+
val.x = __hgtu(a.x, b.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2129
|
+
val.y = __hgtu(a.y, b.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
2130
|
+
return __nv_bfloat162(val);
|
2131
|
+
)
|
2132
|
+
}
|
2133
|
+
|
2134
|
+
/******************************************************************************
|
2135
|
+
* __nv_bfloat162 comparison with mask output *
|
2136
|
+
******************************************************************************/
|
2137
|
+
#define __COMPARISON_OP_BFLOAT162_MACRO_MASK(name) {\
|
2138
|
+
unsigned val; \
|
2139
|
+
asm( "{ " __CUDA_BF16_STRINGIFY(name) ".u32.bf16x2 %0,%1,%2;\n}" \
|
2140
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b))); \
|
2141
|
+
return val; \
|
2142
|
+
}
|
2143
|
+
|
2144
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __heq2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2145
|
+
{
|
2146
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2147
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.eq)
|
2148
|
+
,
|
2149
|
+
const unsigned short px = __heq(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2150
|
+
const unsigned short py = __heq(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2151
|
+
unsigned ur = (unsigned)py;
|
2152
|
+
ur <<= (unsigned)16U;
|
2153
|
+
ur |= (unsigned)px;
|
2154
|
+
return ur;
|
2155
|
+
)
|
2156
|
+
}
|
2157
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hne2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2158
|
+
{
|
2159
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2160
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.ne)
|
2161
|
+
,
|
2162
|
+
const unsigned short px = __hne(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2163
|
+
const unsigned short py = __hne(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2164
|
+
unsigned ur = (unsigned)py;
|
2165
|
+
ur <<= (unsigned)16U;
|
2166
|
+
ur |= (unsigned)px;
|
2167
|
+
return ur;
|
2168
|
+
)
|
2169
|
+
}
|
2170
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hle2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2171
|
+
{
|
2172
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2173
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.le)
|
2174
|
+
,
|
2175
|
+
const unsigned short px = __hle(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2176
|
+
const unsigned short py = __hle(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2177
|
+
unsigned ur = (unsigned)py;
|
2178
|
+
ur <<= (unsigned)16U;
|
2179
|
+
ur |= (unsigned)px;
|
2180
|
+
return ur;
|
2181
|
+
)
|
2182
|
+
}
|
2183
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hge2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2184
|
+
{
|
2185
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2186
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.ge)
|
2187
|
+
,
|
2188
|
+
const unsigned short px = __hge(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2189
|
+
const unsigned short py = __hge(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2190
|
+
unsigned ur = (unsigned)py;
|
2191
|
+
ur <<= (unsigned)16U;
|
2192
|
+
ur |= (unsigned)px;
|
2193
|
+
return ur;
|
2194
|
+
)
|
2195
|
+
}
|
2196
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hlt2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2197
|
+
{
|
2198
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2199
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.lt)
|
2200
|
+
,
|
2201
|
+
const unsigned short px = __hlt(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2202
|
+
const unsigned short py = __hlt(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2203
|
+
unsigned ur = (unsigned)py;
|
2204
|
+
ur <<= (unsigned)16U;
|
2205
|
+
ur |= (unsigned)px;
|
2206
|
+
return ur;
|
2207
|
+
)
|
2208
|
+
}
|
2209
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hgt2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2210
|
+
{
|
2211
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2212
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.gt)
|
2213
|
+
,
|
2214
|
+
const unsigned short px = __hgt(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2215
|
+
const unsigned short py = __hgt(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2216
|
+
unsigned ur = (unsigned)py;
|
2217
|
+
ur <<= (unsigned)16U;
|
2218
|
+
ur |= (unsigned)px;
|
2219
|
+
return ur;
|
2220
|
+
)
|
2221
|
+
}
|
2222
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hequ2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2223
|
+
{
|
2224
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2225
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.equ)
|
2226
|
+
,
|
2227
|
+
const unsigned short px = __hequ(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2228
|
+
const unsigned short py = __hequ(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2229
|
+
unsigned ur = (unsigned)py;
|
2230
|
+
ur <<= (unsigned)16U;
|
2231
|
+
ur |= (unsigned)px;
|
2232
|
+
return ur;
|
2233
|
+
)
|
2234
|
+
}
|
2235
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hneu2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2236
|
+
{
|
2237
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2238
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.neu)
|
2239
|
+
,
|
2240
|
+
const unsigned short px = __hneu(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2241
|
+
const unsigned short py = __hneu(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2242
|
+
unsigned ur = (unsigned)py;
|
2243
|
+
ur <<= (unsigned)16U;
|
2244
|
+
ur |= (unsigned)px;
|
2245
|
+
return ur;
|
2246
|
+
)
|
2247
|
+
}
|
2248
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hleu2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2249
|
+
{
|
2250
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2251
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.leu)
|
2252
|
+
,
|
2253
|
+
const unsigned short px = __hleu(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2254
|
+
const unsigned short py = __hleu(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2255
|
+
unsigned ur = (unsigned)py;
|
2256
|
+
ur <<= (unsigned)16U;
|
2257
|
+
ur |= (unsigned)px;
|
2258
|
+
return ur;
|
2259
|
+
)
|
2260
|
+
}
|
2261
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hgeu2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2262
|
+
{
|
2263
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2264
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.geu)
|
2265
|
+
,
|
2266
|
+
const unsigned short px = __hgeu(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2267
|
+
const unsigned short py = __hgeu(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2268
|
+
unsigned ur = (unsigned)py;
|
2269
|
+
ur <<= (unsigned)16U;
|
2270
|
+
ur |= (unsigned)px;
|
2271
|
+
return ur;
|
2272
|
+
)
|
2273
|
+
}
|
2274
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hltu2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2275
|
+
{
|
2276
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2277
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.ltu)
|
2278
|
+
,
|
2279
|
+
const unsigned short px = __hltu(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2280
|
+
const unsigned short py = __hltu(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2281
|
+
unsigned ur = (unsigned)py;
|
2282
|
+
ur <<= (unsigned)16U;
|
2283
|
+
ur |= (unsigned)px;
|
2284
|
+
return ur;
|
2285
|
+
)
|
2286
|
+
}
|
2287
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ unsigned int __hgtu2_mask(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2288
|
+
{
|
2289
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2290
|
+
__COMPARISON_OP_BFLOAT162_MACRO_MASK(set.gtu)
|
2291
|
+
,
|
2292
|
+
const unsigned short px = __hgtu(a.x, b.x) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2293
|
+
const unsigned short py = __hgtu(a.y, b.y) ? (unsigned short)0xFFFFU : (unsigned short)0U;
|
2294
|
+
unsigned ur = (unsigned)py;
|
2295
|
+
ur <<= (unsigned)16U;
|
2296
|
+
ur |= (unsigned)px;
|
2297
|
+
return ur;
|
2298
|
+
)
|
2299
|
+
}
|
2300
|
+
#undef __COMPARISON_OP_BFLOAT162_MACRO_MASK
|
2301
|
+
|
2302
|
+
#define __BOOL_COMPARISON_OP_BFLOAT162_MACRO(name) {\
|
2303
|
+
unsigned int val; \
|
2304
|
+
bool retval; \
|
2305
|
+
asm( "{ " __CUDA_BF16_STRINGIFY(name) ".bf16x2.bf16x2 %0,%1,%2;\n}" \
|
2306
|
+
:"=r"(val) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b))); \
|
2307
|
+
if (val == 0x3F803F80U) {\
|
2308
|
+
retval = true; \
|
2309
|
+
} else { \
|
2310
|
+
retval = false; \
|
2311
|
+
}\
|
2312
|
+
return retval;\
|
2313
|
+
}
|
2314
|
+
|
2315
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbeq2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2316
|
+
{
|
2317
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2318
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.eq)
|
2319
|
+
,
|
2320
|
+
return (__heq(a.x, b.x) && __heq(a.y, b.y));
|
2321
|
+
)
|
2322
|
+
}
|
2323
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbne2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2324
|
+
{
|
2325
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2326
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.ne)
|
2327
|
+
,
|
2328
|
+
return (__hne(a.x, b.x) && __hne(a.y, b.y));
|
2329
|
+
)
|
2330
|
+
}
|
2331
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hble2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2332
|
+
{
|
2333
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2334
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.le)
|
2335
|
+
,
|
2336
|
+
return (__hle(a.x, b.x) && __hle(a.y, b.y));
|
2337
|
+
)
|
2338
|
+
}
|
2339
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbge2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2340
|
+
{
|
2341
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2342
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.ge)
|
2343
|
+
,
|
2344
|
+
return (__hge(a.x, b.x) && __hge(a.y, b.y));
|
2345
|
+
)
|
2346
|
+
}
|
2347
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hblt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2348
|
+
{
|
2349
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2350
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.lt)
|
2351
|
+
,
|
2352
|
+
return (__hlt(a.x, b.x) && __hlt(a.y, b.y));
|
2353
|
+
)
|
2354
|
+
}
|
2355
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbgt2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2356
|
+
{
|
2357
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2358
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.gt)
|
2359
|
+
,
|
2360
|
+
return (__hgt(a.x, b.x) && __hgt(a.y, b.y));
|
2361
|
+
)
|
2362
|
+
}
|
2363
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbequ2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2364
|
+
{
|
2365
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2366
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.equ)
|
2367
|
+
,
|
2368
|
+
return (__hequ(a.x, b.x) && __hequ(a.y, b.y));
|
2369
|
+
)
|
2370
|
+
}
|
2371
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbneu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2372
|
+
{
|
2373
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2374
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.neu)
|
2375
|
+
,
|
2376
|
+
return (__hneu(a.x, b.x) && __hneu(a.y, b.y));
|
2377
|
+
)
|
2378
|
+
}
|
2379
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbleu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2380
|
+
{
|
2381
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2382
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.leu)
|
2383
|
+
,
|
2384
|
+
return (__hleu(a.x, b.x) && __hleu(a.y, b.y));
|
2385
|
+
)
|
2386
|
+
}
|
2387
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbgeu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2388
|
+
{
|
2389
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2390
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.geu)
|
2391
|
+
,
|
2392
|
+
return (__hgeu(a.x, b.x) && __hgeu(a.y, b.y));
|
2393
|
+
)
|
2394
|
+
}
|
2395
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbltu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2396
|
+
{
|
2397
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2398
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.ltu)
|
2399
|
+
,
|
2400
|
+
return (__hltu(a.x, b.x) && __hltu(a.y, b.y));
|
2401
|
+
)
|
2402
|
+
}
|
2403
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hbgtu2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2404
|
+
{
|
2405
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2406
|
+
__BOOL_COMPARISON_OP_BFLOAT162_MACRO(set.gtu)
|
2407
|
+
,
|
2408
|
+
return (__hgtu(a.x, b.x) && __hgtu(a.y, b.y));
|
2409
|
+
)
|
2410
|
+
}
|
2411
|
+
#undef __BOOL_COMPARISON_OP_BFLOAT162_MACRO
|
2412
|
+
/******************************************************************************
|
2413
|
+
* __nv_bfloat16 comparison *
|
2414
|
+
******************************************************************************/
|
2415
|
+
#define __COMPARISON_OP_BFLOAT16_MACRO(name) {\
|
2416
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,\
|
2417
|
+
unsigned short val; \
|
2418
|
+
asm( "{ .reg .pred __$temp3;\n" \
|
2419
|
+
" setp." __CUDA_BF16_STRINGIFY(name) ".bf16 __$temp3, %1, %2;\n" \
|
2420
|
+
" selp.u16 %0, 1, 0, __$temp3;}" \
|
2421
|
+
: "=h"(val) : "h"(__BFLOAT16_TO_CUS(a)), "h"(__BFLOAT16_TO_CUS(b))); \
|
2422
|
+
return (val != 0U) ? true : false; \
|
2423
|
+
,\
|
2424
|
+
unsigned int val; \
|
2425
|
+
asm( "{.reg .b32 a,b;\n"\
|
2426
|
+
" mov.b32 a, {0, %1};\n"\
|
2427
|
+
" mov.b32 b, {0, %2};\n"\
|
2428
|
+
" set." __CUDA_BF16_STRINGIFY(name) ".f32.f32 %0, a, b;}\n"\
|
2429
|
+
:"=r"(val) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b))); \
|
2430
|
+
return (val != 0U) ? true : false; \
|
2431
|
+
)\
|
2432
|
+
}
|
2433
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __heq(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2434
|
+
{
|
2435
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2436
|
+
__COMPARISON_OP_BFLOAT16_MACRO(eq)
|
2437
|
+
,
|
2438
|
+
const float fa = __bfloat162float(a);
|
2439
|
+
const float fb = __bfloat162float(b);
|
2440
|
+
return (fa == fb);
|
2441
|
+
)
|
2442
|
+
}
|
2443
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hne(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2444
|
+
{
|
2445
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2446
|
+
__COMPARISON_OP_BFLOAT16_MACRO(ne)
|
2447
|
+
,
|
2448
|
+
const float fa = __bfloat162float(a);
|
2449
|
+
const float fb = __bfloat162float(b);
|
2450
|
+
return (fa != fb) && (!__hisnan(a)) && (!__hisnan(b));
|
2451
|
+
)
|
2452
|
+
}
|
2453
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hle(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2454
|
+
{
|
2455
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2456
|
+
__COMPARISON_OP_BFLOAT16_MACRO(le)
|
2457
|
+
,
|
2458
|
+
const float fa = __bfloat162float(a);
|
2459
|
+
const float fb = __bfloat162float(b);
|
2460
|
+
return (fa <= fb);
|
2461
|
+
)
|
2462
|
+
}
|
2463
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hge(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2464
|
+
{
|
2465
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2466
|
+
__COMPARISON_OP_BFLOAT16_MACRO(ge)
|
2467
|
+
,
|
2468
|
+
const float fa = __bfloat162float(a);
|
2469
|
+
const float fb = __bfloat162float(b);
|
2470
|
+
return (fa >= fb);
|
2471
|
+
)
|
2472
|
+
}
|
2473
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hlt(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2474
|
+
{
|
2475
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2476
|
+
__COMPARISON_OP_BFLOAT16_MACRO(lt)
|
2477
|
+
,
|
2478
|
+
const float fa = __bfloat162float(a);
|
2479
|
+
const float fb = __bfloat162float(b);
|
2480
|
+
return (fa < fb);
|
2481
|
+
)
|
2482
|
+
}
|
2483
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hgt(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2484
|
+
{
|
2485
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2486
|
+
__COMPARISON_OP_BFLOAT16_MACRO(gt)
|
2487
|
+
,
|
2488
|
+
const float fa = __bfloat162float(a);
|
2489
|
+
const float fb = __bfloat162float(b);
|
2490
|
+
return (fa > fb);
|
2491
|
+
)
|
2492
|
+
}
|
2493
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hequ(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2494
|
+
{
|
2495
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2496
|
+
__COMPARISON_OP_BFLOAT16_MACRO(equ)
|
2497
|
+
,
|
2498
|
+
const float fa = __bfloat162float(a);
|
2499
|
+
const float fb = __bfloat162float(b);
|
2500
|
+
return (fa == fb) || (__hisnan(a)) || (__hisnan(b));
|
2501
|
+
)
|
2502
|
+
}
|
2503
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hneu(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2504
|
+
{
|
2505
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2506
|
+
__COMPARISON_OP_BFLOAT16_MACRO(neu)
|
2507
|
+
,
|
2508
|
+
const float fa = __bfloat162float(a);
|
2509
|
+
const float fb = __bfloat162float(b);
|
2510
|
+
return (fa != fb);
|
2511
|
+
)
|
2512
|
+
}
|
2513
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hleu(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2514
|
+
{
|
2515
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2516
|
+
__COMPARISON_OP_BFLOAT16_MACRO(leu)
|
2517
|
+
,
|
2518
|
+
const float fa = __bfloat162float(a);
|
2519
|
+
const float fb = __bfloat162float(b);
|
2520
|
+
return (fa <= fb) || (__hisnan(a)) || (__hisnan(b));
|
2521
|
+
)
|
2522
|
+
}
|
2523
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hgeu(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2524
|
+
{
|
2525
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2526
|
+
__COMPARISON_OP_BFLOAT16_MACRO(geu)
|
2527
|
+
,
|
2528
|
+
const float fa = __bfloat162float(a);
|
2529
|
+
const float fb = __bfloat162float(b);
|
2530
|
+
return (fa >= fb) || (__hisnan(a)) || (__hisnan(b));
|
2531
|
+
)
|
2532
|
+
}
|
2533
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hltu(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2534
|
+
{
|
2535
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2536
|
+
__COMPARISON_OP_BFLOAT16_MACRO(ltu)
|
2537
|
+
,
|
2538
|
+
const float fa = __bfloat162float(a);
|
2539
|
+
const float fb = __bfloat162float(b);
|
2540
|
+
return (fa < fb) || (__hisnan(a)) || (__hisnan(b));
|
2541
|
+
)
|
2542
|
+
}
|
2543
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hgtu(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2544
|
+
{
|
2545
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2546
|
+
__COMPARISON_OP_BFLOAT16_MACRO(gtu)
|
2547
|
+
,
|
2548
|
+
const float fa = __bfloat162float(a);
|
2549
|
+
const float fb = __bfloat162float(b);
|
2550
|
+
return (fa > fb) || (__hisnan(a)) || (__hisnan(b));
|
2551
|
+
)
|
2552
|
+
}
|
2553
|
+
#undef __COMPARISON_OP_BFLOAT16_MACRO
|
2554
|
+
/******************************************************************************
|
2555
|
+
* __nv_bfloat162 arithmetic *
|
2556
|
+
******************************************************************************/
|
2557
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
2558
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hadd2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2559
|
+
{
|
2560
|
+
__nv_bfloat162 val;
|
2561
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2562
|
+
asm( "{ add.bf16x2 %0,%1,%2; }\n"
|
2563
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2564
|
+
,
|
2565
|
+
asm( "{.reg .b32 c;\n"
|
2566
|
+
" mov.b32 c, 0x3f803f80U;\n"
|
2567
|
+
" fma.rn.bf16x2 %0,%1,c,%2;}\n"
|
2568
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2569
|
+
)
|
2570
|
+
return val;
|
2571
|
+
}
|
2572
|
+
|
2573
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hsub2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2574
|
+
{
|
2575
|
+
__nv_bfloat162 val;
|
2576
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2577
|
+
asm( "{ sub.bf16x2 %0,%1,%2; }\n"
|
2578
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2579
|
+
,
|
2580
|
+
asm( "{.reg .b32 c;\n"
|
2581
|
+
" mov.b32 c, 0xbf80bf80U;\n"
|
2582
|
+
" fma.rn.bf16x2 %0,%2,c,%1;}\n"
|
2583
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2584
|
+
)
|
2585
|
+
return val;
|
2586
|
+
}
|
2587
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hmul2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2588
|
+
{
|
2589
|
+
__nv_bfloat162 val;
|
2590
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2591
|
+
asm( "{ mul.bf16x2 %0,%1,%2; }\n"
|
2592
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2593
|
+
,
|
2594
|
+
asm( "{.reg .b32 c;\n"
|
2595
|
+
" mov.b32 c, 0x80008000U;\n"
|
2596
|
+
" fma.rn.bf16x2 %0,%1,%2,c;}\n"
|
2597
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2598
|
+
)
|
2599
|
+
return val;
|
2600
|
+
}
|
2601
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hadd2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2602
|
+
{
|
2603
|
+
__nv_bfloat162 val;
|
2604
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2605
|
+
asm( "{ add.rn.bf16x2 %0,%1,%2; }\n"
|
2606
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2607
|
+
,
|
2608
|
+
asm( "{.reg .b32 c;\n"
|
2609
|
+
" mov.b32 c, 0x3f803f80U;\n"
|
2610
|
+
" fma.rn.bf16x2 %0,%1,c,%2;}\n"
|
2611
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2612
|
+
)
|
2613
|
+
return val;
|
2614
|
+
}
|
2615
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hsub2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2616
|
+
{
|
2617
|
+
__nv_bfloat162 val;
|
2618
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2619
|
+
asm( "{ sub.rn.bf16x2 %0,%1,%2; }\n"
|
2620
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2621
|
+
,
|
2622
|
+
asm( "{.reg .b32 c;\n"
|
2623
|
+
" mov.b32 c, 0xbf80bf80U;\n"
|
2624
|
+
" fma.rn.bf16x2 %0,%2,c,%1;}\n"
|
2625
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2626
|
+
)
|
2627
|
+
return val;
|
2628
|
+
}
|
2629
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __internal_device_hmul2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2630
|
+
{
|
2631
|
+
__nv_bfloat162 val;
|
2632
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2633
|
+
asm( "{ mul.rn.bf16x2 %0,%1,%2; }\n"
|
2634
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2635
|
+
,
|
2636
|
+
asm( "{.reg .b32 c;\n"
|
2637
|
+
" mov.b32 c, 0x80008000U;\n"
|
2638
|
+
" fma.rn.bf16x2 %0,%1,%2,c;}\n"
|
2639
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2640
|
+
)
|
2641
|
+
return val;
|
2642
|
+
}
|
2643
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
2644
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hadd2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2645
|
+
{
|
2646
|
+
__nv_bfloat162 val;
|
2647
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2648
|
+
val = __internal_device_hadd2(a, b);
|
2649
|
+
,
|
2650
|
+
val.x = __hadd(a.x, b.x);
|
2651
|
+
val.y = __hadd(a.y, b.y);
|
2652
|
+
)
|
2653
|
+
return val;
|
2654
|
+
}
|
2655
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hsub2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2656
|
+
{
|
2657
|
+
__nv_bfloat162 val;
|
2658
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2659
|
+
val = __internal_device_hsub2(a, b);
|
2660
|
+
,
|
2661
|
+
val.x = __hsub(a.x, b.x);
|
2662
|
+
val.y = __hsub(a.y, b.y);
|
2663
|
+
)
|
2664
|
+
return val;
|
2665
|
+
}
|
2666
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmul2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2667
|
+
{
|
2668
|
+
__nv_bfloat162 val;
|
2669
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2670
|
+
val = __internal_device_hmul2(a, b);
|
2671
|
+
,
|
2672
|
+
val.x = __hmul(a.x, b.x);
|
2673
|
+
val.y = __hmul(a.y, b.y);
|
2674
|
+
)
|
2675
|
+
return val;
|
2676
|
+
}
|
2677
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hadd2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2678
|
+
{
|
2679
|
+
__nv_bfloat162 val;
|
2680
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2681
|
+
val = __internal_device_hadd2_rn(a, b);
|
2682
|
+
,
|
2683
|
+
val.x = __hadd_rn(a.x, b.x);
|
2684
|
+
val.y = __hadd_rn(a.y, b.y);
|
2685
|
+
)
|
2686
|
+
return val;
|
2687
|
+
}
|
2688
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hsub2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2689
|
+
{
|
2690
|
+
__nv_bfloat162 val;
|
2691
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2692
|
+
val = __internal_device_hsub2_rn(a, b);
|
2693
|
+
,
|
2694
|
+
val.x = __hsub_rn(a.x, b.x);
|
2695
|
+
val.y = __hsub_rn(a.y, b.y);
|
2696
|
+
)
|
2697
|
+
return val;
|
2698
|
+
}
|
2699
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmul2_rn(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2700
|
+
{
|
2701
|
+
__nv_bfloat162 val;
|
2702
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2703
|
+
val = __internal_device_hmul2_rn(a, b);
|
2704
|
+
,
|
2705
|
+
val.x = __hmul_rn(a.x, b.x);
|
2706
|
+
val.y = __hmul_rn(a.y, b.y);
|
2707
|
+
)
|
2708
|
+
return val;
|
2709
|
+
}
|
2710
|
+
|
2711
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hadd2_sat(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2712
|
+
{
|
2713
|
+
__nv_bfloat162 val;
|
2714
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2715
|
+
asm( "{.reg .b32 f, one, zero;\n"
|
2716
|
+
" mov.b32 one, 0x3f803f80U;\n"
|
2717
|
+
" mov.b32 zero, 0;\n"
|
2718
|
+
" fma.rn.bf16x2 f,%1,one,%2;\n"
|
2719
|
+
" max.bf16x2 f, f, zero;\n"
|
2720
|
+
" min.bf16x2 %0, f, one;\n}"
|
2721
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2722
|
+
,
|
2723
|
+
val.x = __hadd_sat(a.x, b.x);
|
2724
|
+
val.y = __hadd_sat(a.y, b.y);
|
2725
|
+
)
|
2726
|
+
return val;
|
2727
|
+
}
|
2728
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hsub2_sat(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2729
|
+
{
|
2730
|
+
__nv_bfloat162 val;
|
2731
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2732
|
+
asm( "{.reg .b32 f, one, zero, mone;\n"
|
2733
|
+
" mov.b32 one, 0x3f803f80U;\n"
|
2734
|
+
" mov.b32 zero, 0;\n"
|
2735
|
+
" mov.b32 mone, 0xbf80bf80U;\n"
|
2736
|
+
" fma.rn.bf16x2 f,%2,mone,%1;\n"
|
2737
|
+
" max.bf16x2 f, f, zero;\n"
|
2738
|
+
" min.bf16x2 %0, f, one;\n}"
|
2739
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2740
|
+
,
|
2741
|
+
val.x = __hsub_sat(a.x, b.x);
|
2742
|
+
val.y = __hsub_sat(a.y, b.y);
|
2743
|
+
)
|
2744
|
+
return val;
|
2745
|
+
}
|
2746
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmul2_sat(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
2747
|
+
{
|
2748
|
+
__nv_bfloat162 val;
|
2749
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2750
|
+
asm( "{.reg .b32 f, one, zero, mzero;\n"
|
2751
|
+
" mov.b32 one, 0x3f803f80U;\n"
|
2752
|
+
" mov.b32 zero, 0;\n"
|
2753
|
+
" mov.b32 mzero, 0x80008000U;\n"
|
2754
|
+
" fma.rn.bf16x2 f,%1,%2,mzero;\n"
|
2755
|
+
" max.bf16x2 f, f, zero;\n"
|
2756
|
+
" min.bf16x2 %0, f, one;\n}"
|
2757
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
2758
|
+
,
|
2759
|
+
val.x = __hmul_sat(a.x, b.x);
|
2760
|
+
val.y = __hmul_sat(a.y, b.y);
|
2761
|
+
)
|
2762
|
+
return val;
|
2763
|
+
}
|
2764
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
2765
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __hfma2(const __nv_bfloat162 a, const __nv_bfloat162 b, const __nv_bfloat162 c)
|
2766
|
+
{
|
2767
|
+
__nv_bfloat162 val;
|
2768
|
+
asm( "{fma.rn.bf16x2 %0,%1,%2,%3;\n}"
|
2769
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)),"r"(__BFLOAT162_TO_CUI(c)));
|
2770
|
+
return val;
|
2771
|
+
}
|
2772
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __hfma2_sat(const __nv_bfloat162 a, const __nv_bfloat162 b, const __nv_bfloat162 c)
|
2773
|
+
{
|
2774
|
+
__nv_bfloat162 val;
|
2775
|
+
asm( "{ .reg .b32 f, one, zero;\n"
|
2776
|
+
" mov.b32 one, 0x3f803f80U;\n"
|
2777
|
+
" mov.b32 zero, 0;\n"
|
2778
|
+
" fma.rn.bf16x2 f, %1, %2, %3;\n"
|
2779
|
+
" max.bf16x2 f, f, zero;\n"
|
2780
|
+
" min.bf16x2 %0, f, one;\n}"
|
2781
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)),"r"(__BFLOAT162_TO_CUI(c)));
|
2782
|
+
return val;
|
2783
|
+
}
|
2784
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
2785
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __h2div(const __nv_bfloat162 a, const __nv_bfloat162 b) {
|
2786
|
+
__nv_bfloat16 ha, hb;
|
2787
|
+
|
2788
|
+
ha = __low2bfloat16(a);
|
2789
|
+
hb = __low2bfloat16(b);
|
2790
|
+
|
2791
|
+
const __nv_bfloat16 v1 = __hdiv(ha, hb);
|
2792
|
+
|
2793
|
+
ha = __high2bfloat16(a);
|
2794
|
+
hb = __high2bfloat16(b);
|
2795
|
+
|
2796
|
+
const __nv_bfloat16 v2 = __hdiv(ha, hb);
|
2797
|
+
|
2798
|
+
return __halves2bfloat162(v1, v2);
|
2799
|
+
}
|
2800
|
+
/******************************************************************************
|
2801
|
+
* __nv_bfloat16 arithmetic *
|
2802
|
+
******************************************************************************/
|
2803
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
2804
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hadd(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2805
|
+
{
|
2806
|
+
__nv_bfloat16 val;
|
2807
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2808
|
+
asm( "{ add.bf16 %0,%1,%2; }\n"
|
2809
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2810
|
+
,
|
2811
|
+
asm( "{.reg .b16 c;\n"
|
2812
|
+
" mov.b16 c, 0x3f80U;\n"
|
2813
|
+
" fma.rn.bf16 %0,%1,c,%2;}\n"
|
2814
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2815
|
+
)
|
2816
|
+
return val;
|
2817
|
+
}
|
2818
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hsub(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2819
|
+
{
|
2820
|
+
__nv_bfloat16 val;
|
2821
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2822
|
+
asm( "{ sub.bf16 %0,%1,%2; }\n"
|
2823
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2824
|
+
,
|
2825
|
+
asm( "{.reg .b16 c;\n"
|
2826
|
+
" mov.b16 c, 0xbf80U;\n"
|
2827
|
+
" fma.rn.bf16 %0,%2,c,%1;}\n"
|
2828
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2829
|
+
)
|
2830
|
+
return val;
|
2831
|
+
}
|
2832
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hmul(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2833
|
+
{
|
2834
|
+
__nv_bfloat16 val;
|
2835
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2836
|
+
asm( "{ mul.bf16 %0,%1,%2; }\n"
|
2837
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2838
|
+
,
|
2839
|
+
asm( "{.reg .b16 c;\n"
|
2840
|
+
" mov.b16 c, 0x8000U;\n"
|
2841
|
+
" fma.rn.bf16 %0,%1,%2,c;}\n"
|
2842
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2843
|
+
)
|
2844
|
+
return val;
|
2845
|
+
}
|
2846
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hadd_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2847
|
+
{
|
2848
|
+
__nv_bfloat16 val;
|
2849
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2850
|
+
asm( "{ add.rn.bf16 %0,%1,%2; }\n"
|
2851
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2852
|
+
,
|
2853
|
+
asm( "{.reg .b16 c;\n"
|
2854
|
+
" mov.b16 c, 0x3f80U;\n"
|
2855
|
+
" fma.rn.bf16 %0,%1,c,%2;}\n"
|
2856
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2857
|
+
)
|
2858
|
+
return val;
|
2859
|
+
}
|
2860
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hsub_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2861
|
+
{
|
2862
|
+
__nv_bfloat16 val;
|
2863
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2864
|
+
asm( "{ sub.rn.bf16 %0,%1,%2; }\n"
|
2865
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2866
|
+
,
|
2867
|
+
asm( "{.reg .b16 c;\n"
|
2868
|
+
" mov.b16 c, 0xbf80U;\n"
|
2869
|
+
" fma.rn.bf16 %0,%2,c,%1;}\n"
|
2870
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2871
|
+
)
|
2872
|
+
return val;
|
2873
|
+
}
|
2874
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_sm80_device_hmul_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2875
|
+
{
|
2876
|
+
__nv_bfloat16 val;
|
2877
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
2878
|
+
asm( "{ mul.rn.bf16 %0,%1,%2; }\n"
|
2879
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2880
|
+
,
|
2881
|
+
asm( "{.reg .b16 c;\n"
|
2882
|
+
" mov.b16 c, 0x8000U;\n"
|
2883
|
+
" fma.rn.bf16 %0,%1,%2,c;}\n"
|
2884
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2885
|
+
)
|
2886
|
+
return val;
|
2887
|
+
}
|
2888
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
2889
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
2890
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_hadd(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2891
|
+
{
|
2892
|
+
__nv_bfloat16 val;
|
2893
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2894
|
+
val = __internal_sm80_device_hadd(a, b);
|
2895
|
+
,
|
2896
|
+
const float fa = __bfloat162float(a);
|
2897
|
+
const float fb = __bfloat162float(b);
|
2898
|
+
// avoid ftz in device code
|
2899
|
+
val = __float2bfloat16(__fmaf_ieee_rn(fa, 1.0f, fb));
|
2900
|
+
)
|
2901
|
+
return val;
|
2902
|
+
}
|
2903
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_hsub(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2904
|
+
{
|
2905
|
+
__nv_bfloat16 val;
|
2906
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2907
|
+
val = __internal_sm80_device_hsub(a, b);
|
2908
|
+
,
|
2909
|
+
const float fa = __bfloat162float(a);
|
2910
|
+
const float fb = __bfloat162float(b);
|
2911
|
+
// avoid ftz in device code
|
2912
|
+
val = __float2bfloat16(__fmaf_ieee_rn(fb, -1.0f, fa));
|
2913
|
+
)
|
2914
|
+
return val;
|
2915
|
+
}
|
2916
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_hmul(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2917
|
+
{
|
2918
|
+
__nv_bfloat16 val;
|
2919
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2920
|
+
val = __internal_sm80_device_hmul(a, b);
|
2921
|
+
,
|
2922
|
+
const float fa = __bfloat162float(a);
|
2923
|
+
const float fb = __bfloat162float(b);
|
2924
|
+
// avoid ftz in device code
|
2925
|
+
val = __float2bfloat16(__fmaf_ieee_rn(fa, fb, -0.0f));
|
2926
|
+
)
|
2927
|
+
return val;
|
2928
|
+
}
|
2929
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
2930
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hadd(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2931
|
+
{
|
2932
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2933
|
+
return __internal_device_hadd(a, b);
|
2934
|
+
,
|
2935
|
+
const float fa = __bfloat162float(a);
|
2936
|
+
const float fb = __bfloat162float(b);
|
2937
|
+
return __float2bfloat16(fa + fb);
|
2938
|
+
)
|
2939
|
+
}
|
2940
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hsub(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2941
|
+
{
|
2942
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2943
|
+
return __internal_device_hsub(a, b);
|
2944
|
+
,
|
2945
|
+
const float fa = __bfloat162float(a);
|
2946
|
+
const float fb = __bfloat162float(b);
|
2947
|
+
return __float2bfloat16(fa - fb);
|
2948
|
+
)
|
2949
|
+
}
|
2950
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmul(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2951
|
+
{
|
2952
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
2953
|
+
return __internal_device_hmul(a, b);
|
2954
|
+
,
|
2955
|
+
const float fa = __bfloat162float(a);
|
2956
|
+
const float fb = __bfloat162float(b);
|
2957
|
+
return __float2bfloat16(fa * fb);
|
2958
|
+
)
|
2959
|
+
}
|
2960
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hadd_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2961
|
+
{
|
2962
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2963
|
+
return __internal_sm80_device_hadd_rn(a, b);
|
2964
|
+
,
|
2965
|
+
return __hadd(a, b);
|
2966
|
+
)
|
2967
|
+
}
|
2968
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hsub_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2969
|
+
{
|
2970
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2971
|
+
return __internal_sm80_device_hsub_rn(a, b);
|
2972
|
+
,
|
2973
|
+
return __hsub(a, b);
|
2974
|
+
|
2975
|
+
)
|
2976
|
+
}
|
2977
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmul_rn(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2978
|
+
{
|
2979
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2980
|
+
return __internal_sm80_device_hmul_rn(a, b);
|
2981
|
+
,
|
2982
|
+
return __hmul(a, b);
|
2983
|
+
)
|
2984
|
+
}
|
2985
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hadd_sat(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
2986
|
+
{
|
2987
|
+
__nv_bfloat16 val;
|
2988
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
2989
|
+
asm( "{ .reg .b16 f, one, zero;\n"
|
2990
|
+
" mov.b16 one, 0x3f80U;\n"
|
2991
|
+
" mov.b16 zero, 0;\n"
|
2992
|
+
" fma.rn.bf16 f, %1, one, %2;\n"
|
2993
|
+
" max.bf16 f, f, zero;\n"
|
2994
|
+
" min.bf16 %0, f, one;\n}"
|
2995
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
2996
|
+
,
|
2997
|
+
val = __hmin(__hmax(__hadd(a, b), CUDART_ZERO_BF16), CUDART_ONE_BF16);
|
2998
|
+
)
|
2999
|
+
return val;
|
3000
|
+
}
|
3001
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hsub_sat(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3002
|
+
{
|
3003
|
+
__nv_bfloat16 val;
|
3004
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3005
|
+
asm( "{ .reg .b16 f, one, zero, mone;\n"
|
3006
|
+
" mov.b16 one, 0x3f80U;\n"
|
3007
|
+
" mov.b16 zero, 0;\n"
|
3008
|
+
" mov.b16 mone, 0xbf80U;\n"
|
3009
|
+
" fma.rn.bf16 f, %2, mone, %1;\n"
|
3010
|
+
" max.bf16 f, f, zero;\n"
|
3011
|
+
" min.bf16 %0, f, one;\n}"
|
3012
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3013
|
+
,
|
3014
|
+
val = __hmin(__hmax(__hsub(a, b), CUDART_ZERO_BF16), CUDART_ONE_BF16);
|
3015
|
+
)
|
3016
|
+
return val;
|
3017
|
+
}
|
3018
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmul_sat(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3019
|
+
{
|
3020
|
+
__nv_bfloat16 val;
|
3021
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3022
|
+
asm( "{ .reg .b16 f, one, zero, mzero;\n"
|
3023
|
+
" mov.b16 one, 0x3f80U;\n"
|
3024
|
+
" mov.b16 zero, 0;\n"
|
3025
|
+
" mov.b16 mzero, 0x8000U;\n"
|
3026
|
+
" fma.rn.bf16 f, %1, %2, mzero;\n"
|
3027
|
+
" max.bf16 f, f, zero;\n"
|
3028
|
+
" min.bf16 %0, f, one;\n}"
|
3029
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3030
|
+
,
|
3031
|
+
val = __hmin(__hmax(__hmul(a, b), CUDART_ZERO_BF16), CUDART_ONE_BF16);
|
3032
|
+
)
|
3033
|
+
return val;
|
3034
|
+
}
|
3035
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
3036
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __hfma(const __nv_bfloat16 a, const __nv_bfloat16 b, const __nv_bfloat16 c)
|
3037
|
+
{
|
3038
|
+
__nv_bfloat16 val;
|
3039
|
+
asm( "{fma.rn.bf16 %0,%1,%2,%3;\n}"
|
3040
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)),"h"(__BFLOAT16_TO_CUS(c)));
|
3041
|
+
return val;
|
3042
|
+
}
|
3043
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __hfma_sat(const __nv_bfloat16 a, const __nv_bfloat16 b, const __nv_bfloat16 c)
|
3044
|
+
{
|
3045
|
+
__nv_bfloat16 val;
|
3046
|
+
asm( "{ .reg .b16 f, one, zero;\n"
|
3047
|
+
" mov.b16 one, 0x3f80U;\n"
|
3048
|
+
" mov.b16 zero, 0;\n"
|
3049
|
+
" fma.rn.bf16 f, %1, %2, %3;\n"
|
3050
|
+
" max.bf16 f, f, zero;\n"
|
3051
|
+
" min.bf16 %0, f, one;\n}"
|
3052
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)),"h"(__BFLOAT16_TO_CUS(c)));
|
3053
|
+
return val;
|
3054
|
+
}
|
3055
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
3056
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
3057
|
+
#define __BINARY_OP_BFLOAT16_MACRO(name) /* do */ {\
|
3058
|
+
__nv_bfloat16 val; \
|
3059
|
+
asm( "{.reg .b32 a,b,res;\n"\
|
3060
|
+
" mov.b32 a, {0,%1};\n"\
|
3061
|
+
" mov.b32 b, {0,%2};\n"\
|
3062
|
+
" " __CUDA_BF16_STRINGIFY(name) ".f32 res, a, b;\n"\
|
3063
|
+
" cvt.rn.bf16.f32 %0, res;}\n"\
|
3064
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b))); \
|
3065
|
+
return val; \
|
3066
|
+
} /* while(0) */
|
3067
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_hdiv(const __nv_bfloat16 a, const __nv_bfloat16 b) {
|
3068
|
+
const float two_126 = __uint_as_float(0x7E800000U) ; //2^126
|
3069
|
+
const float a_f = __bfloat162float(a);
|
3070
|
+
float b_f = __bfloat162float(b);
|
3071
|
+
float ans;
|
3072
|
+
bool b_big = (fabsf(b_f) >= two_126);
|
3073
|
+
if(b_big){b_f *= 0.25f;}
|
3074
|
+
|
3075
|
+
// f32 div approximation. Good enough for c-r bfloat div.
|
3076
|
+
asm("{ div.approx.f32 %0, %1, %2; }" : "=f"(ans) : "f"(a_f), "f"(b_f));
|
3077
|
+
|
3078
|
+
// Prevent ftz:
|
3079
|
+
if(b_big){ans = __fmaf_ieee_rn(ans, 0.25f, -0.0f);}
|
3080
|
+
return __float2bfloat16(ans);
|
3081
|
+
}
|
3082
|
+
|
3083
|
+
#undef __BINARY_OP_BFLOAT16_MACRO
|
3084
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
3085
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hdiv(const __nv_bfloat16 a, const __nv_bfloat16 b) {
|
3086
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
3087
|
+
return __internal_device_hdiv(a, b);
|
3088
|
+
,
|
3089
|
+
const float fa = __bfloat162float(a);
|
3090
|
+
const float fb = __bfloat162float(b);
|
3091
|
+
return __float2bfloat16(fa / fb);
|
3092
|
+
)
|
3093
|
+
}
|
3094
|
+
|
3095
|
+
/******************************************************************************
|
3096
|
+
* __nv_bfloat162 functions *
|
3097
|
+
******************************************************************************/
|
3098
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
3099
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __hsin_internal(const __nv_bfloat16 a) {
|
3100
|
+
float f = __bfloat162float(a);
|
3101
|
+
float r = sinf(f);
|
3102
|
+
// Detect compile-time FTZ setting:
|
3103
|
+
// if subnormal constant is not flushed to zero at compile-time, then
|
3104
|
+
// ftz=off, and it is safe to return result of sinf()
|
3105
|
+
// Otherwise, ftz=on, then sinf() result is valid for non-flushed
|
3106
|
+
// values, and subnormal input is returned unchanged via else
|
3107
|
+
// branch.
|
3108
|
+
if ((__uint_as_float(0x00000001U) > 0.0f) || (f != 0.0f))
|
3109
|
+
{
|
3110
|
+
f = r;
|
3111
|
+
}
|
3112
|
+
return __float2bfloat16_rn(f);
|
3113
|
+
}
|
3114
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hsin(const __nv_bfloat16 a) {
|
3115
|
+
return __hsin_internal(a);
|
3116
|
+
}
|
3117
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2sin(const __nv_bfloat162 a) {
|
3118
|
+
const __nv_bfloat16 l = __low2bfloat16(a);
|
3119
|
+
const __nv_bfloat16 h = __high2bfloat16(a);
|
3120
|
+
return __halves2bfloat162(__hsin_internal(l), __hsin_internal(h));
|
3121
|
+
}
|
3122
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __hcos_internal(const __nv_bfloat16 a) {
|
3123
|
+
float f = __bfloat162float(a);
|
3124
|
+
f = cosf(f);
|
3125
|
+
return __float2bfloat16_rn(f);
|
3126
|
+
}
|
3127
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hcos(const __nv_bfloat16 a) {
|
3128
|
+
return __hcos_internal(a);
|
3129
|
+
}
|
3130
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2cos(const __nv_bfloat162 a) {
|
3131
|
+
const __nv_bfloat16 l = __low2bfloat16(a);
|
3132
|
+
const __nv_bfloat16 h = __high2bfloat16(a);
|
3133
|
+
return __halves2bfloat162(__hcos_internal(l), __hcos_internal(h));
|
3134
|
+
}
|
3135
|
+
|
3136
|
+
__CUDA_BF16_DECL__ float __internal_device_fast_bf16exp(const float x)
|
3137
|
+
{
|
3138
|
+
const float log2e_up = __uint_as_float(0x3FB8AA3CU);
|
3139
|
+
float fa = x * log2e_up;
|
3140
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fa));
|
3141
|
+
return fa;
|
3142
|
+
}
|
3143
|
+
|
3144
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hexp(const __nv_bfloat16 a) {
|
3145
|
+
float fa = __bfloat162float(a);
|
3146
|
+
fa = __internal_device_fast_bf16exp(fa);
|
3147
|
+
return __float2bfloat16_rn(fa);
|
3148
|
+
}
|
3149
|
+
|
3150
|
+
#define __APPROX_FCAST2(fun) /* do */ {\
|
3151
|
+
__nv_bfloat162 val;\
|
3152
|
+
asm("{.reg.b16 hl, hu; \n"\
|
3153
|
+
" .reg.b32 fl, fu; \n"\
|
3154
|
+
" mov.b32 {hl, hu}, %1; \n"\
|
3155
|
+
" mov.b32 fl, {0,hl}; \n"\
|
3156
|
+
" mov.b32 fu, {0,hu}; \n"\
|
3157
|
+
" " __CUDA_BF16_STRINGIFY(fun) ".approx.f32 fl, fl; \n"\
|
3158
|
+
" " __CUDA_BF16_STRINGIFY(fun) ".approx.f32 fu, fu; \n"\
|
3159
|
+
" cvt.rn.bf16.f32 hl, fl; \n"\
|
3160
|
+
" cvt.rn.bf16.f32 hu, fu; \n"\
|
3161
|
+
" mov.b32 %0, {hl, hu}; \n"\
|
3162
|
+
"}":"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a))); \
|
3163
|
+
return val;\
|
3164
|
+
} /* while(0) */
|
3165
|
+
#define __BF16_SPEC_CASE2(i,r, spc, ulp) \
|
3166
|
+
"{.reg.b32 spc, ulp, p;\n"\
|
3167
|
+
" mov.b32 spc," __CUDA_BF16_STRINGIFY(spc) ";\n"\
|
3168
|
+
" mov.b32 ulp," __CUDA_BF16_STRINGIFY(ulp) ";\n"\
|
3169
|
+
" set.eq.f16x2.f16x2 p," __CUDA_BF16_STRINGIFY(i) ", spc;\n"\
|
3170
|
+
" fma.rn.bf16x2 " __CUDA_BF16_STRINGIFY(r) ",p,ulp," __CUDA_BF16_STRINGIFY(r) ";\n}\n"
|
3171
|
+
|
3172
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2exp(const __nv_bfloat162 a) {
|
3173
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3174
|
+
__nv_bfloat162 val;
|
3175
|
+
asm("{.reg.b16 hl, hu; \n"
|
3176
|
+
" .reg.b32 h,r,fl,fu, C; \n"
|
3177
|
+
" mov.b32 {hl, hu}, %1; \n"
|
3178
|
+
" mov.b32 h, %1; \n"
|
3179
|
+
" mov.b32 fl, {0,hl}; \n"
|
3180
|
+
" mov.b32 fu, {0,hu}; \n"
|
3181
|
+
" mov.b32 C, 0x3FB8AA3CU; \n"
|
3182
|
+
" mul.f32 fl,fl,C; \n"
|
3183
|
+
" mul.f32 fu,fu,C; \n"
|
3184
|
+
" ex2.approx.f32 fl, fl; \n"
|
3185
|
+
" ex2.approx.f32 fu, fu; \n"
|
3186
|
+
" cvt.rn.bf16.f32 hl, fl; \n"
|
3187
|
+
" cvt.rn.bf16.f32 hu, fu; \n"
|
3188
|
+
" mov.b32 r, {hl, hu}; \n"
|
3189
|
+
" mov.b32 %0, r; \n"
|
3190
|
+
"}":"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3191
|
+
return val;
|
3192
|
+
,
|
3193
|
+
return __floats2bfloat162_rn( __internal_device_fast_bf16exp(__low2float(a)), __internal_device_fast_bf16exp(__high2float(a)) );
|
3194
|
+
)
|
3195
|
+
}
|
3196
|
+
|
3197
|
+
__CUDA_BF16_DECL__ float __internal_device_tanhf_noftz(const float x)
|
3198
|
+
{
|
3199
|
+
float f = x;
|
3200
|
+
float r = tanhf(x);
|
3201
|
+
// Detect compile-time FTZ setting:
|
3202
|
+
// if subnormal constant is not flushed to zero at compile-time, then
|
3203
|
+
// ftz=off, and it is safe to return result of tanhf()
|
3204
|
+
// Otherwise, ftz=on, then tanhf() result is valid for non-flushed
|
3205
|
+
// values, and subnormal input is returned unchanged via else
|
3206
|
+
// branch.
|
3207
|
+
if ((__uint_as_float(0x00000001U) > 0.0f) || (f != 0.0f))
|
3208
|
+
{
|
3209
|
+
f = r;
|
3210
|
+
}
|
3211
|
+
return f;
|
3212
|
+
}
|
3213
|
+
|
3214
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 htanh(const __nv_bfloat16 a) {
|
3215
|
+
float f = __bfloat162float(a);
|
3216
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_75,
|
3217
|
+
asm("{ tanh.approx.f32 %0, %0; }" : "+f"(f));
|
3218
|
+
,
|
3219
|
+
f = __internal_device_tanhf_noftz(f);
|
3220
|
+
)
|
3221
|
+
__nv_bfloat16 h = __float2bfloat16_rn(f);
|
3222
|
+
return h;
|
3223
|
+
}
|
3224
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2tanh(const __nv_bfloat162 a) {
|
3225
|
+
float2 f = __bfloat1622float2(a);
|
3226
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_75,
|
3227
|
+
asm("{ tanh.approx.f32 %0, %0; }" : "+f"(f.x));
|
3228
|
+
asm("{ tanh.approx.f32 %0, %0; }" : "+f"(f.y));
|
3229
|
+
,
|
3230
|
+
f.x = __internal_device_tanhf_noftz(f.x);
|
3231
|
+
f.y = __internal_device_tanhf_noftz(f.y);
|
3232
|
+
)
|
3233
|
+
__nv_bfloat162 h = __float22bfloat162_rn(f);
|
3234
|
+
return h;
|
3235
|
+
}
|
3236
|
+
|
3237
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 htanh_approx(const __nv_bfloat16 a) {
|
3238
|
+
__nv_bfloat16 r;
|
3239
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3240
|
+
__nv_bfloat16_raw hr = (__nv_bfloat16_raw)a;
|
3241
|
+
asm("tanh.approx.bf16 %0, %0;" : "+h"(hr.x));
|
3242
|
+
r = (__nv_bfloat16)hr;
|
3243
|
+
,
|
3244
|
+
r = htanh(a);
|
3245
|
+
)
|
3246
|
+
return r;
|
3247
|
+
}
|
3248
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2tanh_approx(const __nv_bfloat162 a) {
|
3249
|
+
__nv_bfloat162 res;
|
3250
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3251
|
+
asm("tanh.approx.bf16x2 %0, %1;" : "=r"(__BFLOAT162_TO_UI(res)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3252
|
+
,
|
3253
|
+
res = h2tanh(a);
|
3254
|
+
)
|
3255
|
+
return res;
|
3256
|
+
}
|
3257
|
+
|
3258
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hexp2(const __nv_bfloat16 a) {
|
3259
|
+
float fa = __bfloat162float(a);
|
3260
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fa));
|
3261
|
+
return __float2bfloat16_rn(fa);
|
3262
|
+
}
|
3263
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2exp2(const __nv_bfloat162 a) {
|
3264
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3265
|
+
__APPROX_FCAST2(ex2)
|
3266
|
+
,
|
3267
|
+
float fl = __low2float(a);
|
3268
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fl));
|
3269
|
+
float fh = __high2float(a);
|
3270
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fh));
|
3271
|
+
return __floats2bfloat162_rn( fl, fh );
|
3272
|
+
)
|
3273
|
+
}
|
3274
|
+
|
3275
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hexp10(const __nv_bfloat16 a) {
|
3276
|
+
const float log10_2 = __uint_as_float(0x40549A78U);
|
3277
|
+
float fa = __bfloat162float(a) * log10_2;
|
3278
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fa));
|
3279
|
+
__nv_bfloat16 r = __float2bfloat16_rn(fa);
|
3280
|
+
__nv_bfloat16_raw araw = static_cast<__nv_bfloat16_raw>(a);
|
3281
|
+
if (araw.x == (unsigned short)0xBC95U)
|
3282
|
+
{
|
3283
|
+
araw.x = 0x3f75U;
|
3284
|
+
r = static_cast<__nv_bfloat16>(araw);
|
3285
|
+
}
|
3286
|
+
return r;
|
3287
|
+
}
|
3288
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2exp10(const __nv_bfloat162 a) {
|
3289
|
+
__nv_bfloat162 r;
|
3290
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3291
|
+
asm("{.reg.b16 hl, hu; \n"
|
3292
|
+
" .reg.b32 h,r,fl,fu, C; \n"
|
3293
|
+
" mov.b32 {hl, hu}, %1; \n"
|
3294
|
+
" mov.b32 fl, {0,hl}; \n"
|
3295
|
+
" mov.b32 fu, {0,hu}; \n"
|
3296
|
+
" mov.b32 C, 0x40549A78U; \n"
|
3297
|
+
" mul.f32 fl,fl,C; \n"
|
3298
|
+
" mul.f32 fu,fu,C; \n"
|
3299
|
+
" ex2.approx.f32 fl, fl; \n"
|
3300
|
+
" ex2.approx.f32 fu, fu; \n"
|
3301
|
+
" cvt.rn.bf16.f32 hl, fl; \n"
|
3302
|
+
" cvt.rn.bf16.f32 hu, fu; \n"
|
3303
|
+
" mov.b32 r, {hl, hu}; \n"
|
3304
|
+
__BF16_SPEC_CASE2(%1, r, 0xBC95BC95U,0xBF00BF00U)
|
3305
|
+
" mov.b32 %0, r; \n"
|
3306
|
+
"}":"=r"(__BFLOAT162_TO_UI(r)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3307
|
+
,
|
3308
|
+
const float log10_2 = __uint_as_float(0x40549A78U);
|
3309
|
+
float fl = __low2float(a) * log10_2;
|
3310
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fl));
|
3311
|
+
|
3312
|
+
float fh = __high2float(a) * log10_2;
|
3313
|
+
asm("{ ex2.approx.f32 %0, %0; }" : "+f"(fh));
|
3314
|
+
|
3315
|
+
r = __floats2bfloat162_rn( fl, fh );
|
3316
|
+
|
3317
|
+
const __nv_bfloat162_raw araw = static_cast<__nv_bfloat162_raw>(a);
|
3318
|
+
if (araw.x == (unsigned short)0xBC95U)
|
3319
|
+
{
|
3320
|
+
__nv_bfloat16_raw raw_fix;
|
3321
|
+
raw_fix.x = (unsigned short)0x3f75U;
|
3322
|
+
r.x = static_cast<__nv_bfloat16>(raw_fix);
|
3323
|
+
}
|
3324
|
+
if (araw.y == (unsigned short)0xBC95U)
|
3325
|
+
{
|
3326
|
+
__nv_bfloat16_raw raw_fix;
|
3327
|
+
raw_fix.x = (unsigned short)0x3f75U;
|
3328
|
+
r.y = static_cast<__nv_bfloat16>(raw_fix);
|
3329
|
+
}
|
3330
|
+
)
|
3331
|
+
return r;
|
3332
|
+
}
|
3333
|
+
|
3334
|
+
__CUDA_BF16_DECL__ float __internal_device_fast_bf16log2(float x)
|
3335
|
+
{
|
3336
|
+
asm("{ lg2.approx.f32 %0, %0; }" : "+f"(x));
|
3337
|
+
return x;
|
3338
|
+
}
|
3339
|
+
|
3340
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hlog2(const __nv_bfloat16 a) {
|
3341
|
+
float fa = __bfloat162float(a);
|
3342
|
+
fa = __internal_device_fast_bf16log2(fa);
|
3343
|
+
return __float2bfloat16_rn(fa);
|
3344
|
+
}
|
3345
|
+
|
3346
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2log2(const __nv_bfloat162 a) {
|
3347
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3348
|
+
__APPROX_FCAST2(lg2)
|
3349
|
+
,
|
3350
|
+
float fl = __low2float(a);
|
3351
|
+
fl = __internal_device_fast_bf16log2(fl);
|
3352
|
+
float fh = __high2float(a);
|
3353
|
+
fh = __internal_device_fast_bf16log2(fh);
|
3354
|
+
return __floats2bfloat162_rn( fl, fh );
|
3355
|
+
)
|
3356
|
+
}
|
3357
|
+
|
3358
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hlog(const __nv_bfloat16 a) {
|
3359
|
+
const float flt_ln2 = __uint_as_float(0x3f317218U);
|
3360
|
+
float fa = __bfloat162float(a);
|
3361
|
+
fa = __internal_device_fast_bf16log2(fa);
|
3362
|
+
fa = fa * flt_ln2;
|
3363
|
+
return __float2bfloat16_rn(fa);
|
3364
|
+
}
|
3365
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2log(const __nv_bfloat162 a) {
|
3366
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3367
|
+
__nv_bfloat162 val;
|
3368
|
+
asm("{.reg.b16 hl, hu; \n"
|
3369
|
+
" .reg.b32 r, fl, fu, C, h; \n"
|
3370
|
+
" mov.b32 {hl, hu}, %1; \n"
|
3371
|
+
" mov.b32 h, %1; \n"
|
3372
|
+
" mov.b32 fl, {0,hl}; \n"
|
3373
|
+
" mov.b32 fu, {0,hu}; \n"
|
3374
|
+
" lg2.approx.f32 fl, fl; \n"
|
3375
|
+
" lg2.approx.f32 fu, fu; \n"
|
3376
|
+
" mov.b32 C, 0x3f317218U; \n"
|
3377
|
+
" mul.f32 fl,fl,C; \n"
|
3378
|
+
" mul.f32 fu,fu,C; \n"
|
3379
|
+
" cvt.rn.bf16.f32 hl, fl; \n"
|
3380
|
+
" cvt.rn.bf16.f32 hu, fu; \n"
|
3381
|
+
" mov.b32 r, {hl, hu}; \n"
|
3382
|
+
" mov.b32 %0, r; \n"
|
3383
|
+
"}":"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3384
|
+
return val;
|
3385
|
+
,
|
3386
|
+
const float flt_ln2 = __uint_as_float(0x3f317218U);
|
3387
|
+
|
3388
|
+
float fl = __low2float(a);
|
3389
|
+
fl = __internal_device_fast_bf16log2(fl);
|
3390
|
+
fl = fl * flt_ln2;
|
3391
|
+
|
3392
|
+
float fh = __high2float(a);
|
3393
|
+
fh = __internal_device_fast_bf16log2(fh);
|
3394
|
+
fh = fh * flt_ln2;
|
3395
|
+
|
3396
|
+
return __floats2bfloat162_rn( fl, fh );
|
3397
|
+
)
|
3398
|
+
}
|
3399
|
+
|
3400
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hlog10(const __nv_bfloat16 a) {
|
3401
|
+
const float flt_log10_2 = __uint_as_float(0x3E9A209BU);
|
3402
|
+
float fa = __bfloat162float(a);
|
3403
|
+
fa = __internal_device_fast_bf16log2(fa);
|
3404
|
+
fa = fa * flt_log10_2;
|
3405
|
+
return __float2bfloat16_rn(fa);
|
3406
|
+
}
|
3407
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2log10(const __nv_bfloat162 a) {
|
3408
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3409
|
+
__nv_bfloat162 val;
|
3410
|
+
asm("{.reg.b16 hl, hu; \n"
|
3411
|
+
" .reg.b32 r, fl, fu, C, h; \n"
|
3412
|
+
" mov.b32 {hl, hu}, %1; \n"
|
3413
|
+
" mov.b32 h, %1; \n"
|
3414
|
+
" mov.b32 fl, {0,hl}; \n"
|
3415
|
+
" mov.b32 fu, {0,hu}; \n"
|
3416
|
+
" lg2.approx.f32 fl, fl; \n"
|
3417
|
+
" lg2.approx.f32 fu, fu; \n"
|
3418
|
+
" mov.b32 C, 0x3E9A209BU; \n"
|
3419
|
+
" mul.f32 fl,fl,C; \n"
|
3420
|
+
" mul.f32 fu,fu,C; \n"
|
3421
|
+
" cvt.rn.bf16.f32 hl, fl; \n"
|
3422
|
+
" cvt.rn.bf16.f32 hu, fu; \n"
|
3423
|
+
" mov.b32 r, {hl, hu}; \n"
|
3424
|
+
" mov.b32 %0, r; \n"
|
3425
|
+
"}":"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3426
|
+
return val;
|
3427
|
+
,
|
3428
|
+
const float flt_log10_2 = __uint_as_float(0x3E9A209BU);
|
3429
|
+
|
3430
|
+
float fl = __low2float(a);
|
3431
|
+
fl = __internal_device_fast_bf16log2(fl);
|
3432
|
+
fl = fl * flt_log10_2;
|
3433
|
+
|
3434
|
+
float fh = __high2float(a);
|
3435
|
+
fh = __internal_device_fast_bf16log2(fh);
|
3436
|
+
fh = fh * flt_log10_2;
|
3437
|
+
|
3438
|
+
return __floats2bfloat162_rn( fl, fh );
|
3439
|
+
)
|
3440
|
+
}
|
3441
|
+
|
3442
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2rcp(const __nv_bfloat162 a) {
|
3443
|
+
float fl = __low2float(a);
|
3444
|
+
asm("{ rcp.approx.f32 %0, %0; }" : "+f"(fl));
|
3445
|
+
float fh = __high2float(a);
|
3446
|
+
asm("{ rcp.approx.f32 %0, %0; }" : "+f"(fh));
|
3447
|
+
return __floats2bfloat162_rn( fl, fh );
|
3448
|
+
}
|
3449
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hrcp(const __nv_bfloat16 a) {
|
3450
|
+
float fa = __bfloat162float(a);
|
3451
|
+
asm("{ rcp.approx.f32 %0, %0; }" : "+f"(fa));
|
3452
|
+
return __float2bfloat16_rn(fa);
|
3453
|
+
}
|
3454
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2rsqrt(const __nv_bfloat162 a) {
|
3455
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3456
|
+
__APPROX_FCAST2(rsqrt)
|
3457
|
+
,
|
3458
|
+
float fl = __low2float(a);
|
3459
|
+
asm("{ rsqrt.approx.f32 %0, %0; }" : "+f"(fl));
|
3460
|
+
float fh = __high2float(a);
|
3461
|
+
asm("{ rsqrt.approx.f32 %0, %0; }" : "+f"(fh));
|
3462
|
+
return __floats2bfloat162_rn( fl, fh );
|
3463
|
+
)
|
3464
|
+
}
|
3465
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hrsqrt(const __nv_bfloat16 a) {
|
3466
|
+
float fa = __bfloat162float(a);
|
3467
|
+
asm("{ rsqrt.approx.f32 %0, %0; }" : "+f"(fa));
|
3468
|
+
return __float2bfloat16_rn(fa);
|
3469
|
+
}
|
3470
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 h2sqrt(const __nv_bfloat162 a) {
|
3471
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3472
|
+
__APPROX_FCAST2(sqrt)
|
3473
|
+
,
|
3474
|
+
float fl = __low2float(a);
|
3475
|
+
asm("{ sqrt.approx.f32 %0, %0; }" : "+f"(fl));
|
3476
|
+
float fh = __high2float(a);
|
3477
|
+
asm("{ sqrt.approx.f32 %0, %0; }" : "+f"(fh));
|
3478
|
+
return __floats2bfloat162_rn( fl, fh );
|
3479
|
+
)
|
3480
|
+
}
|
3481
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 hsqrt(const __nv_bfloat16 a) {
|
3482
|
+
float fa = __bfloat162float(a);
|
3483
|
+
asm("{ sqrt.approx.f32 %0, %0; }" : "+f"(fa));
|
3484
|
+
return __float2bfloat16_rn(fa);
|
3485
|
+
}
|
3486
|
+
#undef __APPROX_FCAST2
|
3487
|
+
#undef __BF16_SPEC_CASE2
|
3488
|
+
|
3489
|
+
__CUDA_BF16_DECL__ bool __internal_device_hisnan(const __nv_bfloat16 a)
|
3490
|
+
{
|
3491
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3492
|
+
__nv_bfloat16 r;
|
3493
|
+
asm("{set.nan.bf16.bf16 %0,%1,%1;\n}"
|
3494
|
+
:"=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(a)));
|
3495
|
+
return __BFLOAT16_TO_CUS(r) != 0U;
|
3496
|
+
,
|
3497
|
+
unsigned int r;
|
3498
|
+
asm( "{.reg .b32 a;\n"
|
3499
|
+
" mov.b32 a, {0,%1};\n"
|
3500
|
+
" set.nan.f32.f32 %0, a, a;}\n"
|
3501
|
+
:"=r"(r) : "h"(__BFLOAT16_TO_CUS(a)));
|
3502
|
+
return r != 0U;
|
3503
|
+
)
|
3504
|
+
}
|
3505
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
3506
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hisnan2(const __nv_bfloat162 a)
|
3507
|
+
{
|
3508
|
+
__nv_bfloat162 r;
|
3509
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3510
|
+
asm("{set.nan.bf16x2.bf16x2 %0,%1,%1;\n}"
|
3511
|
+
:"=r"(__BFLOAT162_TO_UI(r)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3512
|
+
,
|
3513
|
+
__nv_bfloat162_raw val;
|
3514
|
+
val.x = __hisnan(a.x) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
3515
|
+
val.y = __hisnan(a.y) ? (unsigned short)0x3F80U : (unsigned short)0U;
|
3516
|
+
r = __nv_bfloat162(val);
|
3517
|
+
)
|
3518
|
+
return r;
|
3519
|
+
}
|
3520
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ bool __hisnan(const __nv_bfloat16 a)
|
3521
|
+
{
|
3522
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
3523
|
+
return __internal_device_hisnan(a);
|
3524
|
+
,
|
3525
|
+
const __nv_bfloat16_raw hr = static_cast<__nv_bfloat16_raw>(a);
|
3526
|
+
return ((hr.x & 0x7FFFU) > 0x7F80U);
|
3527
|
+
)
|
3528
|
+
}
|
3529
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hneg2(const __nv_bfloat162 a)
|
3530
|
+
{
|
3531
|
+
__nv_bfloat162 r;
|
3532
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3533
|
+
asm("{neg.bf16x2 %0,%1;\n}"
|
3534
|
+
:"=r"(__BFLOAT162_TO_UI(r)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3535
|
+
,
|
3536
|
+
r.x = __hneg(a.x);
|
3537
|
+
r.y = __hneg(a.y);
|
3538
|
+
)
|
3539
|
+
return r;
|
3540
|
+
}
|
3541
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
3542
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __internal_device_hneg(const __nv_bfloat16 a)
|
3543
|
+
{
|
3544
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3545
|
+
__nv_bfloat16 r;
|
3546
|
+
asm("{neg.bf16 %0,%1;\n}"
|
3547
|
+
:"=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(a)));
|
3548
|
+
return r;
|
3549
|
+
,
|
3550
|
+
const float fa = __bfloat162float(a);
|
3551
|
+
return __float2bfloat16(__fmaf_ieee_rn(fa, -1.0f, -0.0f));
|
3552
|
+
)
|
3553
|
+
}
|
3554
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
3555
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hneg(const __nv_bfloat16 a)
|
3556
|
+
{
|
3557
|
+
NV_IF_ELSE_TARGET(NV_IS_DEVICE,
|
3558
|
+
return __internal_device_hneg(a);
|
3559
|
+
,
|
3560
|
+
const float fa = __bfloat162float(a);
|
3561
|
+
return __float2bfloat16(-fa);
|
3562
|
+
)
|
3563
|
+
}
|
3564
|
+
|
3565
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __habs2(const __nv_bfloat162 a)
|
3566
|
+
{
|
3567
|
+
__nv_bfloat162 r;
|
3568
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3569
|
+
asm("{abs.bf16x2 %0,%1;\n}"
|
3570
|
+
:"=r"(__BFLOAT162_TO_UI(r)) : "r"(__BFLOAT162_TO_CUI(a)));
|
3571
|
+
,
|
3572
|
+
r.x = __habs(a.x);
|
3573
|
+
r.y = __habs(a.y);
|
3574
|
+
)
|
3575
|
+
return r;
|
3576
|
+
}
|
3577
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __habs(const __nv_bfloat16 a)
|
3578
|
+
{
|
3579
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3580
|
+
__nv_bfloat16 r;
|
3581
|
+
asm("{abs.bf16 %0,%1;\n}"
|
3582
|
+
:"=h"(__BFLOAT16_TO_US(r)) : "h"(__BFLOAT16_TO_CUS(a)));
|
3583
|
+
return r;
|
3584
|
+
,
|
3585
|
+
__nv_bfloat16_raw abs_a_raw = static_cast<__nv_bfloat16_raw>(a);
|
3586
|
+
abs_a_raw.x &= (unsigned short)0x7FFFU;
|
3587
|
+
if (abs_a_raw.x > (unsigned short)0x7F80U)
|
3588
|
+
{
|
3589
|
+
// return canonical NaN
|
3590
|
+
abs_a_raw.x = (unsigned short)0x7FFFU;
|
3591
|
+
}
|
3592
|
+
return static_cast<__nv_bfloat16>(abs_a_raw);
|
3593
|
+
)
|
3594
|
+
}
|
3595
|
+
|
3596
|
+
/******************************************************************************
|
3597
|
+
* __nv_bfloat16 arithmetic *
|
3598
|
+
******************************************************************************/
|
3599
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmax(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3600
|
+
{
|
3601
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3602
|
+
__nv_bfloat16 val;
|
3603
|
+
asm( "{ max.bf16 %0,%1,%2;\n}"
|
3604
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3605
|
+
return val;
|
3606
|
+
,
|
3607
|
+
__nv_bfloat16 maxval;
|
3608
|
+
|
3609
|
+
maxval = (__hge(a, b) || __hisnan(b)) ? a : b;
|
3610
|
+
|
3611
|
+
if (__hisnan(maxval))
|
3612
|
+
{
|
3613
|
+
// if both inputs are NaN, return canonical NaN
|
3614
|
+
maxval = CUDART_NAN_BF16;
|
3615
|
+
}
|
3616
|
+
else if (__heq(a, b))
|
3617
|
+
{
|
3618
|
+
// hmax(+0.0, -0.0) = +0.0
|
3619
|
+
// unsigned compare 0x8000U > 0x0000U
|
3620
|
+
__nv_bfloat16_raw ra = __nv_bfloat16_raw(a);
|
3621
|
+
__nv_bfloat16_raw rb = __nv_bfloat16_raw(b);
|
3622
|
+
maxval = (ra.x > rb.x) ? b : a;
|
3623
|
+
}
|
3624
|
+
|
3625
|
+
return maxval;
|
3626
|
+
)
|
3627
|
+
}
|
3628
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmin(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3629
|
+
{
|
3630
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3631
|
+
__nv_bfloat16 val;
|
3632
|
+
asm( "{ min.bf16 %0,%1,%2;\n}"
|
3633
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3634
|
+
return val;
|
3635
|
+
,
|
3636
|
+
__nv_bfloat16 minval;
|
3637
|
+
|
3638
|
+
minval = (__hle(a, b) || __hisnan(b)) ? a : b;
|
3639
|
+
|
3640
|
+
if (__hisnan(minval))
|
3641
|
+
{
|
3642
|
+
// if both inputs are NaN, return canonical NaN
|
3643
|
+
minval = CUDART_NAN_BF16;
|
3644
|
+
}
|
3645
|
+
else if (__heq(a, b))
|
3646
|
+
{
|
3647
|
+
// hmin(+0.0, -0.0) = -0.0
|
3648
|
+
// unsigned compare 0x8000U > 0x0000U
|
3649
|
+
__nv_bfloat16_raw ra = __nv_bfloat16_raw(a);
|
3650
|
+
__nv_bfloat16_raw rb = __nv_bfloat16_raw(b);
|
3651
|
+
minval = (ra.x > rb.x) ? a : b;
|
3652
|
+
}
|
3653
|
+
|
3654
|
+
return minval;
|
3655
|
+
)
|
3656
|
+
}
|
3657
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmax_nan(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3658
|
+
{
|
3659
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3660
|
+
__nv_bfloat16 val;
|
3661
|
+
asm( "{ max.NaN.bf16 %0,%1,%2;\n}"
|
3662
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3663
|
+
return val;
|
3664
|
+
,
|
3665
|
+
__nv_bfloat16 maxval;
|
3666
|
+
|
3667
|
+
if (__hisnan(a) || __hisnan(b))
|
3668
|
+
{
|
3669
|
+
// if either input is NaN, return canonical NaN
|
3670
|
+
maxval = CUDART_NAN_BF16;
|
3671
|
+
}
|
3672
|
+
else
|
3673
|
+
{
|
3674
|
+
maxval = __hge(a, b) ? a : b;
|
3675
|
+
}
|
3676
|
+
|
3677
|
+
return maxval;
|
3678
|
+
)
|
3679
|
+
}
|
3680
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat16 __hmin_nan(const __nv_bfloat16 a, const __nv_bfloat16 b)
|
3681
|
+
{
|
3682
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3683
|
+
__nv_bfloat16 val;
|
3684
|
+
asm( "{ min.NaN.bf16 %0,%1,%2;\n}"
|
3685
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)));
|
3686
|
+
return val;
|
3687
|
+
,
|
3688
|
+
__nv_bfloat16 minval;
|
3689
|
+
|
3690
|
+
if (__hisnan(a) || __hisnan(b))
|
3691
|
+
{
|
3692
|
+
// if either input is NaN, return canonical NaN
|
3693
|
+
minval = CUDART_NAN_BF16;
|
3694
|
+
}
|
3695
|
+
else
|
3696
|
+
{
|
3697
|
+
minval = __hle(a, b) ? a : b;
|
3698
|
+
}
|
3699
|
+
|
3700
|
+
return minval;
|
3701
|
+
)
|
3702
|
+
}
|
3703
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
3704
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 __hfma_relu(const __nv_bfloat16 a, const __nv_bfloat16 b, const __nv_bfloat16 c)
|
3705
|
+
{
|
3706
|
+
__nv_bfloat16 val;
|
3707
|
+
asm( "{ fma.rn.relu.bf16 %0,%1,%2,%3;\n}"
|
3708
|
+
:"=h"(__BFLOAT16_TO_US(val)) : "h"(__BFLOAT16_TO_CUS(a)),"h"(__BFLOAT16_TO_CUS(b)),"h"(__BFLOAT16_TO_CUS(c)));
|
3709
|
+
return val;
|
3710
|
+
}
|
3711
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
3712
|
+
/******************************************************************************
|
3713
|
+
* __nv_bfloat162 arithmetic *
|
3714
|
+
******************************************************************************/
|
3715
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmax2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
3716
|
+
{
|
3717
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3718
|
+
__nv_bfloat162 val;
|
3719
|
+
asm( "{ max.bf16x2 %0,%1,%2;\n}"
|
3720
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
3721
|
+
return val;
|
3722
|
+
,
|
3723
|
+
__nv_bfloat162 val;
|
3724
|
+
val.x = __hmax(a.x, b.x);
|
3725
|
+
val.y = __hmax(a.y, b.y);
|
3726
|
+
return val;
|
3727
|
+
)
|
3728
|
+
}
|
3729
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmin2(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
3730
|
+
{
|
3731
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3732
|
+
__nv_bfloat162 val;
|
3733
|
+
asm( "{ min.bf16x2 %0,%1,%2;\n}"
|
3734
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
3735
|
+
return val;
|
3736
|
+
,
|
3737
|
+
__nv_bfloat162 val;
|
3738
|
+
val.x = __hmin(a.x, b.x);
|
3739
|
+
val.y = __hmin(a.y, b.y);
|
3740
|
+
return val;
|
3741
|
+
)
|
3742
|
+
}
|
3743
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmax2_nan(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
3744
|
+
{
|
3745
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3746
|
+
__nv_bfloat162 val;
|
3747
|
+
asm( "{ max.NaN.bf16x2 %0,%1,%2;\n}"
|
3748
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
3749
|
+
return val;
|
3750
|
+
,
|
3751
|
+
__nv_bfloat162 val;
|
3752
|
+
val.x = __hmax_nan(a.x, b.x);
|
3753
|
+
val.y = __hmax_nan(a.y, b.y);
|
3754
|
+
return val;
|
3755
|
+
)
|
3756
|
+
}
|
3757
|
+
__CUDA_HOSTDEVICE_BF16_DECL__ __nv_bfloat162 __hmin2_nan(const __nv_bfloat162 a, const __nv_bfloat162 b)
|
3758
|
+
{
|
3759
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_80,
|
3760
|
+
__nv_bfloat162 val;
|
3761
|
+
asm( "{ min.NaN.bf16x2 %0,%1,%2;\n}"
|
3762
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)));
|
3763
|
+
return val;
|
3764
|
+
,
|
3765
|
+
__nv_bfloat162 val;
|
3766
|
+
val.x = __hmin_nan(a.x, b.x);
|
3767
|
+
val.y = __hmin_nan(a.y, b.y);
|
3768
|
+
return val;
|
3769
|
+
)
|
3770
|
+
}
|
3771
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA)
|
3772
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __hfma2_relu(const __nv_bfloat162 a, const __nv_bfloat162 b, const __nv_bfloat162 c)
|
3773
|
+
{
|
3774
|
+
__nv_bfloat162 val;
|
3775
|
+
asm( "{ fma.rn.relu.bf16x2 %0,%1,%2,%3;\n}"
|
3776
|
+
:"=r"(__BFLOAT162_TO_UI(val)) : "r"(__BFLOAT162_TO_CUI(a)),"r"(__BFLOAT162_TO_CUI(b)),"r"(__BFLOAT162_TO_CUI(c)));
|
3777
|
+
return val;
|
3778
|
+
}
|
3779
|
+
|
3780
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 __hcmadd(const __nv_bfloat162 a, const __nv_bfloat162 b, const __nv_bfloat162 c)
|
3781
|
+
{
|
3782
|
+
// fast version of complex multiply-accumulate
|
3783
|
+
// (a.re, a.im) * (b.re, b.im) + (c.re, c.im)
|
3784
|
+
// acc.re = (c.re + a.re*b.re) - a.im*b.im
|
3785
|
+
// acc.im = (c.im + a.re*b.im) + a.im*b.re
|
3786
|
+
__nv_bfloat16 real_tmp = __hfma(a.x, b.x, c.x);
|
3787
|
+
__nv_bfloat16 img_tmp = __hfma(a.x, b.y, c.y);
|
3788
|
+
real_tmp = __hfma(__hneg(a.y), b.y, real_tmp);
|
3789
|
+
img_tmp = __hfma(a.y, b.x, img_tmp);
|
3790
|
+
return make_bfloat162(real_tmp, img_tmp);
|
3791
|
+
}
|
3792
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 800))) || defined(_NVHPC_CUDA) */
|
3793
|
+
|
3794
|
+
#if defined(__CUDACC__) || defined(_NVHPC_CUDA)
|
3795
|
+
/* Define __PTR for atomicAdd prototypes below, undef after done */
|
3796
|
+
#if (defined(_MSC_VER) && defined(_WIN64)) || defined(__LP64__) || defined(__CUDACC_RTC__)
|
3797
|
+
#define __PTR "l"
|
3798
|
+
#else
|
3799
|
+
#define __PTR "r"
|
3800
|
+
#endif /*(defined(_MSC_VER) && defined(_WIN64)) || defined(__LP64__) || defined(__CUDACC_RTC__)*/
|
3801
|
+
|
3802
|
+
__CUDA_BF16_DECL__ __nv_bfloat162 atomicAdd(__nv_bfloat162 *const address, const __nv_bfloat162 val)
|
3803
|
+
{
|
3804
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3805
|
+
__nv_bfloat162 r;
|
3806
|
+
asm volatile ("{ atom.add.noftz.bf16x2 %0,[%1],%2; }\n"
|
3807
|
+
: "=r"(__BFLOAT162_TO_UI(r)) : __PTR(address), "r"(__BFLOAT162_TO_CUI(val))
|
3808
|
+
: "memory");
|
3809
|
+
return r;
|
3810
|
+
,
|
3811
|
+
unsigned int* address_as_uint = (unsigned int*)address;
|
3812
|
+
unsigned int old = *address_as_uint;
|
3813
|
+
unsigned int assumed;
|
3814
|
+
do {
|
3815
|
+
assumed = old;
|
3816
|
+
__nv_bfloat162 new_val = __hadd2(val, *(__nv_bfloat162*)&assumed);
|
3817
|
+
old = atomicCAS(address_as_uint, assumed, *(unsigned int*)&new_val);
|
3818
|
+
} while (assumed != old);
|
3819
|
+
return *(__nv_bfloat162*)&old;
|
3820
|
+
)
|
3821
|
+
}
|
3822
|
+
|
3823
|
+
#if (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 700))) || defined(_NVHPC_CUDA)
|
3824
|
+
__CUDA_BF16_DECL__ __nv_bfloat16 atomicAdd(__nv_bfloat16 *const address, const __nv_bfloat16 val)
|
3825
|
+
{
|
3826
|
+
NV_IF_ELSE_TARGET(NV_PROVIDES_SM_90,
|
3827
|
+
__nv_bfloat16 r;
|
3828
|
+
asm volatile ("{ atom.add.noftz.bf16 %0,[%1],%2; }\n"
|
3829
|
+
: "=h"(__BFLOAT16_TO_US(r))
|
3830
|
+
: __PTR(address), "h"(__BFLOAT16_TO_CUS(val))
|
3831
|
+
: "memory");
|
3832
|
+
return r;
|
3833
|
+
,
|
3834
|
+
unsigned short int* address_as_us = (unsigned short int*)address;
|
3835
|
+
unsigned short int old = *address_as_us;
|
3836
|
+
unsigned short int assumed;
|
3837
|
+
do {
|
3838
|
+
assumed = old;
|
3839
|
+
old = atomicCAS(address_as_us, assumed,
|
3840
|
+
__bfloat16_as_ushort(__hadd(val, __ushort_as_bfloat16(assumed))));
|
3841
|
+
} while (assumed != old);
|
3842
|
+
return __ushort_as_bfloat16(old);
|
3843
|
+
)
|
3844
|
+
}
|
3845
|
+
#endif /* (defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || (__CUDA_ARCH__ >= 700))) || defined(_NVHPC_CUDA) */
|
3846
|
+
|
3847
|
+
#undef __PTR
|
3848
|
+
#endif /* defined(__CUDACC__) || defined(_NVHPC_CUDA) */
|
3849
|
+
|
3850
|
+
#endif /* !(defined __DOXYGEN_ONLY__) */
|
3851
|
+
|
3852
|
+
#endif /* defined(__cplusplus) */
|
3853
|
+
|
3854
|
+
#undef __CUDA_HOSTDEVICE_BF16_DECL__
|
3855
|
+
#undef __CUDA_BF16_DECL__
|
3856
|
+
#undef __CUDA_BF16_CONSTEXPR__
|
3857
|
+
|
3858
|
+
#if defined(__CPP_VERSION_AT_LEAST_11_BF16)
|
3859
|
+
#undef __CPP_VERSION_AT_LEAST_11_BF16
|
3860
|
+
#endif /* defined(__CPP_VERSION_AT_LEAST_11_BF16) */
|
3861
|
+
|
3862
|
+
#undef ___CUDA_BF16_STRINGIFY_INNERMOST
|
3863
|
+
#undef __CUDA_BF16_STRINGIFY
|
3864
|
+
|
3865
|
+
#endif /* end of include guard: __CUDA_BF16_HPP__ */
|