RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
atomic.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_policy_hip_atomic_HPP
21 #define RAJA_policy_hip_atomic_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #if defined(RAJA_ENABLE_HIP)
26 
27 #include <cstdint>
28 #include <stdexcept>
29 #include <type_traits>
30 #include "hip/hip_runtime.h"
31 
32 #include "camp/list.hpp"
33 
36 
37 #if defined(RAJA_OPENMP_ACTIVE)
39 #endif
40 
41 #include "RAJA/util/EnableIf.hpp"
42 #include "RAJA/util/Operators.hpp"
44 #include "RAJA/util/macros.hpp"
45 
46 // TODO: When we can use if constexpr in C++17, this file can be cleaned up
47 
48 namespace RAJA
49 {
50 
51 
52 namespace detail
53 {
54 
55 using hip_atomicCommon_builtin_types =
56  ::camp::list<int, unsigned int, unsigned long long>;
57 
64 template<typename T>
65 struct hip_useBuiltinCommon
66 {
67  static constexpr bool value = std::is_same<T, int>::value ||
68  std::is_same<T, unsigned int>::value ||
69  std::is_same<T, unsigned long long>::value;
70 };
71 
79 template<typename T>
80 struct hip_useReinterpretCommon
81 {
82  static constexpr bool value = !hip_useBuiltinCommon<T>::value &&
83  (sizeof(T) == sizeof(unsigned int) ||
84  sizeof(T) == sizeof(unsigned long long));
85 
86  using type = std::conditional_t<sizeof(T) == sizeof(unsigned int),
87  unsigned int,
88  unsigned long long>;
89 };
90 
94 template<typename T>
95 using hip_useReinterpretCommon_t = typename hip_useReinterpretCommon<T>::type;
96 
104 template<typename T,
105  std::enable_if_t<hip_useBuiltinCommon<T>::value, bool> = true>
106 RAJA_INLINE __device__ T hip_atomicOr(T* acc, T value)
107 {
108  return ::atomicOr(acc, value);
109 }
110 
115 template<typename T>
116 struct hip_useBuiltinExchange
117 {
118  static constexpr bool value = std::is_same<T, int>::value ||
119  std::is_same<T, unsigned int>::value ||
120  std::is_same<T, unsigned long long>::value ||
121  std::is_same<T, float>::value;
122 };
123 
128 template<typename T>
129 struct hip_useReinterpretExchange
130 {
131  static constexpr bool value = !hip_useBuiltinExchange<T>::value &&
132  (sizeof(T) == sizeof(unsigned int) ||
133  sizeof(T) == sizeof(unsigned long long));
134 
135  using type = std::conditional_t<sizeof(T) == sizeof(unsigned int),
136  unsigned int,
137  unsigned long long>;
138 };
139 
143 template<typename T>
144 using hip_useReinterpretExchange_t =
145  typename hip_useReinterpretExchange<T>::type;
146 
151 template<typename T,
152  std::enable_if_t<hip_useBuiltinExchange<T>::value, bool> = true>
153 RAJA_INLINE __device__ T hip_atomicExchange(T* acc, T value)
154 {
155  return ::atomicExch(acc, value);
156 }
157 
162 template<typename T,
163  std::enable_if_t<hip_useReinterpretExchange<T>::value, bool> = true>
164 RAJA_INLINE __device__ T hip_atomicExchange(T* acc, T value)
165 {
166  using R = hip_useReinterpretExchange_t<T>;
167 
168  return RAJA::util::reinterp_A_as_B<R, T>(hip_atomicExchange(
169  reinterpret_cast<R*>(acc), RAJA::util::reinterp_A_as_B<T, R>(value)));
170 }
171 
172 
173 #if defined(__has_builtin) && \
174  (__has_builtin(__hip_atomic_load) || __has_builtin(__hip_atomic_store))
175 
180 template<typename T>
181 struct hip_useBuiltinLoad
182 {
183  static constexpr bool value =
184  (std::is_integral<T>::value || std::is_enum<T>::value) &&
185  (sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
186 };
187 
188 template<typename T>
189 using hip_useBuiltinStore = hip_useBuiltinLoad<T>;
190 
195 template<typename T>
196 struct hip_useReinterpretLoad
197 {
198  static constexpr bool value = !std::is_integral<T>::value &&
199  !std::is_enum<T>::value &&
200  ((sizeof(T) == 1
201 #if !defined(UINT8_MAX)
202  && sizeof(unsigned char) == 1
203 #endif
204  ) ||
205  (sizeof(T) == 2
206 #if !defined(UINT16_MAX)
207  && sizeof(unsigned short) == 2
208 #endif
209  ) ||
210  (sizeof(T) == 4
211 #if !defined(UINT32_MAX)
212  && sizeof(unsigned int) == 4
213 #endif
214  ) ||
215  (sizeof(T) == 8
216 #if !defined(UINT64_MAX)
217  && sizeof(unsigned long long) == 8
218 #endif
219  ));
220 
221  using type =
222  std::conditional_t<sizeof(T) == 1,
223 #if defined(UINT8_MAX)
224  uint8_t,
225 #else
226  unsigned char,
227 #endif
228  std::conditional_t<sizeof(T) == 2,
229 #if defined(UINT16_MAX)
230  uint16_t,
231 #else
232  unsigned short,
233 #endif
234  std::conditional_t<sizeof(T) == 4,
235 #if defined(UINT32_MAX)
236  uint32_t,
237 #else
238  unsigned int,
239 #endif
240 #if defined(UINT64_MAX)
241  uint64_t>>>;
242 #else
243  unsigned long long>>>;
244 #endif
245 };
246 
247 template<typename T>
248 using hip_useReinterpretStore = hip_useReinterpretLoad<T>;
249 
250 #else
251 
252 template<typename T>
253 using hip_useBuiltinLoad = hip_useBuiltinCommon<T>;
254 
255 template<typename T>
256 using hip_useBuiltinStore = hip_useBuiltinExchange<T>;
257 
261 template<typename T>
262 using hip_useReinterpretLoad = hip_useReinterpretCommon<T>;
263 
264 template<typename T>
265 using hip_useReinterpretStore = hip_useReinterpretExchange<T>;
266 
267 #endif
268 
272 template<typename T>
273 using hip_useReinterpretLoad_t = typename hip_useReinterpretLoad<T>::type;
274 
275 template<typename T>
276 using hip_useReinterpretStore_t = typename hip_useReinterpretStore<T>::type;
277 
281 template<typename T,
282  std::enable_if_t<hip_useBuiltinLoad<T>::value, bool> = true>
283 RAJA_INLINE __device__ T hip_atomicLoad(T* acc)
284 {
285 #if defined(__has_builtin) && __has_builtin(__hip_atomic_load)
286  return __hip_atomic_load(acc, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT);
287 #else
288  return hip_atomicOr(acc, static_cast<T>(0));
289 #endif
290 }
291 
292 template<typename T,
293  std::enable_if_t<hip_useReinterpretLoad<T>::value, bool> = true>
294 RAJA_INLINE __device__ T hip_atomicLoad(T* acc)
295 {
296  using R = hip_useReinterpretLoad_t<T>;
297 
298  return RAJA::util::reinterp_A_as_B<R, T>(
299  hip_atomicLoad(reinterpret_cast<R*>(acc)));
300 }
301 
305 template<typename T,
306  std::enable_if_t<hip_useBuiltinStore<T>::value, bool> = true>
307 RAJA_INLINE __device__ void hip_atomicStore(T* acc, T value)
308 {
309 #if defined(__has_builtin) && __has_builtin(__hip_atomic_store)
310  __hip_atomic_store(acc, value, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT);
311 #else
312  hip_atomicExchange(acc, value);
313 #endif
314 }
315 
316 template<typename T,
317  std::enable_if_t<hip_useReinterpretStore<T>::value, bool> = true>
318 RAJA_INLINE __device__ void hip_atomicStore(T* acc, T value)
319 {
320  using R = hip_useReinterpretStore_t<T>;
321 
322  hip_atomicStore(reinterpret_cast<R*>(acc),
323  RAJA::util::reinterp_A_as_B<T, R>(value));
324 }
325 
331 template<typename T,
332  std::enable_if_t<hip_useBuiltinCommon<T>::value, bool> = true>
333 RAJA_INLINE __device__ T hip_atomicCAS(T* acc, T compare, T value)
334 {
335  return ::atomicCAS(acc, compare, value);
336 }
337 
343 template<typename T,
344  std::enable_if_t<hip_useReinterpretCommon<T>::value, bool> = true>
345 RAJA_INLINE __device__ T hip_atomicCAS(T* acc, T compare, T value)
346 {
347  using R = hip_useReinterpretCommon_t<T>;
348 
349  return RAJA::util::reinterp_A_as_B<R, T>(hip_atomicCAS(
350  reinterpret_cast<R*>(acc), RAJA::util::reinterp_A_as_B<T, R>(compare),
351  RAJA::util::reinterp_A_as_B<T, R>(value)));
352 }
353 
359 template<typename T,
360  std::enable_if_t<hip_useBuiltinCommon<T>::value, bool> = true>
361 RAJA_INLINE __device__ bool hip_atomicCAS_equal(const T& a, const T& b)
362 {
363  return a == b;
364 }
365 
366 template<typename T,
367  std::enable_if_t<hip_useReinterpretCommon<T>::value, bool> = true>
368 RAJA_INLINE __device__ bool hip_atomicCAS_equal(const T& a, const T& b)
369 {
370  using R = hip_useReinterpretCommon_t<T>;
371 
372  return hip_atomicCAS_equal(RAJA::util::reinterp_A_as_B<T, R>(a),
373  RAJA::util::reinterp_A_as_B<T, R>(b));
374 }
375 
382 template<typename T, typename Oper>
383 RAJA_INLINE __device__ T hip_atomicCAS_loop(T* acc, Oper&& oper)
384 {
385  T old = hip_atomicLoad(acc);
386  T expected;
387 
388  do
389  {
390  expected = old;
391  old = hip_atomicCAS(acc, expected, oper(expected));
392  } while (!hip_atomicCAS_equal(old, expected));
393 
394  return old;
395 }
396 
403 template<typename T, typename Oper, typename ShortCircuit>
404 RAJA_INLINE __device__ T hip_atomicCAS_loop(T* acc,
405  Oper&& oper,
406  ShortCircuit&& sc)
407 {
408  T old = hip_atomicLoad(acc);
409 
410  if (sc(old))
411  {
412  return old;
413  }
414 
415  T expected;
416 
417  do
418  {
419  expected = old;
420  old = hip_atomicCAS(acc, expected, oper(expected));
421  } while (!hip_atomicCAS_equal(old, expected) && !sc(old));
422 
423  return old;
424 }
425 
433 using hip_atomicAdd_builtin_types = ::camp::list<int,
434  unsigned int,
435  unsigned long long,
436  float
437 #ifdef RAJA_ENABLE_HIP_DOUBLE_ATOMICADD
438  ,
439  double
440 #endif
441  >;
442 
443 template<
444  typename T,
446 RAJA_INLINE __device__ T hip_atomicAdd(T* acc, T value)
447 {
448  return hip_atomicCAS_loop(acc, [value](T old) {
449  return old + value;
450  });
451 }
452 
453 template<
454  typename T,
456 RAJA_INLINE __device__ T hip_atomicAdd(T* acc, T value)
457 {
458  return ::atomicAdd(acc, value);
459 }
460 
468 using hip_atomicSub_builtin_types = ::camp::list<int,
469  unsigned int,
470  unsigned long long,
471  float
472 #ifdef RAJA_ENABLE_HIP_DOUBLE_ATOMICADD
473  ,
474  double
475 #endif
476  >;
477 
484 using hip_atomicSub_via_Sub_builtin_types = ::camp::list<int, unsigned int>;
485 
492 using hip_atomicSub_via_Add_builtin_types = ::camp::list<unsigned long long,
493  float
494 #ifdef RAJA_ENABLE_HIP_DOUBLE_ATOMICADD
495  ,
496  double
497 #endif
498  >;
499 
503 template<
504  typename T,
506 RAJA_INLINE __device__ T hip_atomicSub(T* acc, T value)
507 {
508  return hip_atomicCAS_loop(acc, [value](T old) {
509  return old - value;
510  });
511 }
512 
516 template<
517  typename T,
519  nullptr>
520 RAJA_INLINE __device__ T hip_atomicSub(T* acc, T value)
521 {
522  return ::atomicSub(acc, value);
523 }
524 
528 template<
529  typename T,
531  nullptr>
532 RAJA_INLINE __device__ T hip_atomicSub(T* acc, T value)
533 {
534  return ::atomicAdd(acc, -value);
535 }
536 
540 using hip_atomicMin_builtin_types = hip_atomicCommon_builtin_types;
541 
542 template<
543  typename T,
545 RAJA_INLINE __device__ T hip_atomicMin(T* acc, T value)
546 {
547  return hip_atomicCAS_loop(
548  acc,
549  [value](T old) {
550  return value < old ? value : old;
551  },
552  [value](T current) {
553  return current <= value;
554  });
555 }
556 
557 template<
558  typename T,
560 RAJA_INLINE __device__ T hip_atomicMin(T* acc, T value)
561 {
562  return ::atomicMin(acc, value);
563 }
564 
568 using hip_atomicMax_builtin_types = hip_atomicCommon_builtin_types;
569 
570 template<
571  typename T,
573 RAJA_INLINE __device__ T hip_atomicMax(T* acc, T value)
574 {
575  return hip_atomicCAS_loop(
576  acc,
577  [value](T old) {
578  return old < value ? value : old;
579  },
580  [value](T current) {
581  return value <= current;
582  });
583 }
584 
585 template<
586  typename T,
588 RAJA_INLINE __device__ T hip_atomicMax(T* acc, T value)
589 {
590  return ::atomicMax(acc, value);
591 }
592 
596 template<typename T>
597 RAJA_INLINE __device__ T hip_atomicInc(T* acc, T value)
598 {
599  return hip_atomicCAS_loop(acc, [value](T old) {
600  return value <= old ? static_cast<T>(0) : old + static_cast<T>(1);
601  });
602 }
603 
607 template<typename T>
608 RAJA_INLINE __device__ T hip_atomicInc(T* acc)
609 {
610  return hip_atomicAdd(acc, static_cast<T>(1));
611 }
612 
616 template<typename T>
617 RAJA_INLINE __device__ T hip_atomicDec(T* acc, T value)
618 {
619  return hip_atomicCAS_loop(acc, [value](T old) {
620  return old == static_cast<T>(0) || value < old ? value
621  : old - static_cast<T>(1);
622  });
623 }
624 
628 template<typename T>
629 RAJA_INLINE __device__ T hip_atomicDec(T* acc)
630 {
631  return hip_atomicSub(acc, static_cast<T>(1));
632 }
633 
637 using hip_atomicAnd_builtin_types = hip_atomicCommon_builtin_types;
638 
639 template<
640  typename T,
642 RAJA_INLINE __device__ T hip_atomicAnd(T* acc, T value)
643 {
644  return hip_atomicCAS_loop(acc, [value](T old) {
645  return old & value;
646  });
647 }
648 
649 template<
650  typename T,
652 RAJA_INLINE __device__ T hip_atomicAnd(T* acc, T value)
653 {
654  return ::atomicAnd(acc, value);
655 }
656 
660 using hip_atomicOr_builtin_types = hip_atomicCommon_builtin_types;
661 
662 template<
663  typename T,
665 RAJA_INLINE __device__ T hip_atomicOr(T* acc, T value)
666 {
667  return hip_atomicCAS_loop(acc, [value](T old) {
668  return old | value;
669  });
670 }
671 
681 using hip_atomicXor_builtin_types = hip_atomicCommon_builtin_types;
682 
683 template<
684  typename T,
686 RAJA_INLINE __device__ T hip_atomicXor(T* acc, T value)
687 {
688  return hip_atomicCAS_loop(acc, [value](T old) {
689  return old ^ value;
690  });
691 }
692 
693 template<
694  typename T,
696 RAJA_INLINE __device__ T hip_atomicXor(T* acc, T value)
697 {
698  return ::atomicXor(acc, value);
699 }
700 
701 
702 } // namespace detail
703 
714 template<typename T, typename host_policy>
715 RAJA_INLINE RAJA_HOST_DEVICE T atomicLoad(hip_atomic_explicit<host_policy>,
716  T* acc)
717 {
718 #if defined(__HIP_DEVICE_COMPILE__)
719  return detail::hip_atomicLoad(acc);
720 #else
721  return RAJA::atomicLoad(host_policy {}, acc);
722 #endif
723 }
724 
726 template<typename T, typename host_policy>
727 RAJA_INLINE RAJA_HOST_DEVICE void atomicStore(hip_atomic_explicit<host_policy>,
728  T* acc,
729  T value)
730 {
731 #if defined(__HIP_DEVICE_COMPILE__)
732  detail::hip_atomicStore(acc, value);
733 #else
734  RAJA::atomicStore(host_policy {}, acc, value);
735 #endif
736 }
737 
739 template<typename T, typename host_policy>
740 RAJA_INLINE RAJA_HOST_DEVICE T atomicAdd(hip_atomic_explicit<host_policy>,
741  T* acc,
742  T value)
743 {
744 #if defined(__HIP_DEVICE_COMPILE__)
745  return detail::hip_atomicAdd(acc, value);
746 #else
747  return RAJA::atomicAdd(host_policy {}, acc, value);
748 #endif
749 }
750 
752 template<typename T, typename host_policy>
753 RAJA_INLINE RAJA_HOST_DEVICE T atomicSub(hip_atomic_explicit<host_policy>,
754  T* acc,
755  T value)
756 {
757 #if defined(__HIP_DEVICE_COMPILE__)
758  return detail::hip_atomicSub(acc, value);
759 #else
760  return RAJA::atomicSub(host_policy {}, acc, value);
761 #endif
762 }
763 
765 template<typename T, typename host_policy>
766 RAJA_INLINE RAJA_HOST_DEVICE T atomicMin(hip_atomic_explicit<host_policy>,
767  T* acc,
768  T value)
769 {
770 #if defined(__HIP_DEVICE_COMPILE__)
771  return detail::hip_atomicMin(acc, value);
772 #else
773  return RAJA::atomicMin(host_policy {}, acc, value);
774 #endif
775 }
776 
778 template<typename T, typename host_policy>
779 RAJA_INLINE RAJA_HOST_DEVICE T atomicMax(hip_atomic_explicit<host_policy>,
780  T* acc,
781  T value)
782 {
783 #if defined(__HIP_DEVICE_COMPILE__)
784  return detail::hip_atomicMax(acc, value);
785 #else
786  return RAJA::atomicMax(host_policy {}, acc, value);
787 #endif
788 }
789 
791 template<typename T, typename host_policy>
792 RAJA_INLINE RAJA_HOST_DEVICE T atomicInc(hip_atomic_explicit<host_policy>,
793  T* acc,
794  T value)
795 {
796 #if defined(__HIP_DEVICE_COMPILE__)
797  return detail::hip_atomicInc(acc, value);
798 #else
799  return RAJA::atomicInc(host_policy {}, acc, value);
800 #endif
801 }
802 
804 template<typename T, typename host_policy>
805 RAJA_INLINE RAJA_HOST_DEVICE T atomicInc(hip_atomic_explicit<host_policy>,
806  T* acc)
807 {
808 #if defined(__HIP_DEVICE_COMPILE__)
809  return detail::hip_atomicInc(acc);
810 #else
811  return RAJA::atomicInc(host_policy {}, acc);
812 #endif
813 }
814 
816 template<typename T, typename host_policy>
817 RAJA_INLINE RAJA_HOST_DEVICE T atomicDec(hip_atomic_explicit<host_policy>,
818  T* acc,
819  T value)
820 {
821 #if defined(__HIP_DEVICE_COMPILE__)
822  return detail::hip_atomicDec(acc, value);
823 #else
824  return RAJA::atomicDec(host_policy {}, acc, value);
825 #endif
826 }
827 
829 template<typename T, typename host_policy>
830 RAJA_INLINE RAJA_HOST_DEVICE T atomicDec(hip_atomic_explicit<host_policy>,
831  T* acc)
832 {
833 #if defined(__HIP_DEVICE_COMPILE__)
834  return detail::hip_atomicDec(acc);
835 #else
836  return RAJA::atomicDec(host_policy {}, acc);
837 #endif
838 }
839 
841 template<typename T, typename host_policy>
842 RAJA_INLINE RAJA_HOST_DEVICE T atomicAnd(hip_atomic_explicit<host_policy>,
843  T* acc,
844  T value)
845 {
846 #if defined(__HIP_DEVICE_COMPILE__)
847  return detail::hip_atomicAnd(acc, value);
848 #else
849  return RAJA::atomicAnd(host_policy {}, acc, value);
850 #endif
851 }
852 
854 template<typename T, typename host_policy>
855 RAJA_INLINE RAJA_HOST_DEVICE T atomicOr(hip_atomic_explicit<host_policy>,
856  T* acc,
857  T value)
858 {
859 #if defined(__HIP_DEVICE_COMPILE__)
860  return detail::hip_atomicOr(acc, value);
861 #else
862  return RAJA::atomicOr(host_policy {}, acc, value);
863 #endif
864 }
865 
867 template<typename T, typename host_policy>
868 RAJA_INLINE RAJA_HOST_DEVICE T atomicXor(hip_atomic_explicit<host_policy>,
869  T* acc,
870  T value)
871 {
872 #if defined(__HIP_DEVICE_COMPILE__)
873  return detail::hip_atomicXor(acc, value);
874 #else
875  return RAJA::atomicXor(host_policy {}, acc, value);
876 #endif
877 }
878 
880 template<typename T, typename host_policy>
881 RAJA_INLINE RAJA_HOST_DEVICE T atomicExchange(hip_atomic_explicit<host_policy>,
882  T* acc,
883  T value)
884 {
885 #if defined(__HIP_DEVICE_COMPILE__)
886  return detail::hip_atomicExchange(acc, value);
887 #else
888  return RAJA::atomicExchange(host_policy {}, acc, value);
889 #endif
890 }
891 
893 template<typename T, typename host_policy>
894 RAJA_INLINE RAJA_HOST_DEVICE T
895 atomicCAS(hip_atomic_explicit<host_policy>, T* acc, T compare, T value)
896 {
897 #if defined(__HIP_DEVICE_COMPILE__)
898  return detail::hip_atomicCAS(acc, compare, value);
899 #else
900  return RAJA::atomicCAS(host_policy {}, acc, compare, value);
901 #endif
902 }
903 
904 } // namespace RAJA
905 
906 
907 #endif // RAJA_ENABLE_HIP
908 #endif // guard
Header file for enable_if helpers.
Header file for RAJA operator definitions.
Header file for reinterpreting type conversions.
RAJA header file defining automatic and builtin atomic operations.
Header file for common RAJA internal macro definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
#define RAJA_SUPPRESS_HD_WARN
Definition: macros.hpp:68
std::enable_if_t< is_any_of< T, TypeList >::value, T > enable_if_is_any_of
Definition: EnableIf.hpp:49
std::enable_if_t<::RAJA::concepts::negate< is_any_of< T, TypeList > >::value, T > enable_if_is_none_of
Definition: EnableIf.hpp:54
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicAnd(T *acc, T value)
Atomic bitwise AND equivalent to (*acc) = (*acc) & value This only works with integral data types.
Definition: atomic.hpp:224
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicCAS(seq_atomic, T *acc, T compare, T value)
Definition: atomic.hpp:154
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicOr(T *acc, T value)
Atomic bitwise OR equivalent to (*acc) = (*acc) | value This only works with integral data types.
Definition: atomic.hpp:240
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicMax(seq_atomic, T *acc, T value)
Definition: atomic.hpp:73
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicLoad(T *acc)
Atomic load.
Definition: atomic.hpp:92
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicDec(T *acc)
Atomic decrement.
Definition: atomic.hpp:195
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicAdd(T *acc, T value)
Atomic add.
Definition: atomic.hpp:117
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicSub(seq_atomic, T *acc, T value)
Definition: atomic.hpp:55
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicXor(T *acc, T value)
Atomic bitwise XOR equivalent to (*acc) = (*acc) ^ value This only works with integral data types.
Definition: atomic.hpp:256
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicXor(seq_atomic, T *acc, T value)
Definition: atomic.hpp:136
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE void atomicStore(T *acc, T value)
Atomic store.
Definition: atomic.hpp:104
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicAnd(seq_atomic, T *acc, T value)
Definition: atomic.hpp:118
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicMax(T *acc, T value)
Atomic maximum equivalent to (*acc) = std::max(*acc, value)
Definition: atomic.hpp:156
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicCAS(T *acc, T compare, T value)
Atomic compare and swap.
Definition: atomic.hpp:286
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicInc(T *acc)
Atomic increment.
Definition: atomic.hpp:168
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicAdd(seq_atomic, T *acc, T value)
Definition: atomic.hpp:46
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicMin(T *acc, T value)
Atomic minimum equivalent to (*acc) = std::min(*acc, value)
Definition: atomic.hpp:143
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicMin(seq_atomic, T *acc, T value)
Definition: atomic.hpp:64
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicSub(T *acc, T value)
Atomic subtract.
Definition: atomic.hpp:130
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE T atomicOr(seq_atomic, T *acc, T value)
Definition: atomic.hpp:127
RAJA_SUPPRESS_HD_WARN RAJA_INLINE RAJA_HOST_DEVICE T atomicExchange(T *acc, T value)
Atomic value exchange.
Definition: atomic.hpp:271
RAJA header file defining OpenMP atomic operations.
RAJA header file defining sequential atomic operations.