18#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) || defined(ALPAKA_ACC_GPU_HIP_ENABLED)
20# if !defined(ALPAKA_HOST_ONLY)
22# if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) && !ALPAKA_LANG_CUDA
23# error If ALPAKA_ACC_GPU_CUDA_ENABLED is set, the compiler has to support CUDA!
26# if defined(ALPAKA_ACC_GPU_HIP_ENABLED) && !ALPAKA_LANG_HIP
27# error If ALPAKA_ACC_GPU_HIP_ENABLED is set, the compiler has to support HIP!
40 std::conditional_t<
sizeof(T) == 8u,
unsigned long long int,
void>>;
52 return std::bit_cast<AtomicCasType<T>>(value);
64 typename TSfinae = void,
65 typename TDefer =
void>
75 using EmulatedType = std::decay_t<
decltype(*addressAsIntegralType)>;
80# if __has_builtin(__scoped_atomic_load_n)
82 __scoped_atomic_load_n(addressAsIntegralType, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE)};
83# elif __has_builtin(__hip_atomic_load)
84 EmulatedType old{__hip_atomic_load(addressAsIntegralType, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT)};
86 EmulatedType old{__atomic_load_n(addressAsIntegralType, __ATOMIC_RELAXED)};
89 EmulatedType old{*addressAsIntegralType};
95 T v = std::bit_cast<T>(assumed);
97 using Cas = alpaka::trait::
98 AtomicOp<alpaka::AtomicCas, alpaka::AtomicUniformCudaHipBuiltIn, EmulatedType, THierarchy>;
99 old = Cas::atomicOp(ctx, addressAsIntegralType, assumed,
reinterpretValue(v));
101 }
while(assumed != old);
102 return std::bit_cast<T>(old);
107 template<
typename T,
typename THierarchy>
118 using EmulatedType = std::decay_t<
decltype(*addressAsIntegralType)>;
122 auto old = alpaka::trait::
123 AtomicOp<alpaka::AtomicCas, alpaka::AtomicUniformCudaHipBuiltIn, EmulatedType, THierarchy>::
124 atomicOp(ctx, addressAsIntegralType, reinterpretedCompare, reinterpretedValue);
126 return std::bit_cast<T>(old);
131 template<
typename T,
typename THierarchy>
145 template<
typename T,
typename THierarchy>
151 std::enable_if_t<std::is_floating_point_v<T>>>
157 "EmulateAtomic<alpaka::AtomicDec> is not supported for floating point data types!");
163 template<
typename T,
typename THierarchy>
169 std::enable_if_t<std::is_floating_point_v<T>>>
175 "EmulateAtomic<alpaka::AtomicInc> is not supported for floating point data types!");
181 template<
typename T,
typename THierarchy>
187 std::enable_if_t<std::is_floating_point_v<T>>>
193 "EmulateAtomic<alpaka::AtomicAnd> is not supported for floating point data types!");
199 template<
typename T,
typename THierarchy>
205 std::enable_if_t<std::is_floating_point_v<T>>>
211 "EmulateAtomic<alpaka::AtomicOr> is not supported for floating point data types!");
217 template<
typename T,
typename THierarchy>
223 std::enable_if_t<std::is_floating_point_v<T>>>
229 "EmulateAtomic<alpaka::AtomicXor> is not supported for floating point data types!");
241 template<
typename TOp,
typename T,
typename THierarchy>
246 [[maybe_unused]] T*
const addr,
247 [[maybe_unused]] T
const& value) -> T
250 sizeof(T) == 4u ||
sizeof(T) == 8u,
251 "atomicOp<TOp, AtomicUniformCudaHipBuiltIn, T>(atomic, addr, value) is not supported! Only 64 and "
252 "32bit atomics are supported.");
255 return ::AlpakaBuiltInAtomic<TOp, T, THierarchy>::atomic(addr, value);
257 else if constexpr(std::is_same_v<unsigned long int, T>)
260 return ::AlpakaBuiltInAtomic<TOp, unsigned int, THierarchy>::atomic(
261 reinterpret_cast<unsigned int*
>(addr),
262 static_cast<unsigned int>(value));
266 return ::AlpakaBuiltInAtomic<TOp, unsigned long long int, THierarchy>::atomic(
267 reinterpret_cast<unsigned long long int*
>(addr),
268 static_cast<unsigned long long int>(value));
276 template<
typename T,
typename THierarchy>
281 [[maybe_unused]] T*
const addr,
282 [[maybe_unused]] T
const& compare,
283 [[maybe_unused]] T
const& value) -> T
286 sizeof(T) == 4u ||
sizeof(T) == 8u,
287 "atomicOp<AtomicCas, AtomicUniformCudaHipBuiltIn, T>(atomic, addr, compare, value) is not "
288 "supported! Only 64 and "
289 "32bit atomics are supported.");
292 return ::AlpakaBuiltInAtomic<AtomicCas, T, THierarchy>::atomic(addr, compare, value);
294 else if constexpr(std::is_same_v<unsigned long int, T>)
297 return ::AlpakaBuiltInAtomic<AtomicCas, unsigned int, THierarchy>::atomic(
298 reinterpret_cast<unsigned int*
>(addr),
299 static_cast<unsigned int>(compare),
300 static_cast<unsigned int>(value));
305 return ::AlpakaBuiltInAtomic<AtomicCas, unsigned long long int, THierarchy>::atomic(
306 reinterpret_cast<unsigned long long int*
>(addr),
307 static_cast<unsigned long long int>(compare),
308 static_cast<unsigned long long int>(value));
The alpaka accelerator library.
Provide an interface to builtin atomic functions.
The compare and swap function object.
The decrement function object.
The increment function object.
The subtraction function object.
The exclusive or function object.
The atomic operation trait.
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &, T *const, T const &) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &ctx, T *const addr, T const &compare, T const &value) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &, T *const, T const &) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &, T *const, T const &) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &, T *const, T const &) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &ctx, T *const addr, T const &value) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &, T *const, T const &) -> T
static __device__ auto atomic(alpaka::AtomicUniformCudaHipBuiltIn const &ctx, T *const addr, T const &value) -> T
std::conditional_t< sizeof(T)==4u, unsigned int, std::conditional_t< sizeof(T)==8u, unsigned long long int, void > > AtomicCasType
static __device__ auto reinterpretValue(T value) -> AtomicCasType< T > requires(sizeof(T)==4u||sizeof(T)==8u)
static __device__ auto reinterpretAddress(T *address) -> AtomicCasType< T > *requires(sizeof(T)==4u||sizeof(T)==8u)