DASH  0.3.0
GlobLocalMemoryPool.h
1 #ifndef DASH__MEMORY__GLOB_LOCAL_MEMORY_H__INCLUDED
2 #define DASH__MEMORY__GLOB_LOCAL_MEMORY_H__INCLUDED
3 
4 #include <dash/Exception.h>
5 #include <dash/allocator/AllocationPolicy.h>
6 #include <dash/memory/MemorySpaceBase.h>
7 
8 namespace dash {
9 
11 template <class MSpaceDomainCategory, class MSpaceTypeCategory>
12 inline MemorySpace<MSpaceDomainCategory, MSpaceTypeCategory>*
14 
15 class HostSpace;
16 
17 template <class ElementType, class MemorySpace>
18 class GlobPtr;
19 
20 template <class LMemSpace>
22  memory_domain_global,
23  typename dash::memory_space_traits<
24  LMemSpace>::memory_space_type_category> {
25  static_assert(
26  std::is_same<LMemSpace, dash::HostSpace>::value,
27  "currently we support only dash::HostSpace for local memory "
28  "allocation");
29 
30  static constexpr size_t max_align = alignof(dash::max_align_t);
31 
33 
34  using base_t = MemorySpace<
37 
40 
41 public:
42  // inherit parent typedefs
43  using memory_space_domain_category = memory_domain_global;
44  using memory_space_type_category =
45  typename base_t::memory_space_type_category;
46 
47  using size_type = dash::default_size_t;
48  using index_type = dash::default_index_t;
49  using difference_type = index_type;
50 
54 
55  // We use a polymorhic allocator to obtain memory from the
56  // local memory space
58 
59  using void_pointer = pointer;
61  using local_void_pointer = void*;
62  using const_local_void_pointer = void*;
63 
64 private:
68  typename memory_traits::memory_space_type_category>;
69 
70 public:
71  GlobLocalMemoryPool() = delete;
72 
73  explicit GlobLocalMemoryPool(
74  size_type pool_capacity = 0,
75  dash::Team const& team = dash::Team::All());
76 
78  LMemSpace* r,
79  size_type pool_capacity = 0,
80  dash::Team const& team = dash::Team::All());
81 
82  ~GlobLocalMemoryPool() override;
83 
86 
87  GlobLocalMemoryPool& operator=(const GlobLocalMemoryPool&) = delete;
89 
90  size_type size() const DASH_ASSERT_NOEXCEPT
91  {
92  return m_size;
93  }
94 
95  size_type capacity() const DASH_ASSERT_NOEXCEPT
96  {
97  return m_capacity;
98  }
99 
100  dash::Team const& team() const DASH_ASSERT_NOEXCEPT
101  {
102  return *m_team;
103  }
104 
105  void barrier()
106  {
107  m_team->barrier();
108  }
109 
110  allocator_type get_allocator() const
111  {
112  // We copy construct an allocator based on the underlying resource of this
113  // allocator
114  return allocator_type{m_allocator.resource()};
115  }
116 
117  pointer allocate(size_type nbytes, size_type alignment = max_align)
118  {
119  return do_allocate(nbytes, alignment);
120  }
121  void deallocate(
122  pointer gptr, size_type nbytes, size_type alignment = max_align)
123  {
124  return do_deallocate(gptr, nbytes, alignment);
125  }
126  void release();
127 
131  void flush(pointer gptr) DASH_ASSERT_NOEXCEPT
132  {
133  DASH_ASSERT_MSG(gptr, "cannot flush DART_GPTR_NULL");
134  dart_flush_all(gptr);
135  }
136 
140  void flush(pointer gptr, dash::team_unit_t target) DASH_ASSERT_NOEXCEPT
141  {
142  DASH_ASSERT_MSG(gptr, "cannot flush DART_GPTR_NULL");
143  gptr.unitid(target);
144  dart_flush(gptr);
145  }
146 
150  void flush_local(pointer gptr) DASH_ASSERT_NOEXCEPT
151  {
152  DASH_ASSERT_MSG(gptr, "cannot flush DART_GPTR_NULL");
153  dart_flush_local_all(gptr);
154  }
155 
161  DASH_ASSERT_NOEXCEPT
162  {
163  DASH_ASSERT_MSG(gptr, "cannot flush DART_GPTR_NULL");
164  gptr.unitid(target);
165  dart_flush(gptr);
166  dart_flush_local(gptr);
167  }
168 
169 private:
170  dash::Team const* m_team{};
171  size_type m_size{};
172  size_type m_capacity{};
173  allocator_type m_allocator{};
174  std::vector<std::pair<pointer, size_t>> m_segments;
175 
176 private:
177  // alignment not used: Pools always allocate with alignof(max_align_t)
178  pointer do_allocate(size_type nbytes, size_type /*alignment*/);
179  void do_deallocate(pointer gptr, size_type nbytes, size_type /*alignment*/);
180  void do_segment_free(
181  typename std::vector<std::pair<pointer, size_t>>::iterator it_erase);
182 };
183 
185 //
186 template <class LMemSpace>
188  size_type local_capacity, dash::Team const& team)
189  : GlobLocalMemoryPool(nullptr, local_capacity, team)
190 {
191 }
192 
193 template <class LMemSpace>
195  LMemSpace* r, size_type local_capacity, dash::Team const& team)
196  : m_team(&team)
197  , m_size(0)
198  , m_capacity(
199  local_capacity ? local_capacity
200  : std::numeric_limits<size_type>::max())
201  , m_allocator(
202  r ? r
206 {
207  DASH_LOG_DEBUG("MemorySpace.MemorySpace >");
208 }
209 
210 template <class LMemSpace>
212  GlobLocalMemoryPool&& other)
213 {
214  *this = std::move(other);
215 }
216 
217 template <class LMemSpace>
220 {
221  if (this == &other) {
222  return *this;
223  }
224  // deallocate own memory
225  release();
226  // and swap..
227  m_team = other.m_team;
228  m_size = other.m_size;
229  m_capacity = other.m_capacity;
230  m_allocator = allocator_type{other.m_allocator.resource()};
231  m_segments = std::move(other.m_segments);
232 
233  other.m_segments.clear();
234 
235  return *this;
236 }
237 
238 template <class LMemSpace>
241  size_type nbytes, size_type /*alignment*/)
242 {
243  DASH_LOG_TRACE(
244  "MemorySpace.do_allocate",
245  "allocate memory",
246  "nbytes: ",
247  nbytes,
248  "capacity: ",
249  m_capacity,
250  "size: ",
251  m_size);
252 
253  if ((m_capacity - m_size) < nbytes) {
254  throw std::bad_alloc{};
255  }
256 
257  global_allocation_strategy strategy{};
258 
259  auto gptr = strategy.allocate_segment(
260  static_cast<LocalMemorySpaceBase<
262  m_allocator.resource()),
263  nbytes,
264  max_align);
265 
266  if (!DART_GPTR_ISNULL(gptr)) {
267  m_segments.emplace_back(std::make_pair(pointer{gptr}, nbytes));
268  m_size += nbytes;
269  return m_segments.back().first;
270  }
271  else {
272  return pointer{DART_GPTR_NULL};
273  }
274 }
275 
276 template <class LMemSpace>
278 {
279  DASH_LOG_DEBUG("< MemorySpace.~MemorySpace");
280 
281  release();
282 
283  DASH_LOG_DEBUG("MemorySpace.~MemorySpace >");
284 }
285 
286 template <class LMemSpace>
288  pointer gptr, size_type nbytes, size_type /*alignment*/)
289 {
290  DASH_LOG_DEBUG("< MemorySpace.do_deallocate");
291 
292  auto it_seg = std::find_if(
293  std::begin(m_segments),
294  std::end(m_segments),
295  [gptr](const std::pair<pointer, size_t>& item) {
296  return item.first == gptr;
297  });
298 
299  if (it_seg != std::end(m_segments)) {
300  do_segment_free(it_seg);
301  m_segments.erase(it_seg);
302  m_size -= nbytes;
303  }
304 
305  DASH_LOG_DEBUG("MemorySpace.do_deallocate >");
306 }
307 template <class LMemSpace>
309 {
310  for (auto it = std::begin(m_segments); it != std::end(m_segments); ++it) {
311  do_segment_free(it);
312  }
313 
314  m_segments.clear();
315 }
316 
317 template <class LMemSpace>
319  typename std::vector<std::pair<pointer, size_t>>::iterator it_erase)
320 {
321  if (!dart_initialized() || *m_team == dash::Team::Null() ||
322  !(it_erase->first)) {
323  return;
324  }
325  auto gptr = it_erase->first.dart_gptr();
326 
327  DASH_ASSERT_EQ(
328  gptr.teamid,
330  "local memory allocation works only with dash::Team::All()");
331 
332  global_allocation_strategy strategy{};
333 
334  strategy.deallocate_segment(
335  gptr,
336  static_cast<LocalMemorySpaceBase<
338  m_allocator.resource()),
339  //We do not care about this parameter since local memory allocation
340  //happens only in DART and we do never free this memory in DASH
341  nullptr,
342  it_erase->second,
343  max_align);
344 }
345 
346 } // namespace dash
347 
348 #endif
MemorySpace< MSpaceDomainCategory, MSpaceTypeCategory > * get_default_memory_space()
Forward declarations.
Definition: MemorySpace.h:29
internal::default_unsigned_index default_size_t
Unsigned integer type used as default for size values.
Definition: Types.h:69
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
Definition: Range.h:98
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
void flush_local(pointer gptr, dash::team_unit_t target)
Locally complete all outstanding non-blocking operations to the specified unit.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
bool dart_initialized()
Whether the DASH runtime has been initialized.
void flush(pointer gptr)
Complete all outstanding non-blocking operations to all units.
GlobIter find_if(GlobIter first, GlobIter last, UnaryPredicate predicate)
Returns an iterator to the first element in the range [first,last) that satisfies the predicate p...
Definition: Find.h:104
dart_ret_t dart_flush_local(dart_gptr_t gptr)
Guarantee local completion of all outstanding operations involving a segment on a certain unit...
dart_ret_t dart_flush_all(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on all units.
void flush_local(pointer gptr)
Locally complete all outstanding non-blocking operations to all units.
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
Allocation Policy.
#define DART_GPTR_NULL
A NULL global pointer.
Definition: dart_globmem.h:105
A Team instance specifies a subset of all available units.
Definition: Team.h:41
Collective AllocationPolicy: Implements the mechanisms to allocate symmetrically from the global memo...
#define DART_GPTR_ISNULL(gptr_)
Test for NULL global pointer.
Definition: dart_globmem.h:118
The MemorySpace concept follows the STL std::pmr::memory_resource.
constexpr dart_gptr_t dart_gptr() const DASH_NOEXCEPT
The pointer&#39;s underlying global address.
Definition: GlobPtr.h:203
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
Definition: Types.h:319
Pointer in global memory space with random access arithmetics.
Definition: GlobPtr.h:33
static Team & Null()
The invariant Team instance representing an undefined team.
Definition: Team.h:229
void flush(pointer gptr, dash::team_unit_t target)
Complete all outstanding non-blocking operations to the specified unit.
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
typename MemSpace::memory_space_type_category memory_space_type_category
The underlying memory type (Host, CUDA, HBW, etc.)
dart_ret_t dart_flush_local_all(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on all units.
dart_team_t dart_id() const
Index of this team relative to global team dash::Team::All().
Definition: Team.h:522
dart_ret_t dart_flush(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on a certain unit...