CMS 3D CMS Logo

AtomicPairCounter.h
Go to the documentation of this file.
1 #ifndef HeterogeneousCore_AlpakaInterface_interface_AtomicPairCounter_h
2 #define HeterogeneousCore_AlpakaInterface_interface_AtomicPairCounter_h
3 
4 #include <cstdint>
5 
6 #include <alpaka/alpaka.hpp>
7 
8 namespace cms::alpakatools {
9 
11  public:
13 
14  ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter() : counter_{0} {}
15  ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter(uint32_t first, uint32_t second) : counter_{pack(first, second)} {}
17 
20  return *this;
21  }
22 
23  struct Counters {
24  uint32_t first; // in a "One to Many" association is the number of "One"
25  uint32_t second; // in a "One to Many" association is the total number of associations
26  };
27 
28  ALPAKA_FN_HOST_ACC constexpr Counters get() const { return counter_.as_counters; }
29 
30  // atomically add as_counters, and return the previous value
31  template <typename TAcc>
32  ALPAKA_FN_ACC ALPAKA_FN_INLINE constexpr Counters add(const TAcc& acc, Counters c) {
33  Packer value{pack(c.first, c.second)};
34  Packer ret{0};
35  ret.as_doubleword =
37  return ret.as_counters;
38  }
39 
40  // atomically increment first and add i to second, and return the previous value
41  template <typename TAcc>
42  ALPAKA_FN_ACC ALPAKA_FN_INLINE Counters constexpr inc_add(const TAcc& acc, uint32_t i) {
43  return add(acc, {1u, i});
44  }
45 
46  private:
47  union Packer {
50  constexpr Packer(DoubleWord _as_doubleword) : as_doubleword(_as_doubleword) { ; };
51  constexpr Packer(Counters _as_counters) : as_counters(_as_counters) { ; };
52  };
53 
54  // pack two uint32_t values in a DoubleWord (aka uint64_t)
55  // this is needed because in c++17 a union can only be aggregate-initialised to its first type
56  // it can be probably removed with c++20, and replace with a designated initialiser
57  static constexpr DoubleWord pack(uint32_t first, uint32_t second) {
58  Packer ret{0};
59  ret.as_counters = {first, second};
60  return ret.as_doubleword;
61  }
62 
64  };
65 
66 } // namespace cms::alpakatools
67 
68 #endif // HeterogeneousCore_AlpakaInterface_interface_AtomicPairCounter_h
ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter(uint32_t first, uint32_t second)
ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter & operator=(DoubleWord values)
ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter(DoubleWord values)
ret
prodAgent to be discontinued
static constexpr DoubleWord pack(uint32_t first, uint32_t second)
U second(std::pair< T, U > const &p)
ALPAKA_FN_HOST_ACC constexpr AtomicPairCounter()
ALPAKA_FN_ACC ALPAKA_FN_INLINE Counters constexpr inc_add(const TAcc &acc, uint32_t i)
std::vector< Block > Blocks
Definition: Block.h:99
Definition: value.py:1
constexpr Packer(DoubleWord _as_doubleword)
constexpr Packer(Counters _as_counters)
unsigned long long uint64_t
Definition: Time.h:13
ALPAKA_FN_ACC ALPAKA_FN_INLINE constexpr Counters add(const TAcc &acc, Counters c)
T1 atomicAdd(T1 *a, T2 b)
Definition: cudaCompat.h:61