17 #ifndef __SYCL_DEVICE_ONLY__
22 #include <type_traits>
24 #define __SYCL_STATIC_ASSERT_NOT_FLOAT(T) \
25 static_assert(!std::is_same<T, float>::value, \
26 "SYCL atomic function not available for float type")
41 static constexpr
bool value =
42 (std::is_same<T, int>::value || std::is_same<T, unsigned int>::value ||
43 std::is_same<T, long>::value || std::is_same<T, unsigned long>::value ||
44 std::is_same<T, long long>::value ||
45 std::is_same<T, unsigned long long>::value ||
46 std::is_same<T, float>::value);
50 static constexpr
bool value =
51 (AS == access::address_space::global_space ||
52 AS == access::address_space::local_space ||
53 AS == access::address_space::ext_intel_global_device_space);
64 access::address_space::ext_intel_global_device_space> {
75 #ifndef __SYCL_DEVICE_ONLY__
105 template <
typename T>
111 template <
typename T>
117 template <
typename T>
123 template <
typename T>
129 template <
typename T>
135 template <
typename T>
141 template <
typename T>
145 T Val = Ptr->load(MemoryOrder);
147 if (Ptr->compare_exchange_strong(Val, V, MemoryOrder, MemoryOrder))
149 Val = Ptr->load(MemoryOrder);
154 template <
typename T>
158 T Val = Ptr->load(MemoryOrder);
160 if (Ptr->compare_exchange_strong(Val, V, MemoryOrder, MemoryOrder))
162 Val = Ptr->load(MemoryOrder);
167 #endif // !defined(__SYCL_DEVICE_ONLY__)
173 access::address_space::global_space>
175 "
sycl::atomic is deprecated since SYCL 2020") atomic {
176 friend class atomic<
T, access::address_space::global_space>;
177 static_assert(detail::IsValidAtomicType<T>::value,
178 "Invalid SYCL atomic type. Valid types are: int, "
179 "unsigned int, long, unsigned long, long long, unsigned "
181 static_assert(detail::IsValidAtomicAddressSpace<addressSpace>::value,
182 "Invalid SYCL atomic address_space. Valid address spaces are: "
183 "global_space, local_space, ext_intel_global_device_space");
184 static constexpr auto SpirvScope =
187 template <typename pointerT, access::decorated IsDecorated>
189 GetDecoratedPtr(multi_ptr<pointerT, addressSpace, IsDecorated> ptr) {
190 if constexpr (IsDecorated == access::decorated::legacy)
193 return ptr.get_decorated();
197 template <
typename po
interT, access::decorated IsDecorated>
198 #ifdef __SYCL_DEVICE_ONLY__
200 : Ptr(GetDecoratedPtr(ptr))
203 : Ptr(
reinterpret_cast<std::atomic<T> *
>(ptr.
get()))
206 static_assert(
sizeof(
T) ==
sizeof(pointerT),
207 "T and pointerT must be same size");
210 #ifdef __ENABLE_USM_ADDR_SPACE__
214 _Space == addressSpace &&
215 addressSpace == access::address_space::global_space>>
216 atomic(
const atomic<T, access::address_space::ext_intel_global_device_space>
223 _Space == addressSpace &&
224 addressSpace == access::address_space::global_space>>
226 atomic<T, access::address_space::ext_intel_global_device_space> &&RHS) {
229 #endif // __ENABLE_USM_ADDR_SPACE__
231 void store(
T Operand,
memory_order Order = memory_order::relaxed) {
236 #ifdef __SYCL_DEVICE_ONLY__
237 template <
typename T2 = T>
239 load(
memory_order Order = memory_order::relaxed)
const {
243 template <
typename T2 = T>
245 load(
memory_order Order = memory_order::relaxed)
const {
246 auto *TmpPtr =
reinterpret_cast<typename
multi_ptr<
247 cl_int, addressSpace, access::decorated::yes
>::pointer>(Ptr);
250 cl_float ResVal = bit_cast<cl_float>(TmpVal);
260 T exchange(
T Operand,
memory_order Order = memory_order::relaxed) {
266 compare_exchange_strong(
T &Expected,
T Desired,
270 #ifdef __SYCL_DEVICE_ONLY__
271 T Value = __spirv_AtomicCompareExchange(
275 if (Value == Expected)
281 return Ptr->compare_exchange_strong(Expected, Desired,
287 T fetch_add(
T Operand,
memory_order Order = memory_order::relaxed) {
293 T fetch_sub(
T Operand,
memory_order Order = memory_order::relaxed) {
299 T fetch_and(
T Operand,
memory_order Order = memory_order::relaxed) {
305 T fetch_or(
T Operand,
memory_order Order = memory_order::relaxed) {
311 T fetch_xor(
T Operand,
memory_order Order = memory_order::relaxed) {
317 T fetch_min(
T Operand,
memory_order Order = memory_order::relaxed) {
323 T fetch_max(
T Operand,
memory_order Order = memory_order::relaxed) {
330 #ifdef __SYCL_DEVICE_ONLY__
337 template <
typename T, access::address_space addressSpace>
340 Object.store(Operand, MemoryOrder);
343 template <
typename T, access::address_space addressSpace>
346 return Object.load(MemoryOrder);
349 template <
typename T, access::address_space addressSpace>
352 return Object.exchange(Operand, MemoryOrder);
355 template <
typename T, access::address_space addressSpace>
357 atomic<T, addressSpace> Object,
T &Expected,
T Desired,
360 return Object.compare_exchange_strong(Expected, Desired, SuccessOrder,
364 template <
typename T, access::address_space addressSpace>
367 return Object.fetch_add(Operand, MemoryOrder);
370 template <
typename T, access::address_space addressSpace>
373 return Object.fetch_sub(Operand, MemoryOrder);
376 template <
typename T, access::address_space addressSpace>
379 return Object.fetch_and(Operand, MemoryOrder);
382 template <
typename T, access::address_space addressSpace>
385 return Object.fetch_or(Operand, MemoryOrder);
388 template <
typename T, access::address_space addressSpace>
391 return Object.fetch_xor(Operand, MemoryOrder);
394 template <
typename T, access::address_space addressSpace>
397 return Object.fetch_min(Operand, MemoryOrder);
400 template <
typename T, access::address_space addressSpace>
403 return Object.fetch_max(Operand, MemoryOrder);
409 #undef __SYCL_STATIC_ASSERT_NOT_FLOAT