clang 23.0.0git
__clang_gpu_device_functions.h
Go to the documentation of this file.
1//===---- __clang_gpu_device_functions.h - GPU device functions ------------===
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===-----------------------------------------------------------------------===
8
9#ifndef __CLANG_GPU_DEVICE_FUNCTIONS_H__
10#define __CLANG_GPU_DEVICE_FUNCTIONS_H__
11
12#if defined(__HIP__) || defined(__CUDA__)
13
14#ifndef __device__
15#define __host__ __attribute__((host))
16#define __device__ __attribute__((device))
17#define __global__ __attribute__((global))
18#define __shared__ __attribute__((shared))
19#define __constant__ __attribute__((constant))
20#define __managed__ __attribute__((managed))
21#endif
22
23#include <gpuintrin.h>
24
25#pragma push_macro("__GPU_DEVICE__")
26#define __GPU_DEVICE__ static __inline__ __attribute__((device, always_inline))
27
28#pragma push_macro("MAYBE_UNDEF")
29#define MAYBE_UNDEF __attribute__((maybe_undef))
30
31// warpSize and the threadIdx/blockIdx/blockDim/gridDim coordinate variables.
33
34//===----------------------------------------------------------------------===//
35// Integer intrinsics.
36//===----------------------------------------------------------------------===//
37
38__GPU_DEVICE__ unsigned int __popc(unsigned int __x) {
39 return __builtin_popcountg(__x);
40}
41__GPU_DEVICE__ unsigned int __popcll(unsigned long long __x) {
42 return __builtin_popcountg(__x);
43}
44
45__GPU_DEVICE__ int __clz(int __x) {
46 return __builtin_clzg((unsigned int)__x, 32);
47}
48__GPU_DEVICE__ int __clzll(long long __x) {
49 return __builtin_clzg((unsigned long long)__x, 64);
50}
51
52__GPU_DEVICE__ int __ffs(int __x) {
53 return __builtin_ctzg((unsigned int)__x, -1) + 1;
54}
55__GPU_DEVICE__ int __ffs(unsigned int __x) {
56 return __builtin_ctzg(__x, -1) + 1;
57}
58__GPU_DEVICE__ int __ffsll(long long __x) {
59 return __builtin_ctzg((unsigned long long)__x, -1) + 1;
60}
61__GPU_DEVICE__ int __ffsll(unsigned long long __x) {
62 return __builtin_ctzg(__x, -1) + 1;
63}
64
65__GPU_DEVICE__ unsigned int __brev(unsigned int __x) {
66 return __builtin_elementwise_bitreverse(__x);
67}
68__GPU_DEVICE__ unsigned long long __brevll(unsigned long long __x) {
69 return __builtin_elementwise_bitreverse(__x);
70}
71
72__GPU_DEVICE__ int __mul24(int __x, int __y) {
73 return ((int(unsigned(__x) << 8) >> 8)) * ((int(unsigned(__y) << 8) >> 8));
74}
75__GPU_DEVICE__ int __umul24(unsigned int __x, unsigned int __y) {
76 return int((__x & 0x00ffffffu) * (__y & 0x00ffffffu));
77}
78
79__GPU_DEVICE__ int __mulhi(int __x, int __y) {
80 return int(((long long)__x * (long long)__y) >> 32);
81}
82__GPU_DEVICE__ unsigned int __umulhi(unsigned int __x, unsigned int __y) {
83 return (unsigned int)(((unsigned long long)__x * (unsigned long long)__y) >>
84 32);
85}
86__GPU_DEVICE__ long long __mul64hi(long long __x, long long __y) {
87 return (long long)(((__int128)__x * (__int128)__y) >> 64);
88}
89__GPU_DEVICE__ unsigned long long __umul64hi(unsigned long long __x,
90 unsigned long long __y) {
91 return (
92 unsigned long long)(((unsigned __int128)__x * (unsigned __int128)__y) >>
93 64);
94}
95
96__GPU_DEVICE__ unsigned int __sad(int __x, int __y, unsigned int __z) {
97 return __x > __y ? __x - __y + __z : __y - __x + __z;
98}
99__GPU_DEVICE__ unsigned int __usad(unsigned int __x, unsigned int __y,
100 unsigned int __z) {
101 return __x > __y ? __x - __y + __z : __y - __x + __z;
102}
103
104__GPU_DEVICE__ int __hadd(int __x, int __y) {
105 return int(((long long)__x + (long long)__y) >> 1);
106}
107__GPU_DEVICE__ int __rhadd(int __x, int __y) {
108 return int(((long long)__x + (long long)__y + 1) >> 1);
109}
110__GPU_DEVICE__ unsigned int __uhadd(unsigned int __x, unsigned int __y) {
111 return (unsigned int)(((unsigned long long)__x + (unsigned long long)__y) >>
112 1);
113}
114__GPU_DEVICE__ unsigned int __urhadd(unsigned int __x, unsigned int __y) {
115 return (
116 unsigned int)(((unsigned long long)__x + (unsigned long long)__y + 1) >>
117 1);
118}
119
120__GPU_DEVICE__ unsigned int __byte_perm(unsigned int __x, unsigned int __y,
121 unsigned int __s) {
122 unsigned long long __tmp = ((unsigned long long)__y << 32) | __x;
123 unsigned int __result = 0;
124 for (int __i = 0; __i < 4; ++__i) {
125 unsigned int __sel = (__s >> (__i * 4)) & 0x7u;
126 __result |= (unsigned int)((__tmp >> (__sel * 8)) & 0xffu) << (__i * 8);
127 }
128 return __result;
129}
130
131//===----------------------------------------------------------------------===//
132// Bitfield operations.
133//===----------------------------------------------------------------------===//
134
135__GPU_DEVICE__ unsigned int __lastbit_u32_u64(unsigned long long __x) {
136 return (unsigned int)__builtin_ctzg(__x, -1);
137}
138
139__GPU_DEVICE__ unsigned int __bitextract_u32(unsigned int __src,
140 unsigned int __offset,
141 unsigned int __width) {
142 unsigned int __o = __offset & 31u;
143 unsigned int __w = __width & 31u;
144 return __w == 0 ? 0u : (__src << (32u - __o - __w)) >> (32u - __w);
145}
146__GPU_DEVICE__ unsigned long long __bitextract_u64(unsigned long long __src,
147 unsigned int __offset,
148 unsigned int __width) {
149 unsigned long long __o = __offset & 63u;
150 unsigned long long __w = __width & 63u;
151 return __w == 0 ? 0ull : (__src << (64ull - __o - __w)) >> (64ull - __w);
152}
153
154__GPU_DEVICE__ unsigned int __bitinsert_u32(unsigned int __dst,
155 unsigned int __src,
156 unsigned int __offset,
157 unsigned int __width) {
158 unsigned int __o = __offset & 31u;
159 unsigned int __mask = (1u << (__width & 31u)) - 1u;
160 return (__dst & ~(__mask << __o)) | ((__src & __mask) << __o);
161}
162__GPU_DEVICE__ unsigned long long __bitinsert_u64(unsigned long long __dst,
163 unsigned long long __src,
164 unsigned int __offset,
165 unsigned int __width) {
166 unsigned long long __o = __offset & 63u;
167 unsigned long long __mask = (1ull << (__width & 63u)) - 1ull;
168 return (__dst & ~(__mask << __o)) | ((__src & __mask) << __o);
169}
170
171//===----------------------------------------------------------------------===//
172// Type punning.
173//===----------------------------------------------------------------------===//
174
175__GPU_DEVICE__ int __float_as_int(float __x) {
176 return __builtin_bit_cast(int, __x);
177}
178__GPU_DEVICE__ unsigned int __float_as_uint(float __x) {
179 return __builtin_bit_cast(unsigned int, __x);
180}
181__GPU_DEVICE__ float __int_as_float(int __x) {
182 return __builtin_bit_cast(float, __x);
183}
184__GPU_DEVICE__ float __uint_as_float(unsigned int __x) {
185 return __builtin_bit_cast(float, __x);
186}
187__GPU_DEVICE__ long long __double_as_longlong(double __x) {
188 return __builtin_bit_cast(long long, __x);
189}
190__GPU_DEVICE__ double __longlong_as_double(long long __x) {
191 return __builtin_bit_cast(double, __x);
192}
193__GPU_DEVICE__ int __double2hiint(double __x) {
194 return int(__builtin_bit_cast(unsigned long long, __x) >> 32);
195}
196__GPU_DEVICE__ int __double2loint(double __x) {
197 return int(__builtin_bit_cast(unsigned long long, __x));
198}
199__GPU_DEVICE__ double __hiloint2double(int __hi, int __lo) {
200 return __builtin_bit_cast(double,
201 ((unsigned long long)(unsigned int)__hi << 32) |
202 (unsigned long long)(unsigned int)__lo);
203}
204
205//===----------------------------------------------------------------------===//
206// Numeric conversions with explicit rounding.
207//===----------------------------------------------------------------------===//
208
209// Floating-point to integer conversions map directly onto the rounding
210// builtins.
211#define __GPU_CVT_FP2INT(__name, __res, __arg) \
212 __GPU_DEVICE__ __res __name##_rd(__arg __x) { \
213 return (__res)__builtin_elementwise_floor(__x); \
214 } \
215 __GPU_DEVICE__ __res __name##_rn(__arg __x) { \
216 return (__res)__builtin_elementwise_rint(__x); \
217 } \
218 __GPU_DEVICE__ __res __name##_ru(__arg __x) { \
219 return (__res)__builtin_elementwise_ceil(__x); \
220 } \
221 __GPU_DEVICE__ __res __name##_rz(__arg __x) { return (__res)__x; }
222
223__GPU_CVT_FP2INT(__double2int, int, double)
224__GPU_CVT_FP2INT(__double2uint, unsigned int, double)
225__GPU_CVT_FP2INT(__double2ll, long long, double)
226__GPU_CVT_FP2INT(__double2ull, unsigned long long, double)
227__GPU_CVT_FP2INT(__float2int, int, float)
228__GPU_CVT_FP2INT(__float2uint, unsigned int, float)
229__GPU_CVT_FP2INT(__float2ll, long long, float)
230__GPU_CVT_FP2INT(__float2ull, unsigned long long, float)
231
232#undef __GPU_CVT_FP2INT
233
234// Round-to-nearest is a plain conversion, so the '_rn' variants are exact.
235//
236// TODO: Directed rounding (rd/ru/rz) for integer-to-float and the narrowing
237// double-to-float conversions has no portable builtin yet (need pragma STDC
238// FENV_ROUND pragma), so these are stubbed.
239#define __GPU_CVT_TO_F(__name, __res, __arg) \
240 __GPU_DEVICE__ __res __name##_rd(__arg __x) { __builtin_trap(); } \
241 __GPU_DEVICE__ __res __name##_rn(__arg __x) { return (__res)__x; } \
242 __GPU_DEVICE__ __res __name##_ru(__arg __x) { __builtin_trap(); } \
243 __GPU_DEVICE__ __res __name##_rz(__arg __x) { __builtin_trap(); }
244
245__GPU_CVT_TO_F(__int2float, float, int)
246__GPU_CVT_TO_F(__uint2float, float, unsigned int)
247__GPU_CVT_TO_F(__ll2float, float, long long)
248__GPU_CVT_TO_F(__ull2float, float, unsigned long long)
249__GPU_CVT_TO_F(__ll2double, double, long long)
250__GPU_CVT_TO_F(__ull2double, double, unsigned long long)
251__GPU_CVT_TO_F(__double2float, float, double)
252
253#undef __GPU_CVT_TO_F
254
255// Integer to double conversions are always exact, so only round-to-nearest is
256// defined by CUDA and HIP.
257__GPU_DEVICE__ double __int2double_rn(int __x) { return (double)__x; }
258__GPU_DEVICE__ double __uint2double_rn(unsigned int __x) { return (double)__x; }
259
260//===----------------------------------------------------------------------===//
261// Wavefront vote and lane identity.
262//===----------------------------------------------------------------------===//
263
264__GPU_DEVICE__ unsigned int __lane_id(void) { return __gpu_lane_id(); }
265
266__GPU_DEVICE__ unsigned long long __ballot(int __pred) {
267 return __gpu_ballot(__gpu_lane_mask(), __pred);
268}
269__GPU_DEVICE__ unsigned long long __ballot64(int __pred) {
270 return __gpu_ballot(__gpu_lane_mask(), __pred);
271}
272__GPU_DEVICE__ unsigned long long __activemask(void) {
273 return __gpu_ballot(__gpu_lane_mask(), 1);
274}
275
276__GPU_DEVICE__ int __all(int __pred) {
277 return __gpu_ballot(__gpu_lane_mask(), __pred) == __gpu_lane_mask();
278}
279__GPU_DEVICE__ int __any(int __pred) {
280 return __gpu_ballot(__gpu_lane_mask(), __pred) != 0ull;
281}
282
283template <typename __T>
284__GPU_DEVICE__ int __gpu_fns_impl(__T __mask, unsigned int __base,
285 int __offset) {
286 const int __bits = int(sizeof(__T)) * 8;
287 __T __m = __mask;
288 int __off = __offset;
289 if (__offset == 0) {
290 __m &= (__T(1) << __base);
291 __off = 1;
292 } else if (__offset < 0) {
293 __m = __builtin_elementwise_bitreverse(__mask);
294 __base = (unsigned int)(__bits - 1) - __base;
295 __off = -__offset;
296 }
297 __m &= (~__T(0)) << __base;
298 if (__builtin_popcountg(__m) < __off)
299 return -1;
300 int __total = 0;
301 for (int __i = __bits / 2; __i > 0; __i >>= 1) {
302 __T __lo = __m & ((__T(1) << __i) - 1);
303 int __pcnt = __builtin_popcountg(__lo);
304 if (__pcnt < __off) {
305 __m >>= __i;
306 __off -= __pcnt;
307 __total += __i;
308 } else {
309 __m = __lo;
310 }
311 }
312 return __offset < 0 ? (__bits - 1) - __total : __total;
313}
314__GPU_DEVICE__ int __fns64(unsigned long long __mask, unsigned int __base,
315 int __offset) {
316 return __gpu_fns_impl(__mask, __base, __offset);
317}
318__GPU_DEVICE__ int __fns32(unsigned long long __mask, unsigned int __base,
319 int __offset) {
320 return __gpu_fns_impl((unsigned int)__mask, __base, __offset);
321}
322__GPU_DEVICE__ int __fns(unsigned int __mask, unsigned int __base,
323 int __offset) {
324 return __fns32(__mask, __base, __offset);
325}
326
327//===----------------------------------------------------------------------===//
328// Synchronization and fences
329//===----------------------------------------------------------------------===//
330
331// CUDA provides __syncthreads as an NVPTX compiler builtin directly.
332#if !defined(__CUDA__)
333__GPU_DEVICE__ void __syncthreads(void) { __gpu_sync_threads(); }
334#endif
335
336template <typename __Fn>
337__GPU_DEVICE__ int __gpu_block_reduce_impl(int __val, int __init, __Fn __op) {
338 static __attribute__((shared)) int __scratch[32];
339 unsigned int __lanes = __gpu_num_lanes();
340 unsigned int __nthreads = __gpu_num_threads(__GPU_X_DIM) *
343 unsigned int __nwarps = (__nthreads + __lanes - 1) / __lanes;
344 unsigned int __tid =
349
351 __scratch[__tid / __lanes] = __val;
353
354 int __acc = __init;
355 for (unsigned int __i = 0; __i < __nwarps; ++__i)
356 __acc = __op(__acc, __scratch[__i]);
358 return __acc;
359}
360
361__GPU_DEVICE__ int __syncthreads_count(int __pred) {
362 unsigned long long __mask = __gpu_lane_mask();
363 int __val = __builtin_popcountg(__gpu_ballot(__mask, __pred));
364 return __gpu_block_reduce_impl(__val, 0,
365 [](int __a, int __b) { return __a + __b; });
366}
367__GPU_DEVICE__ int __syncthreads_and(int __pred) {
368 unsigned long long __mask = __gpu_lane_mask();
369 int __val = __gpu_ballot(__mask, __pred) == __mask;
370 return __gpu_block_reduce_impl(__val, 1,
371 [](int __a, int __b) { return __a & __b; });
372}
373__GPU_DEVICE__ int __syncthreads_or(int __pred) {
374 unsigned long long __mask = __gpu_lane_mask();
375 int __val = __gpu_ballot(__mask, __pred) != 0ull;
376 return __gpu_block_reduce_impl(__val, 0,
377 [](int __a, int __b) { return __a | __b; });
378}
379
380__GPU_DEVICE__ void __threadfence(void) {
381 __scoped_atomic_thread_fence(__ATOMIC_SEQ_CST, __MEMORY_SCOPE_DEVICE);
382}
383__GPU_DEVICE__ void __threadfence_block(void) {
384 __scoped_atomic_thread_fence(__ATOMIC_SEQ_CST, __MEMORY_SCOPE_WRKGRP);
385}
386__GPU_DEVICE__ void __threadfence_system(void) {
387 __scoped_atomic_thread_fence(__ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
388}
389
390//===----------------------------------------------------------------------===//
391// Timers
392//===----------------------------------------------------------------------===//
393
394__GPU_DEVICE__ long long __clock64(void) {
395 return (long long)__builtin_readcyclecounter();
396}
397__GPU_DEVICE__ long long __clock(void) { return __clock64(); }
398__GPU_DEVICE__ long long clock64(void) { return __clock64(); }
399__GPU_DEVICE__ long long clock(void) { return __clock(); }
400__GPU_DEVICE__ long long wall_clock64(void) {
401 return (long long)__builtin_readsteadycounter();
402}
403
404// Warp shuffle / synchronization / reduction intrinsics.
406
407#pragma pop_macro("MAYBE_UNDEF")
408#pragma pop_macro("__GPU_DEVICE__")
409
410#endif // device compile
411#endif // __CLANG_GPU_DEVICE_FUNCTIONS_H__
__DEVICE__ unsigned long long __umul64hi(unsigned long long __a, unsigned long long __b)
__DEVICE__ void __threadfence(void)
__DEVICE__ unsigned int __usad(unsigned int __a, unsigned int __b, unsigned int __c)
__DEVICE__ float __uint_as_float(unsigned int __a)
__DEVICE__ unsigned int __float_as_uint(float __a)
__DEVICE__ int __any(int __a)
__DEVICE__ double __uint2double_rn(unsigned int __a)
__DEVICE__ int __ffsll(long long __a)
__DEVICE__ int __popc(unsigned int __a)
__DEVICE__ long long clock64()
__DEVICE__ long long __mul64hi(long long __a, long long __b)
__DEVICE__ long long __double_as_longlong(double __a)
__DEVICE__ int __mul24(int __a, int __b)
__DEVICE__ unsigned int __uhadd(unsigned int __a, unsigned int __b)
__DEVICE__ unsigned int __umul24(unsigned int __a, unsigned int __b)
__DEVICE__ void __threadfence_block(void)
__DEVICE__ int __clzll(long long __a)
__DEVICE__ int clock()
__DEVICE__ int __rhadd(int __a, int __b)
__DEVICE__ int __mulhi(int __a, int __b)
__DEVICE__ unsigned int __umulhi(unsigned int __a, unsigned int __b)
__DEVICE__ unsigned int __sad(int __a, int __b, unsigned int __c)
__DEVICE__ int __double2loint(double __a)
__DEVICE__ unsigned long long __brevll(unsigned long long __a)
__DEVICE__ unsigned int __ballot(int __a)
__DEVICE__ unsigned int __urhadd(unsigned int __a, unsigned int __b)
__DEVICE__ int __syncthreads_and(int __a)
__DEVICE__ double __int2double_rn(int __a)
__DEVICE__ double __hiloint2double(int __a, int __b)
__DEVICE__ unsigned int __brev(unsigned int __a)
__DEVICE__ int __float_as_int(float __a)
__DEVICE__ int __ffs(int __a)
__DEVICE__ void __threadfence_system(void)
__DEVICE__ int __hadd(int __a, int __b)
__DEVICE__ int __clz(int __a)
__DEVICE__ double __longlong_as_double(long long __a)
__DEVICE__ int __all(int __a)
__DEVICE__ float __int_as_float(int __a)
__DEVICE__ int __syncthreads_or(int __a)
__DEVICE__ int __syncthreads_count(int __a)
__DEVICE__ int __double2hiint(double __a)
__DEVICE__ unsigned int __byte_perm(unsigned int __a, unsigned int __b, unsigned int __c)
__DEVICE__ int __popcll(unsigned long long __a)
_Float16 __2f16 __attribute__((ext_vector_type(2)))
Zeroes the upper 128 bits (bits 255:128) of all YMM registers.
static __inline__ vector float vector float __b
Definition altivec.h:578
static _DEFAULT_FN_ATTRS __inline__ uint32_t __gpu_lane_id(void)
static _DEFAULT_FN_ATTRS __inline__ uint64_t __gpu_lane_mask(void)
static _DEFAULT_FN_ATTRS __inline__ uint32_t __gpu_num_lanes(void)
static _DEFAULT_FN_ATTRS __inline__ uint64_t __gpu_ballot(uint64_t __lane_mask, bool __x)
static _DEFAULT_FN_ATTRS __inline__ void __gpu_sync_threads(void)
static __inline__ uint32_t uint32_t __y
Definition arm_acle.h:132
static __inline__ void int __a
Definition emmintrin.h:4077
#define __GPU_Y_DIM
Definition gpuintrin.h:52
static _DEFAULT_FN_ATTRS __inline__ bool __gpu_is_first_in_lane(uint64_t __lane_mask)
Definition gpuintrin.h:119
static _DEFAULT_FN_ATTRS __inline__ uint32_t __gpu_num_threads(int __dim)
Definition gpuintrin.h:84
static _DEFAULT_FN_ATTRS __inline__ uint32_t __gpu_thread_id(int __dim)
Definition gpuintrin.h:98
#define __GPU_X_DIM
Definition gpuintrin.h:51
#define __GPU_Z_DIM
Definition gpuintrin.h:53
static __inline__ void const void * __src