CMS 3D CMS Logo

SimpleVector.h
Go to the documentation of this file.
1 #ifndef HeterogeneousCore_CUDAUtilities_interface_SimpleVector_h
2 #define HeterogeneousCore_CUDAUtilities_interface_SimpleVector_h
3 
4 // author: Felice Pantaleo, CERN, 2018
5 
6 #include <type_traits>
7 #include <utility>
8 
10 
11 namespace cms {
12  namespace cuda {
13 
14  template <class T>
15  struct SimpleVector {
16  constexpr SimpleVector() = default;
17 
18  // ownership of m_data stays within the caller
19  constexpr void construct(int capacity, T *data) {
20  m_size = 0;
22  m_data = data;
23  }
24 
25  inline constexpr int push_back_unsafe(const T &element) {
26  auto previousSize = m_size;
27  m_size++;
28  if (previousSize < m_capacity) {
29  m_data[previousSize] = element;
30  return previousSize;
31  } else {
32  --m_size;
33  return -1;
34  }
35  }
36 
37  template <class... Ts>
38  constexpr int emplace_back_unsafe(Ts &&...args) {
39  auto previousSize = m_size;
40  m_size++;
41  if (previousSize < m_capacity) {
42  (new (&m_data[previousSize]) T(std::forward<Ts>(args)...));
43  return previousSize;
44  } else {
45  --m_size;
46  return -1;
47  }
48  }
49 
50  __device__ inline T &back() { return m_data[m_size - 1]; }
51 
52  __device__ inline const T &back() const {
53  if (m_size > 0) {
54  return m_data[m_size - 1];
55  } else
56  return T(); //undefined behaviour
57  }
58 
59  // thread-safe version of the vector, when used in a CUDA kernel
60  __device__ int push_back(const T &element) {
61  auto previousSize = atomicAdd(&m_size, 1);
62  if (previousSize < m_capacity) {
63  m_data[previousSize] = element;
64  return previousSize;
65  } else {
66  atomicSub(&m_size, 1);
67  return -1;
68  }
69  }
70 
71  template <class... Ts>
72  __device__ int emplace_back(Ts &&...args) {
73  auto previousSize = atomicAdd(&m_size, 1);
74  if (previousSize < m_capacity) {
75  (new (&m_data[previousSize]) T(std::forward<Ts>(args)...));
76  return previousSize;
77  } else {
78  atomicSub(&m_size, 1);
79  return -1;
80  }
81  }
82 
83  // thread safe version of resize
84  __device__ int extend(int size = 1) {
85  auto previousSize = atomicAdd(&m_size, size);
86  if (previousSize < m_capacity) {
87  return previousSize;
88  } else {
90  return -1;
91  }
92  }
93 
94  __device__ int shrink(int size = 1) {
95  auto previousSize = atomicSub(&m_size, size);
96  if (previousSize >= size) {
97  return previousSize - size;
98  } else {
100  return -1;
101  }
102  }
103 
104  inline constexpr bool empty() const { return m_size <= 0; }
105  inline constexpr bool full() const { return m_size >= m_capacity; }
106  inline constexpr T &operator[](int i) { return m_data[i]; }
107  inline constexpr const T &operator[](int i) const { return m_data[i]; }
108  inline constexpr void reset() { m_size = 0; }
109  inline constexpr int size() const { return m_size; }
110  inline constexpr int capacity() const { return m_capacity; }
111  inline constexpr T const *data() const { return m_data; }
112  inline constexpr void resize(int size) { m_size = size; }
113  inline constexpr void set_data(T *data) { m_data = data; }
114 
115  private:
116  int m_size;
118 
120  };
121 
122  // ownership of m_data stays within the caller
123  template <class T>
126  ret.construct(capacity, data);
127  return ret;
128  }
129 
130  // ownership of m_data stays within the caller
131  template <class T>
133  auto ret = new (mem) SimpleVector<T>();
134  ret->construct(capacity, data);
135  return ret;
136  }
137 
138  } // namespace cuda
139 } // namespace cms
140 
141 #endif // HeterogeneousCore_CUDAUtilities_interface_SimpleVector_h
__device__ int shrink(int size=1)
Definition: SimpleVector.h:94
T1 atomicSub(T1 *a, T2 b)
Definition: cudaCompat.h:73
SimpleVector< T > make_SimpleVector(int capacity, T *data)
Definition: SimpleVector.h:124
ret
prodAgent to be discontinued
constexpr void resize(int size)
Definition: SimpleVector.h:112
constexpr bool empty() const
Definition: SimpleVector.h:104
__device__ const T & back() const
Definition: SimpleVector.h:52
__device__ int emplace_back(Ts &&...args)
Definition: SimpleVector.h:72
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type * mem
constexpr T const * data() const
Definition: SimpleVector.h:111
__device__ int push_back(const T &element)
Definition: SimpleVector.h:60
constexpr bool full() const
Definition: SimpleVector.h:105
constexpr int emplace_back_unsafe(Ts &&...args)
Definition: SimpleVector.h:38
__device__ int extend(int size=1)
Definition: SimpleVector.h:84
constexpr int size() const
Definition: SimpleVector.h:109
constexpr int capacity() const
Definition: SimpleVector.h:110
Namespace of DDCMS conversion namespace.
constexpr void reset()
Definition: SimpleVector.h:108
constexpr void set_data(T *data)
Definition: SimpleVector.h:113
constexpr SimpleVector()=default
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
constexpr T & operator[](int i)
Definition: SimpleVector.h:106
constexpr void construct(int capacity, T *data)
Definition: SimpleVector.h:19
constexpr const T & operator[](int i) const
Definition: SimpleVector.h:107
__device__ T & back()
Definition: SimpleVector.h:50
long double T
#define __device__
T1 atomicAdd(T1 *a, T2 b)
Definition: cudaCompat.h:61
constexpr int push_back_unsafe(const T &element)
Definition: SimpleVector.h:25
size d for d tracks hist hist capacity()