RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
ListSegment.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_ListSegment_HPP
21 #define RAJA_ListSegment_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <memory>
26 #include <type_traits>
27 #include <utility>
28 
29 #include "camp/resource.hpp"
30 
31 #include "RAJA/util/concepts.hpp"
32 #include "RAJA/util/macros.hpp"
33 #include "RAJA/util/Span.hpp"
34 #include "RAJA/util/types.hpp"
35 
36 namespace RAJA
37 {
38 
86 template<typename StorageT>
88 {
89 public:
91 
94  using value_type = StorageT;
95 
97  using iterator = StorageT*;
98 
100  using IndexType = StorageT;
101 
103 
105 
122  Index_type length,
123  camp::resources::Resource resource,
124  IndexOwnership owned = Owned)
125  : m_resource(nullptr),
126  m_owned(Unowned),
127  m_data(nullptr),
128  m_size(0)
129  {
130  initIndexData(values, length, resource, owned);
131  }
132 
145  template<typename Container>
146  TypedListSegment(const Container& container,
147  camp::resources::Resource resource)
148  : m_resource(nullptr),
149  m_owned(Unowned),
150  m_data(nullptr),
151  m_size(container.size())
152  {
153  if (m_size > 0)
154  {
155 
156  camp::resources::Resource host_res {camp::resources::Host::get_default()};
157 
158  value_type* tmp = host_res.allocate<value_type>(m_size);
159 
160  auto dest = tmp;
161  auto src = container.begin();
162  auto const end = container.end();
163  while (src != end)
164  {
165  *dest = *src;
166  ++dest;
167  ++src;
168  }
169 
170  m_resource = new camp::resources::Resource(resource);
171  m_data = m_resource->allocate<value_type>(m_size);
172  m_resource->memcpy(m_data, tmp, sizeof(value_type) * m_size);
173  m_resource->wait();
174  m_owned = Owned;
175 
176  host_res.deallocate(tmp);
177  }
178  }
179 
181  TypedListSegment() = delete;
182 
184  // As this may be called from a lambda in a
185  // RAJA method we perform a shallow copy
187  : m_resource(nullptr),
188  m_owned(Unowned),
189  m_data(other.m_data),
190  m_size(other.m_size)
191  {}
192 
194  // As this may be called from a lambda in a
195  // RAJA method we perform a shallow copy
197  {
198  clear();
199  m_resource = nullptr;
200  m_owned = Unowned;
201  m_data = other.m_data;
202  m_size = other.m_size;
203  }
204 
206  // As this may be called from a lambda in a
207  // RAJA method we perform a shallow copy
209  {
210  clear();
211  m_resource = rhs.m_resource;
212  m_owned = rhs.m_owned;
213  m_data = rhs.m_data;
214  m_size = rhs.m_size;
215 
216  rhs.m_resource = nullptr;
217  rhs.m_owned = Unowned;
218  rhs.m_data = nullptr;
219  rhs.m_size = 0;
220  }
221 
224  : m_resource(rhs.m_resource),
225  m_owned(rhs.m_owned),
226  m_data(rhs.m_data),
227  m_size(rhs.m_size)
228  {
229  rhs.m_owned = Unowned;
230  rhs.m_resource = nullptr;
231  rhs.m_size = 0;
232  rhs.m_data = nullptr;
233  }
234 
237 
240  {
241 
242 #if !defined(RAJA_GPU_DEVICE_COMPILE_PASS_ACTIVE)
243  if (m_data != nullptr && m_owned == Owned)
244  {
245  m_resource->deallocate(m_data);
246  delete m_resource;
247  }
248 #endif
249  m_data = nullptr;
250  m_resource = nullptr;
251  m_owned = Unowned;
252  m_size = 0;
253  }
254 
256 
258 
263  RAJA_HOST_DEVICE iterator begin() const { return m_data; }
264 
268  RAJA_HOST_DEVICE iterator end() const { return m_data + m_size; }
269 
273  RAJA_HOST_DEVICE Index_type size() const { return m_size; }
274 
279 
281 
283 
297  RAJA_HOST_DEVICE bool indicesEqual(const value_type* container,
298  Index_type len) const
299  {
300  if (container == m_data) return len == m_size;
301  if (len != m_size || container == nullptr || m_data == nullptr)
302  return false;
303  for (Index_type i = 0; i < m_size; ++i)
304  if (m_data[i] != container[i]) return false;
305  return true;
306  }
307 
317  {
318  return (indicesEqual(other.m_data, other.m_size));
319  }
320 
330  {
331  return (!(*this == other));
332  }
333 
335 
340  {
341  camp::safe_swap(m_resource, other.m_resource);
342  camp::safe_swap(m_data, other.m_data);
343  camp::safe_swap(m_size, other.m_size);
344  camp::safe_swap(m_owned, other.m_owned);
345  }
346 
347 private:
348  //
349  // Initialize segment data based on whether object owns the index data.
350  //
351  void initIndexData(const value_type* container,
352  Index_type len,
353  camp::resources::Resource resource_,
354  IndexOwnership container_own)
355  {
356 
357  // empty list segment
358  if (len <= 0 || container == nullptr)
359  {
360  m_data = nullptr;
361  m_size = 0;
362  m_owned = Unowned;
363  return;
364  }
365 
366  // some non-zero size -- initialize accordingly
367  m_size = len;
368  m_owned = container_own;
369  if (m_owned == Owned)
370  {
371 
372  m_resource = new camp::resources::Resource(resource_);
373 
374  camp::resources::Resource host_res {camp::resources::Host::get_default()};
375 
376  value_type* tmp = host_res.allocate<value_type>(m_size);
377 
378  for (Index_type i = 0; i < m_size; ++i)
379  {
380  tmp[i] = container[i];
381  }
382 
383  m_data = m_resource->allocate<value_type>(m_size);
384  m_resource->memcpy(m_data, tmp, sizeof(value_type) * m_size);
385  m_resource->wait();
386 
387  host_res.deallocate(tmp);
388 
389  return;
390  }
391 
392  // list segment accesses container data directly.
393  // Uh-oh. Using evil const_cast....
394  m_data = const_cast<value_type*>(container);
395  }
396 
397  // Copy of camp resource passed to ctor
398  camp::resources::Resource* m_resource;
399 
400  // Ownership flag to guide data copying/management
401  IndexOwnership m_owned;
402 
403  // Buffer storage for segment index data
404  value_type* RAJA_RESTRICT m_data;
405 
406  // Size of list segment
407  Index_type m_size;
408 };
409 
412 
413 } // namespace RAJA
414 
415 namespace std
416 {
417 
419 template<typename StorageT>
422 {
423  a.swap(b);
424 }
425 } // namespace std
426 
427 #endif // closing endif for header file include guard
Header file for RAJA span constructs.
Definition: ListSegment.hpp:88
RAJA_HOST_DEVICE TypedListSegment(const TypedListSegment &other)
Copy constructor for list segment.
Definition: ListSegment.hpp:186
TypedListSegment()=delete
Disable compiler generated constructor.
RAJA_HOST_DEVICE TypedListSegment(TypedListSegment &&rhs)
Move constructor for list segment.
Definition: ListSegment.hpp:223
RAJA_HOST_DEVICE iterator end() const
Get iterator to the end of this segment.
Definition: ListSegment.hpp:268
RAJA_HOST_DEVICE TypedListSegment & operator=(const TypedListSegment &other)
Copy assignment for list segment.
Definition: ListSegment.hpp:196
RAJA_HOST_DEVICE void clear()
Clear method to be called.
Definition: ListSegment.hpp:239
RAJA_HOST_DEVICE bool operator==(const TypedListSegment &other) const
Compare this segment to another for equality.
Definition: ListSegment.hpp:316
RAJA_HOST_DEVICE void swap(TypedListSegment &other)
Swap this segment with another.
Definition: ListSegment.hpp:339
StorageT * iterator
The underlying terator type.
Definition: ListSegment.hpp:97
StorageT IndexType
Expose underlying index type for consistency with other segment types.
Definition: ListSegment.hpp:100
RAJA_HOST_DEVICE bool indicesEqual(const value_type *container, Index_type len) const
Compare this segment's indices to an array of values.
Definition: ListSegment.hpp:297
TypedListSegment(const value_type *values, Index_type length, camp::resources::Resource resource, IndexOwnership owned=Owned)
Construct a list segment from given array with specified length and use given camp resource to alloca...
Definition: ListSegment.hpp:121
RAJA_HOST_DEVICE IndexOwnership getIndexOwnership() const
Get ownership of index data (Owned/Unowned)
Definition: ListSegment.hpp:278
StorageT value_type
The underlying value type for index storage.
Definition: ListSegment.hpp:94
RAJA_HOST_DEVICE ~TypedListSegment()
List segment destructor.
Definition: ListSegment.hpp:236
TypedListSegment(const Container &container, camp::resources::Resource resource)
Construct a list segment from given container of indices.
Definition: ListSegment.hpp:146
RAJA_HOST_DEVICE iterator begin() const
Get iterator to the beginning of this segment.
Definition: ListSegment.hpp:263
RAJA_HOST_DEVICE bool operator!=(const TypedListSegment &other) const
Compare this segment to another for inequality.
Definition: ListSegment.hpp:329
RAJA_HOST_DEVICE Index_type size() const
Get size of this segment (number of indices)
Definition: ListSegment.hpp:273
RAJA_HOST_DEVICE TypedListSegment & operator=(TypedListSegment &&rhs)
move assignment for list segment
Definition: ListSegment.hpp:208
Header file for RAJA concept definitions.
Header file for common RAJA internal macro definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
Definition: AlignedRangeIndexSetBuilders.cpp:35
IndexOwnership
Definition: types.hpp:218
@ Owned
Definition: types.hpp:220
@ Unowned
Definition: types.hpp:219
std::ptrdiff_t Index_type
Definition: types.hpp:226
Definition: ListSegment.hpp:416
RAJA_INLINE void swap(RAJA::TypedListSegment< StorageT > &a, RAJA::TypedListSegment< StorageT > &b)
Specialization of std::swap for TypedListSegment.
Definition: ListSegment.hpp:420
Header file for RAJA type definitions.