14#if ALPAKA_LANG_CUDA || ALPAKA_LANG_HIP
22 class AtomicUniformCudaHipBuiltIn
29inline namespace alpakaGlobal
45 template<
typename TOp,
typename T,
typename T_Scope,
typename TSfinae =
void>
46 struct AlpakaBuiltInAtomic : std::false_type
51 template<
typename T,
typename T_Scope>
52 struct AlpakaBuiltInAtomic<
57 decltype(atomicCAS(alpaka::core::declval<T*>(), alpaka::core::declval<T>(), alpaka::core::declval<T>()))>>
60 static __device__ T atomic(T* add, T compare, T value)
62 return atomicCAS(add, compare, value);
67 struct AlpakaBuiltInAtomic<
70 alpaka::onAcc::scope::Block,
71 typename std::void_t<decltype(atomicCAS_block(
72 alpaka::core::declval<T*>(),
73 alpaka::core::declval<T>(),
74 alpaka::core::declval<T>()))>> : std::true_type
76 static __device__ T atomic(T* add, T compare, T value)
78 return atomicCAS_block(add, compare, value);
83 template<
typename T,
typename T_Scope>
84 struct AlpakaBuiltInAtomic<
88 typename std::void_t<decltype(atomicAdd(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
91 static __device__ T atomic(T* add, T value)
98 struct AlpakaBuiltInAtomic<
101 alpaka::onAcc::scope::Block,
102 typename std::void_t<decltype(atomicAdd_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
105 static __device__ T atomic(T* add, T value)
107 return atomicAdd_block(add, value);
111# if (ALPAKA_LANG_HIP)
116 struct AlpakaBuiltInAtomic<
alpaka::operation::Add, float, alpaka::onAcc::scope::Block> : std::false_type
123 template<
typename T,
typename T_Scope>
124 struct AlpakaBuiltInAtomic<
128 typename std::void_t<decltype(atomicSub(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
131 static __device__ T atomic(T* add, T value)
138 struct AlpakaBuiltInAtomic<
141 alpaka::onAcc::scope::Block,
142 typename std::void_t<decltype(atomicSub_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
145 static __device__ T atomic(T* add, T value)
147 return atomicSub_block(add, value);
152 template<
typename T,
typename T_Scope>
153 struct AlpakaBuiltInAtomic<
157 typename std::void_t<decltype(atomicMin(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
160 static __device__ T atomic(T* add, T value)
167 struct AlpakaBuiltInAtomic<
170 alpaka::onAcc::scope::Block,
171 typename std::void_t<decltype(atomicMin_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
174 static __device__ T atomic(T* add, T value)
176 return atomicMin_block(add, value);
181# if (ALPAKA_LANG_HIP)
182 template<
typename T_Scope>
183 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, float, T_Scope> : std::false_type
188 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, float, alpaka::onAcc::scope::Block> : std::false_type
192 template<
typename T_Scope>
193 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, double, T_Scope> : std::false_type
198 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, double, alpaka::onAcc::scope::Block> : std::false_type
202# if !__has_builtin(__hip_atomic_compare_exchange_strong)
203 template<
typename T_Scope>
204 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, unsigned long long, T_Scope> : std::false_type
209 struct AlpakaBuiltInAtomic<
alpaka::operation::Min, unsigned long long, alpaka::onAcc::scope::Block>
218 template<
typename T,
typename T_Scope>
219 struct AlpakaBuiltInAtomic<
223 typename std::void_t<decltype(atomicMax(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
226 static __device__ T atomic(T* add, T value)
233 struct AlpakaBuiltInAtomic<
236 alpaka::onAcc::scope::Block,
237 typename std::void_t<decltype(atomicMax_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
240 static __device__ T atomic(T* add, T value)
242 return atomicMax_block(add, value);
247# if (ALPAKA_LANG_HIP)
248 template<
typename T_Scope>
249 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, float, T_Scope> : std::false_type
254 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, float, alpaka::onAcc::scope::Block> : std::false_type
258 template<
typename T_Scope>
259 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, double, T_Scope> : std::false_type
264 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, double, alpaka::onAcc::scope::Block> : std::false_type
268# if !__has_builtin(__hip_atomic_compare_exchange_strong)
269 template<
typename T_Scope>
270 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, unsigned long long, T_Scope> : std::false_type
275 struct AlpakaBuiltInAtomic<
alpaka::operation::Max, unsigned long long, alpaka::onAcc::scope::Block>
285 template<
typename T,
typename T_Scope>
286 struct AlpakaBuiltInAtomic<
290 typename std::void_t<decltype(atomicExch(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
293 static __device__ T atomic(T* add, T value)
300 struct AlpakaBuiltInAtomic<
303 alpaka::onAcc::scope::Block,
304 typename std::void_t<decltype(atomicExch_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
307 static __device__ T atomic(T* add, T value)
309 return atomicExch_block(add, value);
315 template<
typename T,
typename T_Scope>
316 struct AlpakaBuiltInAtomic<
320 typename std::void_t<decltype(atomicInc(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
323 static __device__ T atomic(T* add, T value)
330 struct AlpakaBuiltInAtomic<
333 alpaka::onAcc::scope::Block,
334 typename std::void_t<decltype(atomicInc_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
337 static __device__ T atomic(T* add, T value)
339 return atomicInc_block(add, value);
345 template<
typename T,
typename T_Scope>
346 struct AlpakaBuiltInAtomic<
350 typename std::void_t<decltype(atomicDec(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
353 static __device__ T atomic(T* add, T value)
360 struct AlpakaBuiltInAtomic<
363 alpaka::onAcc::scope::Block,
364 typename std::void_t<decltype(atomicDec_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
367 static __device__ T atomic(T* add, T value)
369 return atomicDec_block(add, value);
375 template<
typename T,
typename T_Scope>
376 struct AlpakaBuiltInAtomic<
380 typename std::void_t<decltype(atomicAnd(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
383 static __device__ T atomic(T* add, T value)
390 struct AlpakaBuiltInAtomic<
393 alpaka::onAcc::scope::Block,
394 typename std::void_t<decltype(atomicAnd_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
397 static __device__ T atomic(T* add, T value)
399 return atomicAnd_block(add, value);
405 template<
typename T,
typename T_Scope>
406 struct AlpakaBuiltInAtomic<
410 typename std::void_t<decltype(atomicOr(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
413 static __device__ T atomic(T* add, T value)
420 struct AlpakaBuiltInAtomic<
423 alpaka::onAcc::scope::Block,
424 typename std::void_t<decltype(atomicOr_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
427 static __device__ T atomic(T* add, T value)
429 return atomicOr_block(add, value);
435 template<
typename T,
typename T_Scope>
436 struct AlpakaBuiltInAtomic<
440 typename std::void_t<decltype(atomicXor(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
443 static __device__ T atomic(T* add, T value)
450 struct AlpakaBuiltInAtomic<
453 alpaka::onAcc::scope::Block,
454 typename std::void_t<decltype(atomicXor_block(alpaka::core::declval<T*>(), alpaka::core::declval<T>()))>>
457 static __device__ T atomic(T* add, T value)
459 return atomicXor_block(add, value);
functionality which is usable on the accelerator compute device from within a kernel.
constexpr auto atomicAnd(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic and operation.
constexpr auto atomicXor(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic xor operation.
constexpr auto atomicAdd(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic add operation.
constexpr auto atomicSub(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic sub operation.
constexpr auto atomicExch(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic exchange operation.
constexpr auto atomicDec(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic decrement operation.
constexpr auto atomicInc(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic increment operation.
constexpr auto atomicOr(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic or operation.
constexpr auto atomicMin(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic min operation.
constexpr auto atomicMax(auto const &acc, T *const addr, T const &value, T_Scope const hier=T_Scope()) -> T
Executes an atomic max operation.