DASH  0.3.0
Team.h
1 #ifndef TEAM_H_INCLUDED
2 #define TEAM_H_INCLUDED
3 
4 #include <dash/dart/if/dart.h>
5 
6 #include <dash/Init.h>
7 #include <dash/Types.h>
8 #include <dash/Exception.h>
9 
10 #include <dash/util/Locality.h>
11 
12 #include <dash/internal/Logging.h>
13 
14 #include <list>
15 #include <unordered_map>
16 #include <iostream>
17 #include <memory>
18 #include <type_traits>
19 #include <utility>
20 
21 
22 namespace dash {
23 
24 // Forward-declarations
25 class Team;
26 std::ostream & operator<<(
27  std::ostream & os,
28  const Team & team);
29 
41 class Team
42 {
43  template <typename U>
44  friend class Shared;
45  template <typename U, class P, class GM, class Ptr, class Ref >
46  friend class GlobIter;
47  template <typename U>
48  friend class GlobRef;
49  friend std::ostream & operator<<(
50  std::ostream & os,
51  const Team & team);
52 
53 public:
54 
55  typedef struct iterator
56  {
57  int val;
58 
59  iterator(int v) : val(v) {}
60  iterator & operator+=(const iterator & rhs) {
61  val += rhs.val;
62  return *this;
63  }
64 
65  inline iterator & operator++() {
66  return operator+=(1);
67  }
68 
69  inline int operator*() const {
70  return val;
71  }
72 
73  inline operator int() const {
74  return val;
75  }
76  } iterator;
77 
78  inline iterator begin()
79  {
80  return {0};
81  }
82 
83  inline iterator end()
84  {
85  return {static_cast<int>(size())};
86  }
87 
88 public:
89  typedef struct Deallocator
90  {
91  typedef std::function<void(void)> dealloc_function;
92  void * object;
93  dealloc_function deallocator;
94  } Deallocator;
95 
96 private:
101  Team(
102  dart_team_t id,
104  Team * parent = nullptr,
106  size_t pos = 0,
108  size_t nsiblings = 0);
109 
110  bool get_group() const
111  {
112  if (dash::is_initialized() && _group != DART_GROUP_NULL) {
113  DASH_LOG_DEBUG("Team.get_group()");
114  dart_team_get_group(_dartid, &_group);
115  }
116  return _group != DART_GROUP_NULL;
117  }
118 
119 protected:
123  Team(const Team & t) = default;
124 
125 private:
127  Team & operator=(const Team & t) = delete;
128 
129 public:
133  Team(Team && t)
134  : _dartid(t._dartid),
135  _myid(t._myid),
136  _size(t._size),
137  _parent(t._parent),
138  _child(t._child),
139  _position(t._position),
140  _num_siblings(t._num_siblings),
141  _group(t._group),
142  _deallocs(std::move(t._deallocs))
143  {
144  t._parent = nullptr;
145  t._group = nullptr;
146  t._dartid = DART_TEAM_NULL;
147  }
148 
153  {
154  if (this != &t) {
155  // Free existing resources
156  free();
157  // Take ownership of data from source
158  _deallocs = std::move(t._deallocs);
159  std::swap(_parent, t._parent);
160  std::swap(_group, t._group);
161  std::swap(_dartid, t._dartid);
162  _position = t._position;
163  _num_siblings = t._num_siblings;
164  _myid = t._myid;
165  _size = t._size;
166  }
167  return *this;
168  }
169 
174  {
175  DASH_LOG_DEBUG_VAR("Team.~Team()", this);
176 
177  // Do not register static Team instances as static variable _team might
178  // not be initialized at the time of their instantiation, yet:
179  if (DART_TEAM_NULL != _dartid &&
180  DART_TEAM_ALL != _dartid) {
181  Team::unregister_team(this);
182  }
183 
184  if (_group != DART_GROUP_NULL) {
185  if (DART_OK != dart_group_destroy(&_group)) {
186  DASH_LOG_ERROR("dash::Team d'tor", "Failed to destroy DART group!");
187  }
188  }
189 
190  if (_child) {
191  delete(_child);
192  _child = nullptr;
193  }
194 
195  if (_parent) {
196  _parent->_child = nullptr;
197  }
198 
199  free();
200 
201  if (DART_TEAM_NULL != _dartid &&
202  DART_TEAM_ALL != _dartid) {
203  if (DART_OK != dart_team_destroy(&_dartid))
204  {
205  DASH_LOG_ERROR("dash::Team d'tor", "Failed to destroy DART group!");
206  }
207  }
208  }
209 
213  inline static Team & All()
214  {
215  return Team::_team_all;
216  }
217 
221  inline static global_unit_t GlobalUnitID()
222  {
223  return global_unit_t(Team::_team_all.myid());
224  }
225 
229  inline static Team & Null()
230  {
231  return Team::_team_null;
232  }
233 
237  inline static Team & Get(
238  dart_team_t team_id)
239  {
240  if (DART_TEAM_NULL == team_id) {
241  return dash::Team::Null();
242  }
243  if (DART_TEAM_ALL == team_id) {
244  return dash::Team::All();
245  }
246  return *(Team::_teams[team_id]);
247  }
248 
252  static void initialize()
253  {
254  Team::All().init_team();
255  }
256 
261  static void finalize()
262  {
263  DASH_LOG_TRACE("Team::finalize()");
264 
271  while (Team::_teams.size() > 0) {
272  Team *t = Team::_teams.begin()->second;
273  delete t;
274  }
275 
276  Team::All().free();
277  Team::All().reset_team();
278  }
279 
287  void * object,
289  Deallocator::dealloc_function dealloc)
290  {
291  DASH_LOG_DEBUG_VAR("Team.register_deallocator()", object);
292  _deallocs.push_back(Deallocator { object, std::move(dealloc) });
293  }
294 
302  void * object,
304  Deallocator::dealloc_function dealloc)
305  {
306  DASH_LOG_DEBUG_VAR("Team.unregister_deallocator()", object);
307  _deallocs.remove(Deallocator { object, std::move(dealloc) });
308  }
309 
314  void free()
315  {
316  DASH_LOG_DEBUG("Team.free()");
317  std::list<Deallocator>::iterator next = _deallocs.begin();
318  std::list<Deallocator>::iterator dealloc;
319  while ((dealloc = next) != _deallocs.end()) {
320  barrier();
321  // List changes in iterations
322  ++next;
323  DASH_LOG_DEBUG_VAR("Team.free", dealloc->object);
324  (dealloc->deallocator)();
325  }
326  _deallocs.clear();
327  }
328 
334  Team & split(
336  unsigned nParts);
337 
347  dash::util::Locality::Scope scope,
349  unsigned num_parts);
350 
360  dart_locality_scope_t scope,
362  unsigned num_parts)
363  {
364  return locality_split(
365  static_cast<dash::util::Locality::Scope>(
366  scope),
367  num_parts);
368  }
369 
377  inline bool operator==(const Team & rhs) const
378  {
379  return _dartid == rhs._dartid;
380  }
381 
389  inline bool operator!=(const Team & rhs) const
390  {
391  return !(operator == (rhs));
392  }
393 
397  inline bool is_all() const
398  {
399  return operator==(All());
400  }
401 
405  inline bool is_null() const
406  {
407  return operator==(Null());
408  }
409 
414  inline bool is_leaf() const
415  {
416  return _child == nullptr;
417  }
418 
423  inline bool is_root() const
424  {
425  return _parent == nullptr;
426  }
427 
437  bool is_member(global_unit_t global_unit_id) const
438  {
439  if(!get_group()) {
440  return false;
441  }
442  int32_t ismember;
443  DASH_ASSERT_RETURNS(
445  _group,
446  global_unit_id,
447  &ismember),
448  DART_OK);
449  return (0 != ismember);
450  }
451 
452  inline Team & parent()
453  {
454  if(_parent) { return *_parent; }
455  else { return Null(); }
456  }
457 
458  Team & sub(size_t level = 1)
459  {
460  Team * t = this;
461  while (t && level > 0 && !(t->is_leaf())) {
462  t = t->_child;
463  level--;
464  DASH_ASSERT_MSG(t, "node is neither leaf nor has child");
465  }
466  return *t;
467  }
468 
469  Team & bottom()
470  {
471  Team *t = this;
472  while (t && !(t->is_leaf())) {
473  t = t->_child;
474  DASH_ASSERT_MSG(t, "node is neither leaf nor has child");
475  }
476  return *t;
477  }
478 
479  inline void barrier() const
480  {
481  if (!is_null()) {
482  DASH_ASSERT_RETURNS(
483  dart_barrier(_dartid),
484  DART_OK);
485  }
486  }
487 
488  inline team_unit_t myid() const
489  {
490  return _myid;
491  }
492 
498  inline size_t size() const
499  {
500  return _size;
501  }
502 
506  inline size_t position() const
507  {
508  return _position;
509  }
510 
514  inline size_t num_siblings() const
515  {
516  return _num_siblings;
517  }
518 
522  inline dart_team_t dart_id() const
523  {
524  return _dartid;
525  }
526 
530  inline size_t relative_id() const
531  {
532  return _position;
533  }
534 
535  inline team_unit_t relative_id(
537  {
538  team_unit_t luid;
539  DASH_ASSERT_RETURNS(
541  _dartid,
542  global_id,
543  &luid),
544  DART_OK);
545  return luid;
546  }
547 
552  team_unit_t local_id)
553  {
554  global_unit_t g_id;
555  DASH_ASSERT_RETURNS(
557  _dartid,
558  local_id,
559  &g_id),
560  DART_OK);
561  return g_id;
562  }
563 
564 private:
565 
566  void register_team(Team * team)
567  {
568  DASH_LOG_DEBUG("Team.register_team",
569  "team id:", team->_dartid);
570  DASH_ASSERT_RETURNS(
571  dart_team_locality_init(team->_dartid),
572  DART_OK);
573  dash::Team::_teams.insert(
574  std::make_pair(team->_dartid, team));
575  }
576 
577  void unregister_team(Team * team)
578  {
579  DASH_LOG_DEBUG("Team.unregister_team",
580  "team id:", team->_dartid);
581 // if (team->_dartid != DART_TEAM_NULL)
582  {
583  DASH_ASSERT_RETURNS(
584  dart_team_locality_finalize(team->_dartid),
585  DART_OK);
586  dash::Team::_teams.erase(
587  team->_dartid);
588  }
589  }
590 
591  void init_team()
592  {
593  DASH_ASSERT_RETURNS(
594  dart_team_size(_dartid, &_size),
595  DART_OK);
596 
597  DASH_ASSERT_RETURNS(
598  dart_team_myid(_dartid, &_myid),
599  DART_OK);
600  }
601 
602  void reset_team()
603  {
604  _myid = UNDEFINED_TEAM_UNIT_ID;
605  _size = 0;
606  }
607 
608 private:
609 
610  dart_team_t _dartid;
611  mutable team_unit_t _myid = UNDEFINED_TEAM_UNIT_ID;
612  mutable size_t _size = 0;
613  Team * _parent = nullptr;
614  Team * _child = nullptr;
615  size_t _position = 0;
616  size_t _num_siblings = 0;
617  mutable dart_group_t _group = DART_GROUP_NULL;
618 
621  std::list<Deallocator> _deallocs;
622 
623  static std::unordered_map<dart_team_t, Team *> _teams;
624 
625  static Team _team_all;
626  static Team _team_null;
627 
628 }; // class Team
629 
630 bool operator==(
631  const Team::Deallocator & lhs,
632  const Team::Deallocator & rhs);
633 
634 class TeamPtr {
635 
636  std::shared_ptr<Team*> _teamptr;
637 
638 }; // class TeamPtr
639 
640 } // namespace dash
641 
642 namespace std {
643 
644 template<>
645 struct iterator_traits<dash::Team::iterator> {
646 public:
650  typedef random_access_iterator_tag iterator_category;
651 };
652 
653 } // namespace std
654 
655 #endif /* TEAM_H_INCLUDED */
constexpr team_unit_t UNDEFINED_TEAM_UNIT_ID
Invalid local unit ID.
Definition: Types.h:341
bool operator!=(const Team &rhs) const
Inequality comparison operator.
Definition: Team.h:389
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
global_unit_t global_id(team_unit_t local_id)
Global unit id of specified local unit id.
Definition: Team.h:551
struct dart_group_struct * dart_group_t
DART groups are represented by an opaque struct dart_group_struct.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
Definition: Range.h:98
~Team()
Destructor.
Definition: Team.h:173
dart_ret_t dart_team_myid(dart_team_t teamid, dart_team_unit_t *myid)
Return the unit id of the caller in the specified team.
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_team_destroy(dart_team_t *teamid)
Free up resources associated with the specified team.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
bool is_root() const
Whether this Team is a root node in a Team hierarchy, i.e.
Definition: Team.h:423
struct dash::unit_id< dash::global_unit, dart_global_unit_t > global_unit_t
Unit ID to use for global IDs.
Definition: Types.h:332
dart_ret_t dart_team_size(dart_team_t teamid, size_t *size)
Return the size of the specified team.
#define DART_TEAM_ALL
The default team consisting of all units that run the application.
static global_unit_t GlobalUnitID()
The invariant unit ID in dash::Team::All().
Definition: Team.h:221
dart_ret_t dart_team_locality_finalize(dart_team_t team)
Initialize information of the specified team.
Team & locality_split(dart_locality_scope_t scope, unsigned num_parts)
Split this Team&#39;s units into child Team instances at the specified locality scope.
Definition: Team.h:357
static void finalize()
Finalize all teams.
Definition: Team.h:261
void unregister_deallocator(void *object, Deallocator::dealloc_function dealloc)
Unregister a deallocator function for a team-allocated object.
Definition: Team.h:300
Team & locality_split(dash::util::Locality::Scope scope, unsigned num_parts)
Split this Team&#39;s units into child Team instances at the specified locality scope.
dart_ret_t dart_group_ismember(const dart_group_t g, dart_global_unit_t unitid, int32_t *ismember)
Test if a unit is a member of the group.
bool is_initialized()
Check whether DASH has been initialized already.
bool operator==(const Team &rhs) const
Equality comparison operator.
Definition: Team.h:377
size_t size() const
The number of units in this team.
Definition: Team.h:498
dart_ret_t dart_team_get_group(dart_team_t teamid, dart_group_t *group)
Query the group associated with the specified team.
Team(Team &&t)
Move-constructor.
Definition: Team.h:133
Iterator on Partitioned Global Address Space.
Definition: GlobIter.h:45
A Team instance specifies a subset of all available units.
Definition: Team.h:41
bool is_all() const
Whether this Team contains all available units.
Definition: Team.h:397
static void initialize()
Initialize the global team.
Definition: Team.h:252
size_t position() const
Index of this team relative to parent team.
Definition: Team.h:506
dart_ret_t dart_barrier(dart_team_t team)
DART Equivalent to MPI_Barrier.
dart_ret_t dart_team_locality_init(dart_team_t team)
Initialize information of the specified team.
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
bool is_null() const
Whether this Team is empty.
Definition: Team.h:405
Team & operator=(Team &&t)
Move-assignment operator.
Definition: Team.h:152
dart_ret_t dart_group_destroy(dart_group_t *group)
Reclaim resources that might be associated with the group.
int16_t dart_team_t
Data type for storing a team ID.
Definition: dart_types.h:252
static Team & Get(dart_team_t team_id)
Get Team instance by id.
Definition: Team.h:237
static Team & Null()
The invariant Team instance representing an undefined team.
Definition: Team.h:229
dart_ret_t dart_team_unit_g2l(dart_team_t team, dart_global_unit_t globalid, dart_team_unit_t *localid)
Convert from a global to a local unit ID.
void register_deallocator(void *object, Deallocator::dealloc_function dealloc)
Register a deallocator function for a team-allocated object.
Definition: Team.h:285
Shared access to a value in global memory across a team.
Definition: Shared.h:23
Team & split(unsigned nParts)
Split this Team&#39;s units into nParts child Team instances.
void barrier()
A global barrier involving all units.
dart_ret_t dart_team_unit_l2g(dart_team_t team, dart_team_unit_t localid, dart_global_unit_t *globalid)
Convert from a local to a global unit ID.
bool is_member(global_unit_t global_unit_id) const
Whether the group associated with this Team instance contains the unit specified by global id...
Definition: Team.h:437
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
see https://en.cppreference.com/w/cpp/feature_test for recommended feature tests
Definition: cstddef.h:8
bool is_leaf() const
Whether this Team is a leaf node in a Team hierarchy, i.e.
Definition: Team.h:414
void free()
Call registered deallocator functions for all team-allocated objects.
Definition: Team.h:314
size_t num_siblings() const
Number of sibling teams relative to parent team.
Definition: Team.h:514
size_t relative_id() const
Index of this team relative to parent team.
Definition: Team.h:530
dart_team_t dart_id() const
Index of this team relative to global team dash::Team::All().
Definition: Team.h:522
dart_locality_scope_t
Scopes of locality domains.
Definition: dart_types.h:290