DASH  0.3.0
List.h
1 #ifndef DASH__LIST_H__
2 #define DASH__LIST_H__
3 
4 #include <dash/Types.h>
5 #include <dash/GlobRef.h>
6 #include <dash/Team.h>
7 #include <dash/Exception.h>
8 #include <dash/memory/GlobHeapMem.h>
9 #include <dash/Allocator.h>
10 #include <dash/Array.h>
11 #include <dash/Meta.h>
12 
13 #include <dash/list/ListRef.h>
14 #include <dash/list/LocalListRef.h>
15 #include <dash/list/GlobListIter.h>
16 #include <dash/list/internal/ListTypes.h>
17 
18 #include <iterator>
19 #include <limits>
20 #include <vector>
21 
22 namespace dash {
23 
168 template <
170  typename ElementType,
172  typename LocalMemorySpace = dash::HostSpace>
173 class List {
174  static_assert(
176  "Type not supported for DASH containers");
177 
178  template<typename T_, class A_>
179  friend class LocalListRef;
180 
182 private:
183  typedef List<ElementType, LocalMemorySpace> self_t;
184 
185  typedef internal::ListNode<ElementType> node_type;
186 
187  typedef dash::Array<
189  int,
190  dash::CSRPattern<1, dash::ROW_MAJOR, int> >
191  local_sizes_map;
192 
193  using glob_mem_type = dash::GlobHeapMem<
194  node_type,
195  LocalMemorySpace,
198 
200 public:
201  typedef ElementType value_type;
202  typedef typename dash::default_index_t index_type;
203  typedef typename dash::default_size_t size_type;
204 
207 
208  typedef typename glob_mem_type::local_pointer
210  typedef typename glob_mem_type::const_local_pointer
212 
214 public:
215  typedef index_type difference_type;
216 
219 
220  typedef std::reverse_iterator< iterator> reverse_iterator;
221  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
222 
225 
226  typedef value_type & local_reference;
227  typedef const value_type & const_local_reference;
228 
229  //TODO: add pointer traits to handle this
232 
233  // TODO: define ListLocalIter to dereference node iterators
234  typedef local_node_iterator local_iterator;
235  typedef const_local_node_iterator const_local_iterator;
236 
237 public:
239  local_type local;
240 
241 private:
243  dash::Team * _team
244  = nullptr;
246  team_unit_t _myid;
248  glob_mem_type * _globmem
249  = nullptr;
251  iterator _begin;
253  iterator _end;
255  size_type _remote_size
256  = 0;
258  local_iterator _lbegin;
260  local_iterator _lend;
262  node_type _nil_node;
264  local_sizes_map _local_sizes;
268  size_type _local_buffer_size
269  = 4096 / sizeof(value_type);
270 
271 public:
278  explicit List(
279  Team & team = dash::Team::Null())
280  : local(this),
281  _team(&team),
282  _myid(team.myid())
283  {
284  DASH_LOG_TRACE("List() >", "default constructor");
285  }
286 
291  explicit List(
292  size_type nelem = 0,
293  Team & team = dash::Team::All())
294  : local(this),
295  _team(&team),
296  _myid(team.myid())
297  {
298  DASH_LOG_TRACE("List(nelem,team)", "nelem:", nelem);
299  if (_team->size() > 0) {
300  _local_sizes.allocate(team.size(), dash::BLOCKED, team);
301  _local_sizes.local[0] = 0;
302  }
303  allocate(nelem);
304  barrier();
305  DASH_LOG_TRACE("List(nelem,team) >");
306  }
307 
312  List(size_type nelem, size_type nlbuf, Team& team = dash::Team::All())
313  : local(this)
314  , _team(&team)
315  , _myid(team.myid())
316  , _local_buffer_size(nlbuf)
317  {
318  DASH_LOG_TRACE("List(nelem,nlbuf,team)",
319  "nelem:", nelem, "nlbuf:", nlbuf);
320  if (_team->size() > 0) {
321  _local_sizes.allocate(team.size(), dash::BLOCKED, team);
322  _local_sizes.local[0] = 0;
323  }
324  allocate(nelem);
325  barrier();
326  DASH_LOG_TRACE("List(nelem,nlbuf,team) >");
327  }
328 
334  {
335  DASH_LOG_TRACE_VAR("List.~List()", this);
336  deallocate();
337  DASH_LOG_TRACE_VAR("List.~List >", this);
338  }
339 
353  void push_back(const value_type & element)
354  {
355  }
356 
361  void pop_back()
362  {
363  }
364 
368  reference back()
369  {
370  }
371 
385  void push_front(const value_type & value)
386  {
387  }
388 
393  void pop_front()
394  {
395  }
396 
400  reference front()
401  {
402  }
403 
407  iterator begin() noexcept
408  {
409  return _begin;
410  }
411 
415  constexpr const_iterator begin() const noexcept
416  {
417  return _begin;
418  }
419 
423  iterator end() noexcept
424  {
425  return _end;
426  }
427 
431  constexpr const_iterator end() const noexcept
432  {
433  return _end;
434  }
435 
439  local_iterator lbegin() noexcept
440  {
441  return _lbegin;
442  }
443 
447  constexpr const_local_iterator lbegin() const noexcept
448  {
449  return _lbegin;
450  }
451 
455  local_iterator lend() noexcept
456  {
457  return _lend;
458  }
459 
463  constexpr const_local_iterator lend() const noexcept
464  {
465  return _lend;
466  }
467 
473  constexpr size_type max_size() const noexcept
474  {
475  return std::numeric_limits<index_type>::max();
476  }
477 
483  constexpr size_type size() const noexcept
484  {
485  return _remote_size + _local_sizes.local[0];
486  }
487 
493  void resize(size_t num_elements)
494  {
495  }
496 
503  constexpr size_type capacity() const noexcept
504  {
505  return _globmem->size();
506  }
507 
515  inline iterator erase(const_iterator position)
516  {
517  return _begin;
518  }
519 
527  inline iterator erase(const_iterator first, const_iterator last)
528  {
529  return _end;
530  }
531 
538  constexpr Team & team() const noexcept
539  {
540  return *_team;
541  }
542 
549  constexpr size_type lsize() const noexcept
550  {
551  return _local_sizes.local[0];
552  }
553 
560  constexpr size_type lcapacity() const noexcept
561  {
562  return _globmem != nullptr
563  ? _globmem->local_size()
564  : 0;
565  }
566 
572  constexpr bool empty() const noexcept
573  {
574  return size() == 0;
575  }
576 
581  void barrier()
582  {
583  DASH_LOG_TRACE_VAR("List.barrier()", _team);
584  // Apply changes in local memory spaces to global memory space:
585  if (_globmem != nullptr) {
586  _globmem->commit();
587  }
588  // Accumulate local sizes of remote units:
589  _remote_size = 0;
590  for (int u = 0; u < _team->size(); ++u) {
591  if (u != _myid) {
592  size_type local_size_u = _local_sizes[u];
593  _remote_size += local_size_u;
594  }
595  }
596  DASH_LOG_TRACE("List.barrier()", "passed barrier");
597  }
598 
605  bool allocate(
607  size_type nelem = 0,
610  {
611  DASH_LOG_TRACE("List.allocate()");
612  DASH_LOG_TRACE_VAR("List.allocate", nelem);
613  DASH_LOG_TRACE_VAR("List.allocate", _local_buffer_size);
614  if (_team == nullptr || *_team == dash::Team::Null()) {
615  DASH_LOG_TRACE("List.allocate",
616  "initializing with Team::All()");
617  _team = &team;
618  DASH_LOG_TRACE_VAR("List.allocate", team.dart_id());
619  } else {
620  DASH_LOG_TRACE("List.allocate",
621  "initializing with initial team");
622  }
623  DASH_ASSERT_GT(_local_buffer_size, 0, "local buffer size must not be 0");
624  if (nelem < _team->size() * _local_buffer_size) {
625  nelem = _team->size() * _local_buffer_size;
626  }
627  _remote_size = 0;
628  auto lcap = dash::math::div_ceil(nelem, _team->size());
629  // Initialize members:
630  _myid = _team->myid();
631  // Allocate local memory of identical size on every unit:
632  DASH_LOG_TRACE_VAR("List.allocate", lcap);
633 
634  _globmem = new glob_mem_type(lcap, *_team);
635  // Global iterators:
636  _begin = iterator(_globmem, _nil_node);
637  _end = _begin;
638  // Local iterators:
639  _lbegin = _globmem->lbegin();
640  // More efficient than using _globmem->lend as this a second mapping
641  // of the local memory segment:
642  _lend = _lbegin;
643  DASH_LOG_TRACE_VAR("List.allocate", _myid);
644  // Register deallocator of this list instance at the team
645  // instance that has been used to initialized it:
646  _team->register_deallocator(
647  this, std::bind(&List::deallocate, this));
648  // Assure all units are synchronized after allocation, otherwise
649  // other units might start working on the list before allocation
650  // completed at all units:
651  if (dash::is_initialized()) {
652  DASH_LOG_TRACE("List.allocate",
653  "waiting for allocation of all units");
654  _team->barrier();
655  }
656  DASH_LOG_TRACE("List.allocate >", "finished");
657  return true;
658  }
659 
666  void deallocate()
667  {
668  DASH_LOG_TRACE_VAR("List.deallocate()", this);
669  // Assure all units are synchronized before deallocation, otherwise
670  // other units might still be working on the list:
671  if (dash::is_initialized()) {
672  barrier();
673  }
674  // Remove this function from team deallocator list to avoid
675  // double-free:
676  _team->unregister_deallocator(
677  this, std::bind(&List::deallocate, this));
678  // Deallocate list elements:
679  DASH_LOG_TRACE_VAR("List.deallocate()", _globmem);
680  if (_globmem != nullptr) {
681  delete _globmem;
682  _globmem = nullptr;
683  }
684  _local_sizes.local[0] = 0;
685  _remote_size = 0;
686  DASH_LOG_TRACE_VAR("List.deallocate >", this);
687  }
688 
689 };
690 
691 } // namespace dash
692 
693 #endif // DASH__LIST_H__
constexpr const_iterator end() const noexcept
Global pointer to the end of the list.
Definition: List.h:431
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
internal::default_unsigned_index default_size_t
Unsigned integer type used as default for size values.
Definition: Types.h:69
void barrier()
Establish a barrier for all units operating on the list, publishing all changes to all units...
Definition: List.h:581
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
constexpr size_type size() const noexcept
Total number of elements in attached memory space, including size of local unattached memory segments...
Definition: GlobHeapMem.h:422
constexpr size_type size() const noexcept
The size of the list.
Definition: List.h:483
void resize(size_t num_elements)
Resizes the list so its capacity is changed to the given number of elements.
Definition: List.h:493
local_iterator lbegin() noexcept
Native pointer to the first local element in the list.
Definition: List.h:439
iterator erase(const_iterator position)
Removes and destroys single element referenced by given iterator from the container, decreasing the container size by 1.
Definition: List.h:515
index_type difference_type
Public types as required by STL list concept.
Definition: List.h:215
void deallocate()
Free global memory allocated by this container instance.
Definition: List.h:666
bool allocate(size_type nelem=0, dash::Team &team=dash::Team::All())
Allocate memory for this container in global memory.
Definition: List.h:605
local_iterator lend() noexcept
Native pointer to the end of the list.
Definition: List.h:455
void push_front(const value_type &value)
Inserts a new element at the beginning of the list, before its current first element.
Definition: List.h:385
constexpr size_type max_size() const noexcept
Maximum number of elements a list container can hold, e.g.
Definition: List.h:473
Returns second operand.
Definition: Operation.h:201
void unregister_deallocator(void *object, Deallocator::dealloc_function dealloc)
Unregister a deallocator function for a team-allocated object.
Definition: Team.h:300
void commit()
Commit changes of local memory region to global memory space.
Definition: GlobHeapMem.h:739
bool is_initialized()
Check whether DASH has been initialized already.
Proxy type referencing a dash::List.
Definition: ListRef.h:43
iterator end() noexcept
Global pointer to the end of the list.
Definition: List.h:423
List(Team &team=dash::Team::Null())
Default constructor, for delayed allocation.
Definition: List.h:278
size_t size() const
The number of units in this team.
Definition: Team.h:498
constexpr size_type capacity() const noexcept
The number of elements that can be held in currently allocated storage of the list.
Definition: List.h:503
local_type local
Local proxy object, allows use in range-based for loops.
Definition: List.h:239
Global memory region with dynamic size.
Definition: GlobHeapMem.h:204
List(size_type nelem, size_type nlbuf, Team &team=dash::Team::All())
Constructor, creates a new constainer instance with the specified initial global container capacity a...
Definition: List.h:312
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
iterator begin() noexcept
Global pointer to the beginning of the list.
Definition: List.h:407
A Team instance specifies a subset of all available units.
Definition: Team.h:41
constexpr const_iterator begin() const noexcept
Global pointer to the beginning of the list.
Definition: List.h:415
constexpr const_local_iterator lend() const noexcept
Native pointer to the end of the list.
Definition: List.h:463
void pop_back()
Removes and destroys the last element in the list, reducing the container size by one...
Definition: List.h:361
all units allocate invdividually in local memory and synchronize in epochs
constexpr size_type lcapacity() const noexcept
The capacity of the local part of the list.
Definition: List.h:560
constexpr const_local_iterator lbegin() const noexcept
Native pointer to the first local element in the list.
Definition: List.h:447
~List()
Destructor, deallocates local and global memory acquired by the container instance.
Definition: List.h:333
Iterator on global buckets.
Definition: GlobHeapMem.h:32
void pop_front()
Removes and destroys the first element in the list, reducing the container size by one...
Definition: List.h:393
void push_back(const value_type &element)
Inserts a new element at the end of the list, after its current last element.
Definition: List.h:353
A distributed array.
Definition: Array.h:89
constexpr size_type local_size() const noexcept
Number of elements in local memory space.
Definition: GlobHeapMem.h:430
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
ElementType value_type
Public types as required by DASH list concept.
Definition: List.h:201
iterator erase(const_iterator first, const_iterator last)
Removes and destroys elements in the given range from the container, decreasing the container size by...
Definition: List.h:527
Type trait indicating whether the specified type is eligible for elements of DASH containers...
Definition: Types.h:236
static Team & Null()
The invariant Team instance representing an undefined team.
Definition: Team.h:229
void register_deallocator(void *object, Deallocator::dealloc_function dealloc)
Register a deallocator function for a team-allocated object.
Definition: Team.h:285
constexpr Team & team() const noexcept
The team containing all units accessing this list.
Definition: List.h:538
constexpr bool empty() const noexcept
Whether the list is empty.
Definition: List.h:572
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
List(size_type nelem=0, Team &team=dash::Team::All())
Constructor, creates a new constainer instance with the specified initial global container capacity a...
Definition: List.h:291
reference front()
Accesses the first element in the list.
Definition: List.h:400
constexpr size_type lsize() const noexcept
The number of elements in the local part of the list.
Definition: List.h:549
local_pointer & lbegin() noexcept
Native pointer of the initial address of the local memory of the unit that initialized this GlobHeapM...
Definition: GlobHeapMem.h:831
dart_team_t dart_id() const
Index of this team relative to global team dash::Team::All().
Definition: Team.h:522
bool allocate(size_type nelem, dash::DistributionSpec< 1 > distribution, dash::Team &team=dash::Team::All())
Delayed allocation of global memory using a one-dimensional distribution spec.
Definition: Array.h:1319
local_type local
Local proxy object, allows use in range-based for loops.
Definition: Array.h:732
reference back()
Accesses the last element in the list.
Definition: List.h:368