DASH  0.3.0
Array.h
1 #ifndef ARRAY_H_INCLUDED
2 #define ARRAY_H_INCLUDED
3 
4 #include <dash/Cartesian.h>
5 #include <dash/Dimensional.h>
6 #include <dash/Exception.h>
7 #include <dash/GlobRef.h>
8 #include <dash/GlobAsyncRef.h>
9 #include <dash/HView.h>
10 #include <dash/Meta.h>
11 #include <dash/Team.h>
12 #include <dash/Types.h>
13 
14 #include <dash/allocator/GlobalAllocator.h>
15 #include <dash/iterator/GlobIter.h>
16 #include <dash/memory/MemorySpace.h>
17 #include <dash/memory/UniquePtr.h>
18 #include <dash/pattern/BlockPattern1D.h>
19 
20 #include <iterator>
21 #include <initializer_list>
22 #include <type_traits>
23 
81 namespace dash {
82 
83 // forward declaration
84 template<
85  typename ElementType,
86  typename IndexType,
87  class PatternType,
88  class LocalMemSpaceT >
89 class Array;
90 
100 template<
101  typename T,
102  typename IndexType,
103  class PatternType,
104  typename LocalMemSpaceT>
106 {
107 private:
108  static const dim_t NumDimensions = 1;
109 
111  self_t;
113  Array_t;
115  ViewSpec_t;
116  typedef std::array<typename PatternType::size_type, NumDimensions>
117  Extents_t;
118 
119 public:
120  template <typename T_, typename I_, typename P_,typename M_>
121  friend class LocalArrayRef;
122 
123 public:
124  typedef T value_type;
125 
126  typedef typename std::make_unsigned<IndexType>::type size_type;
127  typedef IndexType index_type;
128 
129  typedef IndexType difference_type;
130 
131  typedef T & reference;
132  typedef const T & const_reference;
133 
134  typedef T * pointer;
135  typedef const T * const_pointer;
136 
137  typedef T * iterator;
138  typedef const T * const_iterator;
139 
140 public:
143  typedef self_t local_type;
144  typedef PatternType pattern_type;
145 
146 public:
147  typedef std::integral_constant<dim_t, 1>
148  rank;
149 
150  static constexpr dim_t ndim() {
151  return 1;
152  }
153 
154 public:
159  const Array_t * array)
160  : _array(array)
161  { }
162 
165  const Array_t * array,
167  const ViewSpec_t & viewspec)
168  : _array(array),
169  _viewspec(viewspec)
170  { }
171 
172  LocalArrayRef(const self_t &) = default;
173  LocalArrayRef(self_t &&) = default;
174 
175  self_t & operator=(const self_t &) = default;
176  self_t & operator=(self_t &&) = default;
177 
181  constexpr const_iterator begin() const noexcept {
182  return _array->m_lbegin;
183  }
184 
188  inline iterator begin() noexcept {
189  return _array->m_lbegin;
190  }
191 
195  constexpr const_iterator end() const noexcept {
196  return _array->m_lend;
197  }
198 
202  inline iterator end() noexcept {
203  return _array->m_lend;
204  }
205 
209  constexpr size_type size() const noexcept {
210  return end() - begin();
211  }
212 
216  constexpr const_reference operator[](const size_type n) const {
217  return (_array->m_lbegin)[n];
218  }
219 
223  inline reference operator[](const size_type n) {
224  return (_array->m_lbegin)[n];
225  }
226 
232  constexpr bool is_local(
234  index_type local_index) const {
235  return true;
236  }
237 
241  constexpr self_t block(index_type block_lindex) const
242  {
243  return self_t(_array, pattern().local_block(block_lindex));
244  }
245 
249  constexpr const PatternType & pattern() const noexcept {
250  return _array->pattern();
251  }
252 
253 private:
255  const Array_t * _array;
257  ViewSpec_t _viewspec;
258 };
259 
260 #ifndef DOXYGEN
261 
262 template<
263  typename T,
264  typename IndexType,
265  class PatternType,
266  typename LocalMemSpaceT>
267 class AsyncArrayRef
268 {
269 private:
270  typedef AsyncArrayRef<T, IndexType, PatternType, LocalMemSpaceT>
271  self_t;
272 
273 public:
274  template <typename T_, typename I_, typename P_, typename M_>
275  friend class AsyncArrayRef;
276 
277 public:
278  typedef T value_type;
279  typedef typename std::make_unsigned<IndexType>::type size_type;
280  typedef IndexType difference_type;
281 
282  typedef T & reference;
283  typedef const T & const_reference;
284 
285  typedef T * iterator;
286  typedef const T * const_iterator;
287 
288  typedef T * pointer;
289  typedef const T * const_pointer;
290 
291  typedef GlobAsyncRef<T> async_reference;
292  typedef typename GlobAsyncRef<T>::const_type const_async_reference;
293 
294 public:
295  typedef std::integral_constant<dim_t, 1>
296  rank;
297 
298  static constexpr dim_t ndim() {
299  return 1;
300  }
301 
302 private:
304 
305 public:
309  AsyncArrayRef(
311  : _array(array) {
312  }
313 
314  AsyncArrayRef(const self_t &) = default;
315  AsyncArrayRef(self_t &&) = default;
316 
317  self_t & operator=(const self_t &) = default;
318  self_t & operator=(self_t &&) = default;
319 
320 
326  constexpr const_iterator begin() const noexcept {
327  return _array->m_begin;
328  }
329 
335  inline iterator begin() noexcept {
336  return _array->m_begin;
337  }
338 
344  constexpr const_iterator end() const noexcept {
345  return _array->m_end;
346  }
347 
353  inline iterator end() noexcept {
354  return _array->m_end;
355  }
356 
360  constexpr size_type size() const noexcept {
361  return _array->size();
362  }
363 
367  constexpr const_async_reference operator[](const size_type n) const {
368  return const_async_reference(
369  (*(_array->begin() + n)).dart_gptr());
370  }
371 
375  async_reference operator[](const size_type n) {
376  return async_reference(
377  (*(_array->begin() + n)).dart_gptr());
378  }
379 
384  inline void flush() const {
385  _array->flush();
386  }
387 
392  inline void flush(dash::team_unit_t target) const {
393  _array->flush(target);
394  }
395 
400  inline void flush_local() const {
401  _array->flush_local();
402  }
403 
408  inline void flush_local(dash::team_unit_t target) const {
409  _array->flush_local(target);
410  }
411 
412 };
413 
414 #endif // DOXYGEN
415 
422 template<
423  typename T,
424  class PatternT,
425  typename MSpaceC>
427 {
428  public:
429  typedef typename PatternT::index_type index_type;
430 
431  private:
433  ViewSpec<1, index_type> _viewspec;
434 };
435 
442 template<
443  typename ElementType,
444  typename IndexType,
445  class PatternType,
446  typename LocalMemSpaceT>
447 class ArrayRef
448 {
449 private:
450  static const dim_t NumDimensions = 1;
451 
453  self_t;
455  Array_t;
457  ViewSpec_t;
458  typedef std::array<typename PatternType::size_type, NumDimensions>
459  Extents_t;
460 
462 public:
463  typedef ElementType value_type;
464  typedef IndexType index_type;
465  typedef typename std::make_unsigned<IndexType>::type size_type;
466  typedef typename std::make_unsigned<IndexType>::type difference_type;
467 
469  iterator;
470 
471  typedef GlobIter<
472  const value_type,
473  PatternType,
474  typename Array_t::memory_type>
476 
477  typedef std::reverse_iterator<iterator> reverse_iterator;
478  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
479 
482 
483  typedef iterator pointer;
484  typedef const_iterator const_pointer;
485 
487 public:
489  typedef PatternType
491  typedef self_t
492  view_type;
494  local_type;
495  typedef AsyncArrayRef<value_type, IndexType, PatternType, LocalMemSpaceT>
496  async_type;
497 
498 public:
499  typedef std::integral_constant<dim_t, 1>
500  rank;
501 
502  static constexpr dim_t ndim() {
503  return 1;
504  }
505 
506 public:
509  const Array_t * array,
511  const ViewSpec_t & viewspec)
512  : _arr(array),
513  _viewspec(viewspec),
514  _begin(array->begin() + _viewspec.offsets()[0]),
515  _end(array->begin() + _viewspec.offsets()[0] + _viewspec.extents()[0]),
516  _size(_viewspec.size())
517  { }
518 
519 public:
520  constexpr Team & team() const {
521  return _arr->team();
522  }
523 
524  constexpr size_type size() const noexcept {
525  return _size;
526  }
527 
528  constexpr size_type local_size() const noexcept;
529  constexpr size_type local_capacity() const noexcept;
530 
531  constexpr size_type extent(dim_t dim) const noexcept {
532  return _viewspec.extents()[dim];
533  }
534  constexpr Extents_t extents() const noexcept {
535  return _viewspec.extents();
536  }
537  constexpr bool empty() const noexcept {
538  return _size == 0;
539  }
540 
541  inline void barrier() const;
542 
543  constexpr const_pointer data() const noexcept {
544  return _begin;
545  }
546  inline iterator begin() noexcept {
547  return _begin;
548  }
549  constexpr const_iterator begin() const noexcept {
550  return _begin;
551  }
552  inline iterator end() noexcept {
553  return _end;
554  }
555  constexpr const_iterator end() const noexcept {
556  return _end;
557  }
559  inline local_type sub_local() noexcept;
561  constexpr ElementType * lbegin() const noexcept;
563  constexpr ElementType * lend() const noexcept;
564 
565  reference operator[](
567  size_type global_index)
568  {
569  DASH_LOG_TRACE("ArrayRef.[]=", global_index);
570  return _arr->_begin[global_index];
571  }
572 
573  constexpr const_reference operator[](
575  size_type global_index) const
576  {
577  return _arr->_begin[global_index];
578  }
579 
580  reference at(
582  size_type global_pos)
583  {
584  if (global_pos >= size()) {
585  DASH_THROW(
587  "Position " << global_pos
588  << " is out of range " << size()
589  << " in ArrayRef.at()" );
590  }
591  return _arr->_begin[global_pos];
592  }
593 
594  const_reference at(
596  size_type global_pos) const
597  {
598  if (global_pos >= size()) {
599  DASH_THROW(
601  "Position " << global_pos
602  << " is out of range " << size()
603  << " in ArrayRef.at()" );
604  }
605  return _arr->_begin[global_pos];
606  }
607 
611  constexpr const PatternType & pattern() const {
612  return _arr->pattern();
613  }
614 
615 private:
617  const Array_t * const _arr;
619  ViewSpec_t _viewspec;
621  iterator _begin;
623  iterator _end;
625  size_type _size;
626 }; // class ArrayRef
627 
639 template <
640  typename ElementType,
641  typename IndexType = dash::default_index_t,
645  class PatternType = BlockPattern<1, ROW_MAJOR, IndexType>,
646  typename LocalMemSpaceT = HostSpace>
647 class Array {
648  static_assert(
650  "Type not supported for DASH containers");
651 
652 private:
654 
655 
657 public:
658  typedef ElementType value_type;
659  typedef IndexType index_type;
660  typedef typename std::make_unsigned<IndexType>::type size_type;
661  typedef typename std::make_unsigned<IndexType>::type difference_type;
662 
665 
668 
669  typedef std::reverse_iterator< iterator> reverse_iterator;
670  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
671 
674 
675  typedef typename iterator::pointer pointer;
676  typedef typename pointer::const_type const_pointer;
677 
678  typedef typename pointer::local_type local_pointer;
679  typedef typename pointer::const_local_type const_local_pointer;
680 
682 
683 public:
684  template<
685  typename T_,
686  typename I_,
687  class P_,
688  typename LM_>
689  friend class LocalArrayRef;
690  template<
691  typename T_,
692  typename I_,
693  class P_,
694  typename M_>
695  friend class AsyncArrayRef;
696 
698 public:
700  typedef PatternType
702 
704  local_type;
706  view_type;
707  typedef AsyncArrayRef<value_type, IndexType, PatternType, LocalMemSpaceT>
708  async_type;
709 
710 public:
711  typedef std::integral_constant<dim_t, 1>
712  rank;
713 
714  static constexpr dim_t ndim() {
715  return 1;
716  }
717 
718 private:
719  typedef SizeSpec<1, size_type>
720  SizeSpec_t;
721 
722  using unique_gptr_t = decltype(
723  dash::allocate_unique<value_type>(allocator_type{}, std::size_t{}));
724 
725  using allocator_traits =
726  std::allocator_traits<typename memory_type::allocator_type>;
727 
728  static constexpr size_t alignment = alignof(value_type);
729 
730 public:
732  local_type local;
734  async_type async;
735 
736 private:
738  dash::Team *m_team{nullptr};
740  PatternType m_pattern{};
742  memory_type m_globmem{};
744  allocator_type m_allocator{};
746  unique_gptr_t m_data{nullptr};
748  iterator m_begin{};
750  iterator m_end{};
752  size_type m_size{};
754  size_type m_lsize{};
756  size_type m_lcapacity{};
758  ElementType * m_lbegin{};
760  ElementType * m_lend{};
762  team_unit_t m_myid{};
763 public:
770  explicit constexpr Array(Team &team = dash::Team::Null())
771  : local(this)
772  , async(this)
773  , m_team(&team)
774  , m_pattern(SizeSpec_t(0), distribution_spec(dash::BLOCKED), team)
775  {
776  DASH_LOG_TRACE("Array() >", "finished default constructor");
777  }
778 
783  size_type nelem,
784  const distribution_spec &distribution,
785  Team & team = dash::Team::All())
786  : local(this)
787  , async(this)
788  , m_team(&team)
789  , m_pattern(SizeSpec_t(nelem), distribution, team)
790  {
791  DASH_LOG_TRACE("Array(nglobal,dist,team)()", "size:", nelem);
792  allocate(m_pattern);
793  DASH_LOG_TRACE("Array(nglobal,dist,team) >");
794  }
795 
799  explicit Array(size_type nelem, Team &team = dash::Team::All())
800  : Array(nelem, dash::BLOCKED, team)
801  {
802  DASH_LOG_TRACE(
803  "Array(nglobal,team) >", "finished delegating constructor");
804  }
805 
811  size_type nelem,
812  std::initializer_list<value_type> local_elements,
813  const distribution_spec & distribution,
814  Team & team = dash::Team::All())
815  : local(this)
816  , async(this)
817  , m_team(&team)
818  , m_pattern(SizeSpec_t(nelem), distribution, team)
819  , m_globmem(*m_team)
820  , m_allocator(&m_globmem)
821  , m_myid(team.myid())
822  {
823  DASH_LOG_TRACE("Array(nglobal,lvals,dist,team)()",
824  "size:", nelem,
825  "nlocal:", local_elements.size());
826  allocate(local_elements);
827  DASH_LOG_TRACE("Array(nglobal,lvals,dist,team) >");
828  }
829 
835  size_type nelem,
836  std::initializer_list<value_type> local_elements,
837  Team & team = dash::Team::All())
838  : Array(nelem, local_elements, dash::BLOCKED, team)
839  {
840  DASH_LOG_TRACE("Array(nglobal,lvals,team) >",
841  "finished delegating constructor");
842  }
843 
847  explicit
849  const PatternType & pattern)
850  : local(this),
851  async(this),
852  m_team(&pattern.team()),
853  m_pattern(pattern),
854  m_myid(m_team->myid())
855  {
856  DASH_LOG_TRACE("Array()", "pattern instance constructor");
857  allocate(m_pattern);
858  }
859 
878  Array(const self_t & other) = delete;
879 
887  Array(self_t &&other) noexcept(
888  std::is_nothrow_move_constructible<memory_type>::value)
889  : local(this)
890  , async(this)
891  , m_team(other.m_team)
892  , m_pattern(std::move(other.m_pattern))
893  , m_globmem(std::move(other.m_globmem))
894  , m_allocator(&m_globmem)
895  , m_data(
896  other.m_data.release(),
897  typename unique_gptr_t::deleter_type{m_allocator,
898  m_pattern.local_size()})
899  , m_begin(other.m_begin)
900  , m_end(other.m_end)
901  , m_size(other.m_size)
902  , m_lsize(other.m_lsize)
903  , m_lcapacity(other.m_lcapacity)
904  , m_lbegin(other.m_lbegin)
905  , m_lend(other.m_lend)
906  , m_myid(other.m_myid)
907  {
908  other.m_begin = iterator{};
909  other.m_end = iterator{};
910  other.m_lbegin = nullptr;
911  other.m_lend = nullptr;
912  other.m_lsize = 0;
913  other.m_size = 0;
914 
915  other.m_team->unregister_deallocator(&other, std::bind(&Array::deallocate, &other));
916 
917  // Register deallocator of this array instance at the team
918  // instance that has been used to initialized it:
919  m_team->register_deallocator(this, std::bind(&Array::deallocate, this));
920  }
921 
940  self_t & operator=(const self_t & rhs) = delete;
941 
949  self_t & operator=(self_t && other) {
950  if (this == &other) {
951  return *this;
952  }
953 
954  m_pattern = std::move(other.m_pattern);
955 
956  DASH_ASSERT_EQ(
957  m_allocator.resource(),
958  &m_globmem,
959  "invalid state in move assignment");
960 
961  // a) reset own data
962  if (m_data) {
963  destruct_at_end(m_lbegin);
964  }
965  m_data.reset();
966  // b) swap memory resources
967  m_globmem = std::move(other.m_globmem);
968  // c) move the unique_gptr from other into this
969  unique_gptr_t __tmp{other.m_data.release(),
970  typename unique_gptr_t::deleter_type{
971  m_allocator, m_pattern.local_size()}};
972  m_data = std::move(__tmp);
973 
974 
975  //TODO rko: we have to provide a proper dash::swap for iterators;
976  this->m_begin = iterator{&m_globmem, m_pattern, other.m_begin.pos()};
977  this->m_end = iterator{&m_globmem, m_pattern, other.m_end.pos()};
978 
979  this->m_lbegin = other.m_lbegin;
980  this->m_lcapacity = other.m_lcapacity;
981  this->m_lend = other.m_lend;
982  this->m_lsize = other.m_lsize;
983  this->m_myid = other.m_myid;
984  this->m_size = other.m_size;
985  this->m_team = other.m_team;
986 
987  other.m_begin = iterator{};
988  other.m_end = iterator{};
989 
990  other.m_lbegin = nullptr;
991  other.m_lend = nullptr;
992  other.m_lsize = 0;
993  other.m_size = 0;
994 
995  other.m_team->unregister_deallocator(&other, std::bind(&Array::deallocate, &other));
996 
997  m_team->register_deallocator(this, std::bind(&Array::deallocate, this));
998 
999  return *this;
1000  }
1001 
1006  {
1007  DASH_LOG_TRACE_VAR("Array.~Array()", this);
1008  deallocate();
1009  DASH_LOG_TRACE_VAR("Array.~Array >", this);
1010  }
1011 
1015  constexpr const view_type block(index_type block_gindex) const
1016  {
1017  return View(this, ViewSpec<1>(pattern().block(block_gindex)));
1018  }
1019 
1024  constexpr const memory_type & globmem() const noexcept
1025  {
1026  return m_globmem;
1027  }
1028 
1032  constexpr const_pointer data() const noexcept
1033  {
1034  return const_pointer(m_data.get());
1035  }
1036 
1040  iterator begin() noexcept
1041  {
1042  return m_begin;
1043  }
1044 
1048  constexpr const_iterator begin() const noexcept
1049  {
1050  return const_iterator(
1051  const_cast<memory_type *>(&m_globmem), m_pattern, m_begin.pos());
1052  }
1053 
1057  iterator end() noexcept {
1058  return m_end;
1059  }
1060 
1064  constexpr const_iterator end() const noexcept
1065  {
1066  return const_iterator(
1067  const_cast<memory_type *>(&m_globmem), m_pattern, m_end.pos());
1068  }
1069 
1073  constexpr const ElementType * lbegin() const noexcept {
1074  return m_lbegin;
1075  }
1076 
1080  ElementType * lbegin() noexcept {
1081  return m_lbegin;
1082  }
1083 
1087  constexpr const ElementType * lend() const noexcept {
1088  return m_lend;
1089  }
1090 
1094  ElementType * lend() noexcept {
1095  return m_lend;
1096  }
1097 
1104  reference operator[](
1106  size_type global_index)
1107  {
1108  return m_begin[global_index];
1109  }
1110 
1117  constexpr const_reference operator[](
1119  size_type global_index) const
1120  {
1121  return m_begin[global_index];
1122  }
1123 
1132  reference at(
1134  size_type global_pos)
1135  {
1136  if (global_pos >= size()) {
1137  DASH_THROW(
1139  "Position " << global_pos
1140  << " is out of range " << size()
1141  << " in Array.at()" );
1142  }
1143  return m_begin[global_pos];
1144  }
1145 
1154  const_reference at(
1156  size_type global_pos) const
1157  {
1158  if (global_pos >= size()) {
1159  DASH_THROW(
1161  "Position " << global_pos
1162  << " is out of range " << size()
1163  << " in Array.at()" );
1164  }
1165  return m_begin[global_pos];
1166  }
1167 
1173  constexpr size_type size() const noexcept
1174  {
1175  return m_size;
1176  }
1177 
1184  constexpr size_type capacity() const noexcept
1185  {
1186  return m_size;
1187  }
1188 
1195  constexpr Team & team() const noexcept
1196  {
1197  return *m_team;
1198  }
1199 
1206  constexpr size_type lsize() const noexcept
1207  {
1208  return m_lsize;
1209  }
1210 
1217  constexpr size_type lcapacity() const noexcept
1218  {
1219  return m_lcapacity;
1220  }
1221 
1227  constexpr bool empty() const noexcept
1228  {
1229  return size() == 0;
1230  }
1231 
1232  constexpr view_type local_in(dash::util::Locality::Scope scope) const
1233  {
1234  return view_type(); // TODO
1235  }
1236 
1243  constexpr bool is_local(
1245  index_type global_index) const
1246  {
1247  return m_pattern.is_local(global_index, m_myid);
1248  }
1249 
1254  void barrier() const
1255  {
1256  DASH_LOG_TRACE_VAR("Array.barrier()", m_team);
1257  flush();
1258  if (m_team && *m_team != dash::Team::Null()) {
1259  m_team->barrier();
1260  }
1261  DASH_LOG_TRACE("Array.barrier >", "passed barrier");
1262  }
1263 
1268  inline void flush() const {
1269  //if (m_globmem && m_begin != m_end) {
1270  if (m_data) {
1271  //If we have some allocated memory -> flush it
1272  m_globmem.flush(m_data.get());
1273  }
1274  }
1275 
1280  inline void flush(dash::team_unit_t target) const {
1281  if (m_data) {
1282  m_globmem.flush(m_data.get(), target);
1283  }
1284  }
1285 
1290  inline void flush_local() const {
1291  if (m_data) {
1292  m_globmem.flush_local(m_data.get());
1293  }
1294  }
1295 
1296 
1301  inline void flush_local(dash::team_unit_t target) const {
1302  if (m_data) {
1303  m_globmem.flush_local(m_data.get(), target);
1304  }
1305  }
1306 
1310  constexpr const PatternType & pattern() const noexcept
1311  {
1312  return m_pattern;
1313  }
1314 
1319  bool allocate(
1320  size_type nelem,
1321  dash::DistributionSpec<1> distribution,
1322  dash::Team & team = dash::Team::All())
1323  {
1324  DASH_LOG_TRACE_VAR("Array.allocate(nlocal,ds,team)", nelem);
1325  DASH_LOG_TRACE_VAR("Array.allocate", m_team->dart_id());
1326  DASH_LOG_TRACE_VAR("Array.allocate", team.dart_id());
1327  // Check requested capacity:
1328  if (nelem == 0) {
1329  DASH_LOG_WARN("Array.allocate", "allocating dash::Array with size 0");
1330  }
1331  if (m_team == nullptr || *m_team == dash::Team::Null()) {
1332  DASH_LOG_TRACE("Array.allocate",
1333  "initializing with specified team -",
1334  "team size:", team.size());
1335  m_team = &team;
1336  m_pattern = PatternType(nelem, distribution, team);
1337  DASH_LOG_TRACE_VAR("Array.allocate", team.dart_id());
1338  DASH_LOG_TRACE_VAR("Array.allocate", m_pattern.team().dart_id());
1339  } else {
1340  DASH_LOG_TRACE("Array.allocate",
1341  "initializing pattern with initial team");
1342  m_pattern = PatternType(nelem, distribution, *m_team);
1343  }
1344 
1345  bool ret = allocate(m_pattern);
1346  DASH_LOG_TRACE("Array.allocate(nlocal,ds,team) >");
1347  return ret;
1348  }
1349 
1350 
1355  bool allocate(
1356  size_type nelem,
1357  Team & team = dash::Team::All())
1358  {
1359  return allocate(nelem, dash::BLOCKED, team);
1360  }
1361 
1367  bool allocate(
1368  size_type nelem,
1369  std::initializer_list<value_type> local_elements,
1370  dash::DistributionSpec<1> distribution,
1371  dash::Team & team = dash::Team::All())
1372  {
1373  DASH_LOG_TRACE_VAR("Array.allocate(lvals,ds,team)",
1374  local_elements.size());
1375  DASH_LOG_TRACE_VAR("Array.allocate", m_team->dart_id());
1376  DASH_LOG_TRACE_VAR("Array.allocate", team.dart_id());
1377  // Check requested capacity:
1378  if (nelem == 0) {
1379  DASH_THROW(
1381  "Tried to allocate dash::Array with size 0");
1382  }
1383  if (m_team == nullptr || *m_team == dash::Team::Null()) {
1384  DASH_LOG_TRACE("Array.allocate",
1385  "initializing pattern with Team::All()");
1386  m_team = &team;
1387  m_pattern = PatternType(nelem, distribution, team);
1388  DASH_LOG_TRACE_VAR("Array.allocate", team.dart_id());
1389  DASH_LOG_TRACE_VAR("Array.allocate", m_pattern.team().dart_id());
1390  } else {
1391  DASH_LOG_TRACE("Array.allocate",
1392  "initializing pattern with initial team");
1393  m_pattern = PatternType(nelem, distribution, *m_team);
1394  }
1395  bool ret = allocate(local_elements);
1396  DASH_LOG_TRACE("Array.allocate(lvals,ds,team) >");
1397  return ret;
1398  }
1399 
1400  void deallocate()
1401  {
1402  DASH_LOG_TRACE_VAR("Array.deallocate()", this);
1403  DASH_LOG_TRACE_VAR("Array.deallocate()", m_size);
1404  // Assure all units are synchronized before deallocation, otherwise
1405  // other units might still be working on the array:
1406  if (dash::is_initialized()) {
1407  barrier();
1408  }
1409 
1410  m_team->unregister_deallocator(
1411  this, std::bind(&Array::deallocate, this));
1412 
1413  // Actual destruction of the array instance:
1414  DASH_LOG_TRACE_VAR("Array.deallocate()", m_data.get());
1415 
1416  if (m_data) {
1417  destruct_at_end(m_lbegin);
1418  }
1419 
1420  m_data.reset();
1421 
1422  m_lsize = 0;
1423  m_size = 0;
1424  m_begin = iterator{};
1425  m_end = iterator{};
1426  m_lbegin = nullptr;
1427  m_lend = nullptr;
1428  DASH_LOG_TRACE_VAR("Array.deallocate >", this);
1429  }
1430 
1431 private:
1432  void destruct_at_end(local_pointer new_last)
1433  {
1434  if (0 == m_lsize || m_lend == nullptr) return;
1435 
1436  local_pointer soon_to_be_new_last = m_lend;
1437 
1438  auto local_alloc = this->globmem().get_allocator();
1439 
1440  while (new_last != soon_to_be_new_last) {
1441  allocator_traits::destroy(local_alloc, --soon_to_be_new_last);
1442  }
1443  m_lend = new_last;
1444  }
1445 
1446  void do_allocate() {
1447  //reset old data
1448  m_data.reset();
1449 
1450  m_team = &(m_pattern.team());
1451  m_globmem = memory_type{*m_team};
1452  m_allocator = allocator_type{&m_globmem};
1453 
1454  // Check requested capacity:
1455  m_size = m_pattern.capacity();
1456  m_team = &m_pattern.team();
1457  if (m_size == 0) {
1458  DASH_LOG_WARN("Array.allocate", "allocating dash::Array with size 0");
1459  }
1460  // Initialize members:
1461  m_lsize = m_pattern.local_size();
1462  m_lcapacity = m_pattern.local_capacity();
1463  m_myid = m_pattern.team().myid();
1464  // Allocate local memory of identical size on every unit:
1465  DASH_LOG_TRACE_VAR("Array._allocate", m_myid);
1466  DASH_LOG_TRACE_VAR("Array._allocate", m_lcapacity);
1467  DASH_LOG_TRACE_VAR("Array._allocate", m_lsize);
1468 
1469  m_data = std::move(dash::allocate_unique<value_type>(
1470  m_allocator, m_pattern.local_size()));
1471 
1472  if (m_pattern.local_size()) {
1473  DASH_ASSERT(m_data);
1474  }
1475 
1476  // Global iterators:
1477  m_begin = iterator(&m_globmem, m_pattern);
1478  m_end = iterator(m_begin) + m_size;
1479  }
1480 
1481  bool allocate(std::initializer_list<value_type> local_elements)
1482  {
1483  DASH_LOG_TRACE("< Array.allocate", "finished");
1484 
1485  DASH_ASSERT_EQ(
1486  m_pattern.local_size(), local_elements.size(), "invalid arguments");
1487 
1488  do_allocate();
1489 
1490  // Local iterators:
1491  auto soon_to_be_lbegin = m_data.get();
1492  soon_to_be_lbegin.set_unit(m_myid);
1493  m_lbegin = soon_to_be_lbegin.local();
1494 
1495  DASH_ASSERT(m_lbegin);
1496 
1497  //construct all elements and properly set m_lend
1498  std::uninitialized_copy(std::begin(local_elements), std::end(local_elements), m_lbegin);
1499  m_lend = std::next(m_lbegin, local_elements.size());
1500 
1501  DASH_LOG_TRACE_VAR("Array._allocate", m_myid);
1502  DASH_LOG_TRACE_VAR("Array._allocate", m_size);
1503  DASH_LOG_TRACE_VAR("Array._allocate", m_lsize);
1504  // Register deallocator of this array instance at the team
1505  // instance that has been used to initialized it:
1506  m_team->register_deallocator(
1507  this, std::bind(&Array::deallocate, this));
1508  // Assure all units are synchronized after allocation, otherwise
1509  // other units might start working on the array before allocation
1510  // completed at all units:
1511  DASH_LOG_TRACE("Array._allocate", "waiting for allocation of all units");
1512  m_team->barrier();
1513 
1514  DASH_LOG_TRACE("Array._allocate >", "finished");
1515  return true;
1516  }
1517 
1518 public:
1522  bool allocate(const PatternType &pattern)
1523  {
1524  DASH_LOG_TRACE("< Array.allocate", "finished");
1525  if (&m_pattern != &pattern) {
1526  DASH_LOG_TRACE("Array.allocate()", "using specified pattern");
1527  m_pattern = pattern;
1528  }
1529 
1530  do_allocate();
1531 
1532  // Local iterators:
1533  auto soon_to_be_lbegin = m_data.get();
1534  soon_to_be_lbegin.set_unit(m_myid);
1535  m_lbegin = soon_to_be_lbegin.local();
1536  // More efficient than using m_globmem->lend as this a second mapping
1537  // of the local memory segment:
1538  m_lend = std::next(m_lbegin, m_lsize);
1539 
1540  // We do no construct the elements to prevent NUMA effects
1541  // construct_at_end(m_lsize);
1542 
1543  // Register deallocator of this array instance at the team
1544  // instance that has been used to initialized it:
1545  m_team->register_deallocator(this, std::bind(&Array::deallocate, this));
1546  // Assure all units are synchronized after allocation, otherwise
1547  // other units might start working on the array before allocation
1548  // completed at all units:
1549  DASH_LOG_TRACE("Array.allocate", "waiting for allocation of all units");
1550  m_team->barrier();
1551  DASH_LOG_TRACE("Array.allocate >", "finished");
1552  return true;
1553  }
1554 };
1555 
1556 } // namespace dash
1557 
1558 #endif /* ARRAY_H_INCLUDED */
constexpr dim_t rank(const DimensionalType &d)
Definition: Dimensional.h:64
ElementType value_type
Public types as required by iterator concept.
Definition: Array.h:463
async_type async
Proxy object, provides non-blocking operations on array.
Definition: Array.h:734
constexpr size_type size() const noexcept
Number of array elements in local memory.
Definition: Array.h:209
bool allocate(size_type nelem, Team &team=dash::Team::All())
Delayed allocation of global memory using the default blocked distribution spec.
Definition: Array.h:1355
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
constexpr const_iterator end() const noexcept
Pointer past final local element in the array.
Definition: Array.h:195
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
constexpr const_iterator begin() const noexcept
Global pointer to the beginning of the array.
Definition: Array.h:1048
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
Specifies view parameters for implementing submat, rows and cols.
Definition: Dimensional.h:430
constexpr size_type lcapacity() const noexcept
The capacity of the local part of the array.
Definition: Array.h:1217
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
constexpr const ElementType * lbegin() const noexcept
Native pointer to the first local element in the array.
Definition: Array.h:1073
iterator end() noexcept
Global pointer to the end of the array.
Definition: Array.h:1057
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
void flush_local() const
Locally complete all outstanding non-blocking operations to all units on the array&#39;s underlying globa...
Definition: Array.h:1290
Array(size_type nelem, std::initializer_list< value_type > local_elements, const distribution_spec &distribution, Team &team=dash::Team::All())
Constructor, specifies the array&#39;s global capacity, values of local elements and distribution.
Definition: Array.h:810
constexpr size_type lsize() const noexcept
The number of elements in the local part of the array.
Definition: Array.h:1206
Array(size_type nelem, Team &team=dash::Team::All())
Delegating constructor, specifies the array&#39;s global capacity.
Definition: Array.h:799
Array(const PatternType &pattern)
Constructor, specifies distribution pattern explicitly.
Definition: Array.h:848
const_reference at(size_type global_pos) const
Random access operator, range-checked.
Definition: Array.h:1154
void flush(dash::team_unit_t target) const
Complete all outstanding non-blocking operations to the specified unit on the array&#39;s underlying glob...
Definition: Array.h:1280
ArrayRef(const Array_t *array, const ViewSpec_t &viewspec)
Definition: Array.h:507
void unregister_deallocator(void *object, Deallocator::dealloc_function dealloc)
Unregister a deallocator function for a team-allocated object.
Definition: Team.h:300
Proxy type representing local access to elements in a dash::Array.
Definition: Array.h:105
bool is_initialized()
Check whether DASH has been initialized already.
ElementType value_type
Public types as required by iterator concept.
Definition: Array.h:658
constexpr const ElementType * lend() const noexcept
Native pointer to the end of the array.
Definition: Array.h:1087
LocalArrayRef(const Array_t *array)
Constructor, creates a local access proxy for the given array.
Definition: Array.h:158
constexpr Team & team() const noexcept
The team containing all units accessing this array.
Definition: Array.h:1195
PatternType pattern_type
Public types as required by dash container concept.
Definition: Array.h:490
reference operator[](const size_type n)
Subscript operator, access to local array element at given position.
Definition: Array.h:223
Array(size_type nelem, const distribution_spec &distribution, Team &team=dash::Team::All())
Constructor, specifies the array&#39;s global capacity and distribution.
Definition: Array.h:782
ElementType * lend() noexcept
Native pointer to the end of the array.
Definition: Array.h:1094
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
void flush() const
Complete all outstanding non-blocking operations to all units on the array&#39;s underlying global memory...
Definition: Array.h:1268
constexpr const PatternType & pattern() const
The pattern used to distribute array elements to units.
Definition: Array.h:611
A Team instance specifies a subset of all available units.
Definition: Team.h:41
reference at(size_type global_pos)
Random access assignment operator, range-checked.
Definition: Array.h:1132
LocalArrayRef(const Array_t *array, const ViewSpec_t &viewspec)
Definition: Array.h:163
constexpr const_reference operator[](const size_type n) const
Subscript operator, access to local array element at given position.
Definition: Array.h:216
constexpr const memory_type & globmem() const noexcept
The instance of GlobStaticMem used by this iterator to resolve addresses in global memory...
Definition: Array.h:1024
DASH_CONSTEXPR index_type pos() const DASH_NOEXCEPT
Position of the iterator in global index space.
Definition: GlobIter.h:336
bool allocate(const PatternType &pattern)
Delayed allocation of global memory using the specified pattern.
Definition: Array.h:1522
iterator end() noexcept
Pointer past final local element in the array.
Definition: Array.h:202
constexpr const PatternType & pattern() const noexcept
The pattern used to distribute array elements to units.
Definition: Array.h:1310
constexpr bool empty() const noexcept
Checks whether the array is empty.
Definition: Array.h:1227
constexpr const_reference operator[](size_type global_index) const
Definition: Array.h:573
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
void flush_local(dash::team_unit_t target) const
Locally complete all outstanding non-blocking operations to the specified unit on the array&#39;s underly...
Definition: Array.h:1301
Proxy type representing an access modifier on elements in a dash::Array.
Definition: Array.h:447
A distributed array.
Definition: Array.h:89
~Array()
Destructor, deallocates array elements.
Definition: Array.h:1005
constexpr const_reference operator[](size_type global_index) const
Subscript operator, not range-checked.
Definition: Array.h:1117
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
constexpr size_type size() const noexcept
The size of the array.
Definition: Array.h:1173
PatternType pattern_type
Public types as required by dash container concept.
Definition: Array.h:701
constexpr size_type capacity() const noexcept
The number of elements that can be held in currently allocated storage of the array.
Definition: Array.h:1184
constexpr const PatternType & pattern() const noexcept
The pattern used to distribute array elements to units.
Definition: Array.h:249
constexpr self_t block(index_type block_lindex) const
View at block at given global block offset.
Definition: Array.h:241
self_t & operator=(self_t &&other)
Move assignment is supported for the container with the following limitations:
Definition: Array.h:949
void barrier() const
Establish a barrier for all units operating on the array, publishing all changes to all units...
Definition: Array.h:1254
reference at(size_type global_pos)
Definition: Array.h:580
Proxy type representing a view specifier on elements in a dash::Array.
Definition: Array.h:426
constexpr bool is_local(index_type global_index) const
Checks whether the given global index is local to the calling unit.
Definition: Array.h:1243
Type trait indicating whether the specified type is eligible for elements of DASH containers...
Definition: Types.h:236
bool allocate(size_type nelem, std::initializer_list< value_type > local_elements, dash::DistributionSpec< 1 > distribution, dash::Team &team=dash::Team::All())
Delayed allocation of global memory using a one-dimensional distribution spec and initializing values...
Definition: Array.h:1367
static Team & Null()
The invariant Team instance representing an undefined team.
Definition: Team.h:229
constexpr Array(Team &team=dash::Team::Null())
Default constructor, for delayed allocation.
Definition: Array.h:770
Array(size_type nelem, std::initializer_list< value_type > local_elements, Team &team=dash::Team::All())
Delegating constructor, specifies the array&#39;s global capacity and values of local elements...
Definition: Array.h:834
constexpr bool is_local(index_type local_index) const
Checks whether the given local index is local to the calling unit.
Definition: Array.h:232
iterator begin() noexcept
Pointer to initial local element in the array.
Definition: Array.h:188
constexpr DimensionalType::extent_type extent(const DimensionalType &d)
Definition: Dimensional.h:73
constexpr const_iterator begin() const noexcept
Pointer to initial local element in the array.
Definition: Array.h:181
reference operator[](size_type global_index)
Definition: Array.h:565
constexpr const view_type block(index_type block_gindex) const
View at block at given global block offset.
Definition: Array.h:1015
void barrier()
A global barrier involving all units.
Global value reference for asynchronous / non-blocking operations.
Definition: GlobAtomicRef.h:17
reference operator[](size_type global_index)
Subscript assignment operator, not range-checked.
Definition: Array.h:1104
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
ElementType * lbegin() noexcept
Native pointer to the first local element in the array.
Definition: Array.h:1080
constexpr const_pointer data() const noexcept
Global const pointer to the beginning of the array.
Definition: Array.h:1032
iterator begin() noexcept
Global pointer to the beginning of the array.
Definition: Array.h:1040
const_reference at(size_type global_pos) const
Definition: Array.h:594
Array(self_t &&other) noexcept(std::is_nothrow_move_constructible< memory_type >::value)
Move construction is supported for the container with the following limitations:
Definition: Array.h:887
constexpr const_iterator end() const noexcept
Global pointer to the end of the array.
Definition: Array.h:1064
LocalArrayRef< T, IndexType, PatternType, LocalMemSpaceT > View
Type alias for LocalArrayRef<T,I,P>::view_type.
Definition: Array.h:142
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222
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