Project
Loading...
Searching...
No Matches
GPUCommonDefAPI.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef GPUCOMMONDEFAPI_H
16#define GPUCOMMONDEFAPI_H
17// clang-format off
18
19#ifndef GPUCOMMONDEF_H
20 #error Please include GPUCommonDef.h!
21#endif
22
23#ifndef GPUCA_GPUCODE_DEVICE
24#include <cstdint>
25#endif
26
27//Define macros for GPU keywords. i-version defines inline functions.
28//All host-functions in GPU code are automatically inlined, to avoid duplicate symbols.
29//For non-inline host only functions, use no keyword at all!
30#if !defined(GPUCA_GPUCODE) || defined(__OPENCL_HOST__) || defined(__METAL_HOST__) // For host / ROOT dictionary
31 #define GPUd() // device function
32 #define GPUdDefault() // default (constructor / operator) device function
33 #define GPUhdDefault() // default (constructor / operator) host device function
34 #define GPUdi() inline // to-be-inlined device function
35 #define GPUdii() // Only on GPU to-be-inlined (forced) device function
36 #define GPUdni() // Device function, not-to-be-inlined
37 #define GPUdnii() inline // Device function, not-to-be-inlined on device, inlined on host
38 #define GPUh() // Host-only function
39 // NOTE: All GPUd*() functions are also compiled on the host during host compilation.
40 // The GPUh*() macros are for the rare cases of functions that you want to compile for the host during GPU compilation.
41 // Usually, you do not need the GPUh*() versions. If in doubt, use GPUd*()!
42 #define GPUhi() inline // to-be-inlined host-only function
43 #define GPUhd() // Host and device function, inlined during GPU compilation to avoid symbol clashes in host code
44 #define GPUhdi() inline // Host and device function, to-be-inlined on host and device
45 #define GPUhdni() // Host and device function, not to-be-inlined automatically
46 #define GPUg() INVALID_TRIGGER_ERROR_NO_GPU_CODE // GPU kernel
47 #define GPUshared() // shared memory variable declaration
48 #define GPUglobal() // global memory variable declaration (only used for kernel input pointers)
49 #define GPUconstant() // constant memory variable declaraion
50 #define GPUconstexpr() static constexpr // constexpr on GPU that needs to be instantiated for dynamic access (e.g. arrays), becomes __constant on GPU
51 #define GPUglobalconstexpr() constexpr // constexpr variable at program scope, needs the constant address space in MSL
52 #define GPUnoexcept() noexcept // noexcept where the backend supports it
53 #define GPUprivate() // private memory variable declaration
54 #define GPUgeneric() // reference / ptr to generic address space
55 #define GPUbarrier() // synchronize all GPU threads in block
56 #define GPUbarrierWarp() // synchronize threads inside warp
57 #define GPUAtomic(type) type // atomic variable type
58 #define GPUsharedref() // reference / ptr to shared memory
59 #define GPUglobalref() // reference / ptr to global memory
60 #define GPUconstantref() // reference / ptr to constant memory
61 #define GPUconstexprref() // reference / ptr to variable declared as GPUconstexpr()
62
63 #ifndef __VECTOR_TYPES_H__ // FIXME: ROOT will pull in these CUDA definitions if built against CUDA, so we have to add an ugly protection here
64 struct float4 { float x, y, z, w; };
65 struct float3 { float x, y, z; };
66 struct float2 { float x; float y; };
67 struct uchar2 { uint8_t x, y; };
68 struct short2 { int16_t x, y; };
69 struct ushort2 { uint16_t x, y; };
70 struct int2 { int32_t x, y; };
71 struct int3 { int32_t x, y, z; };
72 struct int4 { int32_t x, y, z, w; };
73 struct uint1 { uint32_t x; };
74 struct uint2 { uint32_t x, y; };
75 struct uint3 { uint32_t x, y, z; };
76 struct uint4 { uint32_t x, y, z, w; };
77 struct dim3 { uint32_t x, y, z; };
78 #endif
79#elif defined(__OPENCL__) // Defines for OpenCL
80 #define GPUd()
81 #define GPUdDefault()
82 #define GPUhdDefault()
83 #define GPUdi() inline
84 #define GPUdii() __attribute__((always_inline)) inline
85 #define GPUdni()
86 #define GPUdnii()
87 #define GPUh() INVALID_TRIGGER_ERROR_NO_HOST_CODE
88 #define GPUhi() INVALID_TRIGGER_ERROR_NO_HOST_CODE
89 #define GPUhd() inline
90 #define GPUhdi() inline
91 #define GPUhdni()
92 #define GPUg() __kernel
93 #define GPUshared() __local
94 #define GPUglobal() __global
95 #define GPUconstant() __constant // TODO: possibly add const __restrict where possible later!
96 #define GPUconstexpr() __constant
97 #define GPUprivate() __private
98 #define GPUgeneric() __generic
99 #define GPUconstexprref() GPUconstexpr()
100 #if defined(__OPENCL__) && !defined(__clang__)
101 #define GPUbarrier() work_group_barrier(mem_fence::global | mem_fence::local)
102 #define GPUbarrierWarp() sub_group_barrier(mem_fence::global | mem_fence::local)
103 #define GPUAtomic(type) atomic<type>
104 static_assert(sizeof(atomic<uint32_t>) == sizeof(uint32_t), "Invalid size of atomic type");
105 #else
106 #define GPUbarrier() barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE)
107 #define GPUbarrierWarp() sub_group_barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE)
108 #if defined(__OPENCL__) && defined(GPUCA_OPENCL_CLANG_C11_ATOMICS)
109 namespace o2 { namespace gpu {
110 template <class T> struct oclAtomic;
111 template <> struct oclAtomic<uint32_t> {typedef atomic_uint t;};
112 static_assert(sizeof(oclAtomic<uint32_t>::t) == sizeof(uint32_t), "Invalid size of atomic type");
113 }}
114 #define GPUAtomic(type) o2::gpu::oclAtomic<type>::t
115 #else
116 #define GPUAtomic(type) volatile type
117 #endif
118 #endif
119 #if !defined(__OPENCL__) // Other special defines for OpenCL 1
120 #define GPUCA_USE_TEMPLATE_ADDRESS_SPACES // TODO: check if we can make this (partially, where it is already implemented) compatible with OpenCL CPP
121 #define GPUsharedref() GPUshared()
122 #define GPUglobalref() GPUglobal()
123 #undef GPUgeneric
124 #define GPUgeneric()
125 #endif
126 #if (!defined(__OPENCL__) || !defined(GPUCA_NO_CONSTANT_MEMORY))
127 #define GPUconstantref() GPUconstant()
128 #endif
129#elif defined(__METAL__) //Defines for Metal Shading Language
130 // ADDRESS SPACES. This backend targets MSL 4.1 (macOS 27) and later only --
131 // see -std=metal4.1 in the CMakeLists, which fails the build on anything
132 // older rather than miscompiling quietly.
133 //
134 // That version is what makes the port tractable: up to MSL 4.0 a member
135 // function's implicit `this` is `thread`, which is wrong for us, since most
136 // objects the kernels touch live in `device` memory. Pinning defaulted
137 // constructors and operators to `device` was the 4.0 workaround, and it made
138 // the same type unusable in `thread` or `threadgroup`. In 4.1 an unannotated
139 // `this` is GENERIC and resolves to whichever address space the object is in
140 // -- the C++ semantics this codebase already assumes -- so GPUdDefault()
141 // needs nothing at all. The compiler resolves it statically in almost every
142 // case; it only falls back to a runtime branch where it cannot see through,
143 // such as argument buffers or dynamic libraries.
144 //
145 // The *ref() macros below stay explicit even so. They are already correct
146 // from the OpenCL port, an explicit annotation is never slower than a generic
147 // one, and `constant` is not covered by generic pointers at all.
148 #define GPUdDefault() // generic `this` (MSL 4.1+)
149 #define GPUd()
150 #define GPUhdDefault()
151 #define GPUdi() inline
152 #define GPUdii() inline
153 #define GPUdni()
154 #define GPUdnii()
155 #define GPUh() inline
156 #define GPUhi() inline
157 #define GPUhd() inline
158 #define GPUhdi() inline
159 #define GPUhdni()
160 #define GPUg() kernel
161 #define GPUshared() threadgroup
162 #define GPUglobal() device
163 #define GPUconstant() constant // TODO: possibly add const __restrict where possible later!
164 #define GPUconstexpr() constant
165 #define GPUglobalconstexpr() constant constexpr
166 #define GPUnoexcept()
167 #define GPUprivate() thread
168 #define GPUgeneric()
169 #define GPUglobalref() device
170 #define GPUsharedref() threadgroup
171 #define GPUprivateref() thread
172 #define GPUconstexprref() GPUconstexpr()
173 #define GPUdouble() float
174 #define GPUbarrier() threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup)
175 #define GPUbarrierWarp() simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup)
176 #define GPUAtomic(type) atomic<type> // atomic variable type
177#elif defined(__HIPCC__) //Defines for HIP
178 #define GPUd() __device__
179 #define GPUdDefault() __device__
180 #define GPUhdDefault() __host__ __device__
181 #define GPUdi() __device__ inline
182 #define GPUdii() __device__ __forceinline__
183 #define GPUdni() __device__ __attribute__((noinline))
184 #define GPUdnii() __device__ __attribute__((noinline))
185 #define GPUh() __host__ inline
186 #define GPUhi() __host__ inline
187 #define GPUhd() __host__ __device__ inline
188 #define GPUhdi() __host__ __device__ inline
189 #define GPUhdni() __host__ __device__
190 #define GPUg() __global__
191 #define GPUshared() __shared__
192 #if defined(GPUCA_GPUCODE_DEVICE) && 0 // TODO: Fix for HIP
193 #define GPUCA_USE_TEMPLATE_ADDRESS_SPACES
194 #define GPUglobal() __attribute__((address_space(1)))
195 #define GPUglobalref() GPUglobal()
196 #define GPUconstantref() __attribute__((address_space(4)))
197 #define GPUsharedref() __attribute__((address_space(3)))
198 #else
199 #define GPUglobal()
200 #endif
201 #define GPUconstant() __constant__
202 #define GPUconstexpr() constexpr __constant__
203 #define GPUprivate()
204 #define GPUgeneric()
205 #define GPUbarrier() __syncthreads()
206 #define GPUbarrierWarp()
207 #define GPUAtomic(type) type
208#elif defined(__CUDACC__) //Defines for CUDA
209 #ifndef GPUCA_GPUCODE_DEVICE
210 #define GPUd() __device__ inline // FIXME: DR: Workaround: mark device function as inline such that nvcc does not create bogus host symbols
211 #else
212 #define GPUd() __device__
213 #endif
214 #define GPUdDefault()
215 #define GPUhdDefault()
216 #define GPUdi() __device__ inline
217 #define GPUdii() __device__ inline
218 #define GPUdni() __device__ __attribute__((noinline))
219 #define GPUdnii() __device__ __attribute__((noinline))
220 #define GPUh() __host__ inline
221 #define GPUhi() __host__ inline
222 #define GPUhd() __host__ __device__ inline
223 #define GPUhdi() __host__ __device__ inline
224 #define GPUhdni() __host__ __device__
225 #define GPUg() __global__
226 #define GPUshared() __shared__
227 #define GPUglobal()
228 #define GPUconstant() __constant__
229 #define GPUconstexpr() constexpr __constant__
230 #define GPUprivate()
231 #define GPUgeneric()
232 #define GPUbarrier() __syncthreads()
233 #define GPUbarrierWarp() __syncwarp()
234 #define GPUAtomic(type) type
235#endif
236
237#ifndef GPUdic // Takes different parameter for inlining: 0 = never, 1 = always, 2 = compiler-decision
238#define GPUdic(...) GPUd()
239#endif
240#define GPUCA_GPUdic_select_0() GPUdni()
241#define GPUCA_GPUdic_select_1() GPUdii()
242#define GPUCA_GPUdic_select_2() GPUd()
243
244#if defined(GPUCA_NO_CONSTANT_MEMORY)
245 #undef GPUconstant
246 #define GPUconstant() GPUglobal()
247#endif
248
249#ifndef GPUsharedref
250#define GPUsharedref()
251#endif
252#ifndef GPUglobalref
253#define GPUglobalref()
254#endif
255#ifndef GPUconstantref
256#define GPUconstantref()
257#endif
258#ifndef GPUconstexprref
259#define GPUconstexprref()
260#endif
261#ifndef GPUglobalconstexpr
262#define GPUglobalconstexpr() constexpr
263#endif
264#ifndef GPUnoexcept
265#define GPUnoexcept() noexcept
266#endif
267
268#define GPUrestrict() __restrict__
269
270// Macros for GRID dimension
271#if defined(__CUDACC__) || defined(__HIPCC__)
272 #define get_global_id(dim) (blockIdx.x * blockDim.x + threadIdx.x)
273 #define get_global_size(dim) (blockDim.x * gridDim.x)
274 #define get_num_groups(dim) (gridDim.x)
275 #define get_local_id(dim) (threadIdx.x)
276 #define get_local_size(dim) (blockDim.x)
277 #define get_group_id(dim) (blockIdx.x)
278#elif defined(__OPENCL__)
279 // Using OpenCL defaults
280#else
281 #define get_global_id(dim) iBlock
282 #define get_global_size(dim) nBlocks
283 #define get_num_groups(dim) nBlocks
284 #define get_local_id(dim) 0
285 #define get_local_size(dim) 1
286 #define get_group_id(dim) iBlock
287#endif
288
289// clang-format on
290#endif
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint32_t y
uint32_t z
uint32_t x
int32_t x
int32_t y
int32_t z
int32_t y
int32_t x
int32_t y
int32_t z
int32_t x
int32_t w
int16_t y
int16_t x
uint8_t x
uint8_t y
uint32_t x
uint32_t x
uint32_t y
uint32_t y
uint32_t x
uint32_t z
uint32_t z
uint32_t w
uint32_t x
uint32_t y
uint16_t x
uint16_t y