DASH  0.3.0
GlobStaticMem.h
1 #ifndef DASH__MEMORY__GLOB_STATIC_MEMORY_H__INCLUDED
2 #define DASH__MEMORY__GLOB_STATIC_MEMORY_H__INCLUDED
3 
4 #include <algorithm>
5 #include <numeric>
6 
7 #include <dash/Exception.h>
8 #include <dash/allocator/AllocationPolicy.h>
9 #include <dash/memory/MemorySpaceBase.h>
10 #include <dash/internal/Macro.h>
11 
12 #include <cpp17/type_traits.h>
13 
14 // clang-format off
15 
67 // clang-format on
68 
69 namespace dash {
70 
72 template <class MSpaceDomainCategory, class MSpaceTypeCategory>
73 inline MemorySpace<MSpaceDomainCategory, MSpaceTypeCategory>*
75 
87 template <class LMemSpace>
88 class GlobStaticMem : public MemorySpace<
90  memory_domain_global,
92  typename dash::memory_space_traits<
93  LMemSpace>::memory_space_type_category> {
94  static constexpr size_t max_align = alignof(max_align_t);
95 
97 
98  using base_t = MemorySpace<
103 
107  typename memory_traits::memory_space_type_category>;
108 
109 public:
110  using memory_space_domain_category =
111  typename base_t::memory_space_domain_category;
112  using memory_space_type_category =
113  typename base_t::memory_space_type_category;
114 
115  using size_type = dash::default_size_t;
116  using index_type = dash::default_index_t;
117  using difference_type = index_type;
118 
119  using memory_space_allocation_policy = allocation_static;
120  using memory_space_synchronization_policy = synchronization_collective;
122 
124 
127  using local_void_pointer = void*;
128  using const_local_void_pointer = const void*;
129 
130 public:
131  constexpr GlobStaticMem() = default;
132  explicit constexpr GlobStaticMem(dash::Team const& team);
133  GlobStaticMem(LMemSpace* r, dash::Team const& team);
134  ~GlobStaticMem() override = default;
135 
136  GlobStaticMem(const GlobStaticMem&) = delete;
137  GlobStaticMem& operator=(const GlobStaticMem&) = delete;
138 
139  constexpr GlobStaticMem(GlobStaticMem&& other) noexcept {
140  *this = std::move(other);
141  }
142 
143  GlobStaticMem& operator=(GlobStaticMem&&) noexcept = default;
144 
145  constexpr size_type capacity() const noexcept;
146 
147  constexpr size_type capacity(dash::team_unit_t uid) const noexcept
148  {
149  return m_local_sizes.at(uid);
150  }
151 
152  constexpr void_pointer begin() noexcept
153  {
154  return void_pointer(m_begin);
155  }
156 
157  constexpr const_void_pointer begin() const noexcept
158  {
159  return const_void_pointer(m_begin);
160  }
161 
162  constexpr void_pointer end() noexcept
163  {
164  auto soon_to_be_end = m_begin;
165  // reset local offset to 0
166  soon_to_be_end.set_unit(dash::team_unit_t{static_cast<dart_team_unit_t>(m_team->size())});
167 
168  return void_pointer(soon_to_be_end);
169  }
170  constexpr const_void_pointer end() const noexcept
171  {
172  auto soon_to_be_end = m_begin;
173  // reset local offset to 0
174  soon_to_be_end.set_unit(
175  dash::team_unit_t{static_cast<dart_team_unit_t>(m_team->size())});
176 
177  return void_pointer(soon_to_be_end);
178  }
179 
180  void_pointer allocate(size_type nbytes, size_type alignment = max_align)
181  {
182  m_local_sizes.resize(m_team->size());
183  return do_allocate(nbytes, alignment);
184  }
185 
186  void deallocate(
187  void_pointer gptr, size_type nbytes, size_type alignment = max_align)
188  {
189  do_deallocate(gptr, nbytes, alignment);
190  }
191 
192  constexpr dash::Team const& team() const noexcept
193  {
194  return *m_team;
195  }
196 
197  constexpr void barrier() const
198  {
199  m_team->barrier();
200  }
201 
202  allocator_type get_allocator() const
203  {
204  // We copy construct an allocator based on the underlying resource of this
205  // allocator
206  return allocator_type{m_local_allocator.resource()};
207  }
208 
213  constexpr void flush(
215  {
216  if (unit == dash::team_unit_t{}) {
217  dart_flush_all(static_cast<dart_gptr_t>(ptr));
218  }
219  else {
220  auto gptr = static_cast<dart_gptr_t>(ptr);
221  // DASH_ASSERT_EQ(gptr.teamid, m_team->dart_id(), "invalid pointer to
222  // flush");
223  gptr.unitid = unit.id;
224  dart_flush(gptr);
225  }
226  }
227 
231  DASH_CONSTEXPR void flush_local(
233  {
234  if (unit == dash::team_unit_t{}) {
235  dart_flush_local_all(static_cast<dart_gptr_t>(ptr));
236  }
237  else {
238  auto gptr = static_cast<dart_gptr_t>(ptr);
239  DASH_ASSERT_EQ(
240  gptr.teamid, m_team->dart_id(), "invalid pointer to flush");
241  gptr.unitid = unit.id;
242  dart_flush_local(gptr);
243  }
244  }
245 
246 private:
248  dash::Team const* m_team{};
250  allocator_type m_local_allocator{};
252  std::vector<size_type> m_local_sizes{};
254  void_pointer m_begin{nullptr};
255 
256  // global size across all units in bytes
257  mutable size_type m_size{std::numeric_limits<size_type>::max()};
258 
259 private:
260  void_pointer do_allocate(size_type nbytes, size_type alignment);
261 
262  void do_deallocate(
263  void_pointer gptr, size_type nbytes, size_type alignment);
264 };
265 
267 //
268 template <class LMemSpace>
269 inline constexpr GlobStaticMem<LMemSpace>::GlobStaticMem(dash::Team const& team)
270  : GlobStaticMem(nullptr, team)
271 {
272 }
273 
274 template <class LMemSpace>
275 inline GlobStaticMem<LMemSpace>::GlobStaticMem(
276  LMemSpace* r, dash::Team const& team)
277  : m_team(&team)
278  , m_local_allocator(
279  r ? r
282  typename memory_traits::memory_space_type_category>())
283  , m_local_sizes(std::max(team.size(), std::size_t(1)))
284 {
285  DASH_LOG_DEBUG("< MemorySpace.MemorySpace");
286 
287  DASH_LOG_DEBUG_VAR("MemorySpace.MemorySpace", team);
288 
289  DASH_LOG_DEBUG("MemorySpace.MemorySpace >");
290 }
291 
292 template <class LMemSpace>
294 GlobStaticMem<LMemSpace>::do_allocate(size_type nbytes, size_type alignment)
295 {
296  global_allocation_strategy strategy{};
297  auto gptr = strategy.allocate_segment(
298  m_team->dart_id(),
299  static_cast<LocalMemorySpaceBase<
300  typename memory_traits::memory_space_type_category>*>(
301  m_local_allocator.resource()),
302  nbytes,
303  alignment);
304 
305  DASH_ASSERT(!DART_GPTR_ISNULL(gptr));
306  DASH_ASSERT_EQ(m_team->size(), m_local_sizes.size(), "invalid setting");
307 
308  m_begin = static_cast<void_pointer>(gptr);
309 
310  DASH_ASSERT_RETURNS(
312  // source buffer
313  &nbytes,
314  // target buffer
315  m_local_sizes.data(),
316  // nels
317  1,
318  // dart type
320  // dart team
321  m_team->dart_id()),
322  DART_OK);
323 
324  return void_pointer(gptr);
325 }
326 
327 template <class LMemSpace>
329  void_pointer gptr, size_type nbytes, size_type alignment)
330 {
331  DASH_LOG_DEBUG("< MemorySpace.do_deallocate");
332 
333  if (*m_team != dash::Team::Null()) {
334  DASH_ASSERT_RETURNS(dart_barrier(m_team->dart_id()), DART_OK);
335 
336  auto soon_to_be_lbegin = gptr;
337  gptr.set_unit(m_team->myid());
338 
339  auto* lbegin = gptr.local();
340 
341  global_allocation_strategy strategy{};
342  strategy.deallocate_segment(
343  static_cast<dart_gptr_t>(gptr),
344  static_cast<LocalMemorySpaceBase<
345  typename memory_traits::memory_space_type_category>*>(
346  m_local_allocator.resource()),
347  lbegin,
348  nbytes,
349  alignment);
350  }
351 
352  m_begin = void_pointer{};
353  m_size = 0;
354 
355  DASH_LOG_DEBUG("MemorySpace.do_deallocate >");
356 }
357 
358 template <class LMemSpace>
359 constexpr inline typename GlobStaticMem<LMemSpace>::size_type
360 GlobStaticMem<LMemSpace>::capacity() const noexcept
361 {
362  if (m_size == std::numeric_limits<size_type>::max()) {
363  m_size = std::accumulate(
364  std::begin(m_local_sizes),
365  std::end(m_local_sizes),
366  0,
367  std::plus<size_type>());
368  }
369  return m_size;
370 }
371 
372 } // namespace dash
373 
374 #endif
DASH_CONSTEXPR void flush_local(void_pointer ptr, dash::team_unit_t unit=dash::team_unit_t{}) const
Locally complete all outstanding non-blocking operations to all units.
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
value_type * local()
Conversion to local pointer.
Definition: GlobPtr.h:405
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
Signals success.
Definition: dart_types.h:33
dart_ret_t dart_allgather(const void *sendbuf, void *recvbuf, size_t nelem, dart_datatype_t dtype, dart_team_t team)
DART Equivalent to MPI allgather.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
Global memory with address space of static size.
Definition: GlobStaticMem.h:88
constexpr void flush(void_pointer ptr, dash::team_unit_t unit=dash::team_unit_t{}) const
Complete all outstanding non-blocking operations to either all units or a specified unit...
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.
size_t size() const
The number of units in this team.
Definition: Team.h:498
Data type for storing a unit ID relative to a team.
Definition: dart_types.h:180
void set_unit(team_unit_t unit_id) DASH_NOEXCEPT
Set the global pointer&#39;s associated unit.
Definition: GlobPtr.h:432
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
Allocation Policy.
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...
DART Global pointer type.
Definition: dart_globmem.h:77
dart_ret_t dart_barrier(dart_team_t team)
DART Equivalent to MPI_Barrier.
#define DART_GPTR_ISNULL(gptr_)
Test for NULL global pointer.
Definition: dart_globmem.h:118
Type trait for mapping to DART data types.
Definition: Types.h:96
The MemorySpace concept follows the STL std::pmr::memory_resource.
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
static Team & Null()
The invariant Team instance representing an undefined team.
Definition: Team.h:229
Synchronization Policy.
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...