Block-Structured AMR Software Framework
AMReX_ParticleArray.H
Go to the documentation of this file.
1 #ifndef AMREX_PARTICLEARRAY_H_
2 #define AMREX_PARTICLEARRAY_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX.H>
6 #include <AMReX_TypeTraits.H>
7 #include <AMReX_Tuple.H>
8 
9 #include <functional>
10 #include <tuple>
11 #include <type_traits>
12 
13 namespace amrex
14 {
19 enum class DataLayout
20 {
21  AoS = 0,
22  SoA
23 };
24 
28 template <template <typename...> class ContainerType,
29  typename ParticleType,
30  DataLayout DataLayoutTag>
32 
33 template <typename ParticleType, DataLayout DataLayoutTag>
35 
36 template <typename ParticleType, DataLayout DataLayoutTag>
38 
42 template <class T>
43 class ref_wrapper {
44 public:
45  using type = T;
46 
48  ref_wrapper(T& ref) noexcept : _ptr(&ref) {}
49  ref_wrapper(T&&) = delete; // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) // clang-tidy bug
50 
51  ~ref_wrapper () = default;
52  ref_wrapper (const ref_wrapper&) noexcept = default;
53  ref_wrapper (ref_wrapper&&) noexcept = default;
54 
56  ref_wrapper& operator= (T&& a_other) { this->get()=std::move(a_other); return *this; }
57 
58  ref_wrapper& operator= (const ref_wrapper&) noexcept = default;
59  ref_wrapper& operator= (ref_wrapper&&) noexcept = default;
60 
61  [[nodiscard]] AMREX_GPU_HOST_DEVICE
62  operator T& () const noexcept { return *_ptr; }
63 
64  [[nodiscard]] AMREX_GPU_HOST_DEVICE
65  T& get() const noexcept { return *_ptr; }
66 
67 private:
68  T* _ptr;
69 };
70 
75 template <template <typename...> class ContainerType,
76  template<typename...> class ParticleType,
77  typename... Types>
78 struct DataLayoutPolicy<ContainerType, ParticleType<Types...>, DataLayout::AoS>
79 {
80  using container_type = ContainerType<ParticleType<Types...>>;
81  using raw_type = ParticleType<Types...>*;
82  using value_type = ParticleType<Types...>&;
83 
84  static constexpr raw_type get_raw_data (container_type& a_container)
85  {
86  return raw_type(static_cast<ParticleType<Types...>*>(a_container.data()));
87  }
88 
89  static constexpr void resize (container_type& a_container, std::size_t a_size)
90  {
91  a_container.resize(a_size);
92  }
93 
94  template <typename ValueType>
95  static constexpr void push_back (container_type& a_container, ValueType&& a_value)
96  {
97  a_container.push_back(std::forward<ValueType>(a_value));
98  }
99 
100  static constexpr std::size_t size (container_type& a_container)
101  {
102  return a_container.size();
103  }
104 };
105 
109 template <template<typename...> class ParticleType, typename... Types>
110 struct DataLayoutPolicyRaw<ParticleType<Types...>, DataLayout::AoS>
111 {
112  using raw_type = ParticleType<Types...>*;
113  using value_type = ParticleType<Types...>&;
114 
116  static constexpr value_type get (raw_type a_ptr, std::size_t a_index)
117  {
118  return value_type(*static_cast<ParticleType<Types...>*>(&a_ptr[a_index]));
119  }
120 };
121 
128 template <template <typename...> class ContainerType,
129  template<typename...> class ParticleType,
130  typename... Types>
131 struct DataLayoutPolicy<ContainerType, ParticleType<Types...>, DataLayout::SoA> {
132  using container_type = std::tuple<ContainerType<Types>...>;
133  using raw_type = amrex::GpuTuple<Types*...>;
134  using value_type = ParticleType<ref_wrapper<Types>...>;
135 
136  static constexpr raw_type get_raw_data (container_type& a_container)
137  {
138  return get_raw_data_impl(a_container, std::make_index_sequence<sizeof...(Types)>());
139  }
140 
141  static constexpr void resize (container_type& a_container, std::size_t a_size)
142  {
143  resize_impl(a_container, a_size, std::make_index_sequence<sizeof...(Types)>());
144  }
145 
146  template <typename ValueType>
147  static constexpr void push_back (container_type& a_container, ValueType&& a_value)
148  {
149  push_back_impl(a_container, std::forward<ValueType>(a_value),
150  std::make_index_sequence<sizeof...(Types)>());
151  }
152 
153  static constexpr std::size_t size (container_type& a_container)
154  {
155  return std::get<0>(a_container).size();
156  }
157 
158 private:
159 
160  template <std::size_t... Is>
161  static constexpr auto get_raw_data_impl (container_type& a_container,
162  std::index_sequence<Is...>)
163  {
164  return raw_type{static_cast<Types*>(&std::get<Is>(a_container)[0])... };
165  }
166 
167  template <std::size_t... Is>
168  static constexpr void resize_impl (container_type& a_container, std::size_t a_size,
169  std::index_sequence<Is...>)
170  {
171  using expander = int[];
172  (void) expander{ 0, (std::get<Is>(a_container).resize(a_size), 0)... };
173  }
174 
175  template <typename ValueType, std::size_t... Is>
176  static constexpr void push_back_impl(container_type& a_container, ValueType const& a_value,
177  std::index_sequence<Is...>)
178  {
179  using expander = int[];
180  (void) expander{ 0, (std::get<Is>(a_container).push_back(
181  std::get<Is>(a_value)), 0)... };
182  }
183 };
184 
188 template <template<typename...> class ParticleType, typename... Types>
189 struct DataLayoutPolicyRaw<ParticleType<Types...>, DataLayout::SoA> {
190  using raw_type = amrex::GpuTuple<Types*...>;
191  using value_type = ParticleType<ref_wrapper<Types>...>;
192 
194  static constexpr value_type get (raw_type const& a_tuple, std::size_t a_index)
195  {
196  return get_impl(a_tuple, a_index, std::make_index_sequence<sizeof...(Types)>());
197  }
198 
199 private:
200 
201  template <std::size_t... Is>
203  static constexpr auto get_impl (raw_type const& a_tuple, std::size_t a_index,
204  std::index_sequence<Is...>)
205  {
206  return value_type{ref_wrapper<Types>(amrex::get<Is>(a_tuple)[a_index])... };
207  }
208 };
209 
213 template <template <typename ValueType> class ContainerType,
214  typename ParticleType,
215  DataLayout DataLayoutTag>
217 {
220  using value_type = typename policy_type::value_type;
221  using container_type = typename policy_type::container_type;
222 
223  static constexpr auto data_layout = DataLayoutTag;
224 
226 
227  ParticleArray (size_t a_size) { resize(a_size); }
228 
229  template <typename ValueType>
230  void push_back (ValueType&& val)
231  {
232  policy_type::push_back(m_data, std::forward<ValueType>(val));
233  }
234 
235  std::size_t size () { return policy_type::size(m_data); }
236 
237  void resize (size_t a_size) { policy_type::resize(m_data, a_size); }
238 
240  {
241  return accessor_type(size(), policy_type::get_raw_data(m_data));
242  }
243 
244 private:
245 
247 };
248 
253 template <typename ParticleType, DataLayout DataLayoutTag>
255 {
256  // ParticleType: Particle<double, double, double, int, int>
257  // DataLayoutTag: amrex::DataLayout::SoA
258  // value_type: Particle<amrex::ref_wrapper<double>, amrex::ref_wrapper<double>, amrex::ref_wrapper<double>, amrex::ref_wrapper<int>, amrex::ref_wrapper<int> >
259 
261  using value_type = typename policy_type::value_type;
262  using raw_type = typename policy_type::raw_type;
263 
264  static constexpr auto data_layout = DataLayoutTag;
265 
266  ParticleArrayAccessor (std::size_t a_size, raw_type a_data)
267  : m_size(a_size), m_data(a_data)
268  {}
269 
270  [[nodiscard]] AMREX_GPU_HOST_DEVICE
271  value_type operator[] (std::size_t a_index) const { return policy_type::get(m_data, a_index); }
272 
273  [[nodiscard]] AMREX_GPU_HOST_DEVICE
274  std::size_t size () const { return m_size; }
275 
276 private:
277  std::size_t m_size;
279 };
280 }
281 
282 #endif
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
Definition: AMReX_Tuple.H:93
Definition: AMReX_ParticleArray.H:43
AMREX_GPU_HOST_DEVICE T & get() const noexcept
Definition: AMReX_ParticleArray.H:65
AMREX_GPU_HOST_DEVICE ref_wrapper & operator=(T &&a_other)
Definition: AMReX_ParticleArray.H:56
ref_wrapper(ref_wrapper &&) noexcept=default
ref_wrapper(const ref_wrapper &) noexcept=default
~ref_wrapper()=default
ref_wrapper(T &&)=delete
T type
Definition: AMReX_ParticleArray.H:45
T * _ptr
Definition: AMReX_ParticleArray.H:68
AMREX_GPU_HOST_DEVICE ref_wrapper(T &ref) noexcept
Definition: AMReX_ParticleArray.H:48
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
integer version
Definition: AMReX_GpuRange.H:26
constexpr AMREX_GPU_HOST_DEVICE GpuTupleElement< I, GpuTuple< Ts... > >::type & get_impl(detail::gpu_tuple_element< I, typename GpuTupleElement< I, GpuTuple< Ts... > >::type > &te) noexcept
Definition: AMReX_Tuple.H:147
Definition: AMReX_Amr.cpp:49
constexpr AMREX_GPU_HOST_DEVICE GpuTupleElement< I, GpuTuple< Ts... > >::type & get(GpuTuple< Ts... > &tup) noexcept
Definition: AMReX_Tuple.H:179
DataLayout
Definition: AMReX_ParticleArray.H:20
ParticleType< Types... > * raw_type
Definition: AMReX_ParticleArray.H:112
ParticleType< Types... > & value_type
Definition: AMReX_ParticleArray.H:113
static constexpr AMREX_GPU_HOST_DEVICE value_type get(raw_type a_ptr, std::size_t a_index)
Definition: AMReX_ParticleArray.H:116
static constexpr AMREX_GPU_HOST_DEVICE value_type get(raw_type const &a_tuple, std::size_t a_index)
Definition: AMReX_ParticleArray.H:194
static constexpr AMREX_GPU_HOST_DEVICE auto get_impl(raw_type const &a_tuple, std::size_t a_index, std::index_sequence< Is... >)
Definition: AMReX_ParticleArray.H:203
ParticleType< ref_wrapper< Types >... > value_type
Definition: AMReX_ParticleArray.H:191
Definition: AMReX_ParticleArray.H:34
static constexpr void resize(container_type &a_container, std::size_t a_size)
Definition: AMReX_ParticleArray.H:89
static constexpr raw_type get_raw_data(container_type &a_container)
Definition: AMReX_ParticleArray.H:84
static constexpr void push_back(container_type &a_container, ValueType &&a_value)
Definition: AMReX_ParticleArray.H:95
ContainerType< ParticleType< Types... > > container_type
Definition: AMReX_ParticleArray.H:80
ParticleType< Types... > * raw_type
Definition: AMReX_ParticleArray.H:81
static constexpr std::size_t size(container_type &a_container)
Definition: AMReX_ParticleArray.H:100
ParticleType< Types... > & value_type
Definition: AMReX_ParticleArray.H:82
static constexpr void push_back(container_type &a_container, ValueType &&a_value)
Definition: AMReX_ParticleArray.H:147
static constexpr raw_type get_raw_data(container_type &a_container)
Definition: AMReX_ParticleArray.H:136
static constexpr auto get_raw_data_impl(container_type &a_container, std::index_sequence< Is... >)
Definition: AMReX_ParticleArray.H:161
ParticleType< ref_wrapper< Types >... > value_type
Definition: AMReX_ParticleArray.H:134
static constexpr std::size_t size(container_type &a_container)
Definition: AMReX_ParticleArray.H:153
std::tuple< ContainerType< Types >... > container_type
Definition: AMReX_ParticleArray.H:132
static constexpr void resize(container_type &a_container, std::size_t a_size)
Definition: AMReX_ParticleArray.H:141
static constexpr void resize_impl(container_type &a_container, std::size_t a_size, std::index_sequence< Is... >)
Definition: AMReX_ParticleArray.H:168
static constexpr void push_back_impl(container_type &a_container, ValueType const &a_value, std::index_sequence< Is... >)
Definition: AMReX_ParticleArray.H:176
Definition: AMReX_ParticleArray.H:31
Definition: AMReX_ParticleArray.H:255
typename policy_type::raw_type raw_type
Definition: AMReX_ParticleArray.H:262
std::size_t m_size
Definition: AMReX_ParticleArray.H:277
AMREX_GPU_HOST_DEVICE std::size_t size() const
Definition: AMReX_ParticleArray.H:274
AMREX_GPU_HOST_DEVICE value_type operator[](std::size_t a_index) const
Definition: AMReX_ParticleArray.H:271
typename policy_type::value_type value_type
Definition: AMReX_ParticleArray.H:261
raw_type m_data
Definition: AMReX_ParticleArray.H:278
ParticleArrayAccessor(std::size_t a_size, raw_type a_data)
Definition: AMReX_ParticleArray.H:266
static constexpr auto data_layout
Definition: AMReX_ParticleArray.H:264
Definition: AMReX_ParticleArray.H:217
void resize(size_t a_size)
Definition: AMReX_ParticleArray.H:237
container_type m_data
Definition: AMReX_ParticleArray.H:246
std::size_t size()
Definition: AMReX_ParticleArray.H:235
typename policy_type::container_type container_type
Definition: AMReX_ParticleArray.H:221
static constexpr auto data_layout
Definition: AMReX_ParticleArray.H:223
accessor_type get_particle_data()
Definition: AMReX_ParticleArray.H:239
ParticleArray(size_t a_size)
Definition: AMReX_ParticleArray.H:227
ParticleArray()
Definition: AMReX_ParticleArray.H:225
ParticleArrayAccessor< ParticleType, DataLayoutTag > accessor_type
Definition: AMReX_ParticleArray.H:219
typename policy_type::value_type value_type
Definition: AMReX_ParticleArray.H:220
void push_back(ValueType &&val)
Definition: AMReX_ParticleArray.H:230