DASH  0.3.0
UnorderedMapGlobIter.h
1 #ifndef DASH__MAP__UNORDERED_MAP_GLOB_ITER_H__INCLUDED
2 #define DASH__MAP__UNORDERED_MAP_GLOB_ITER_H__INCLUDED
3 
4 #include <dash/dart/if/dart.h>
5 
6 #include <dash/Types.h>
7 #include <dash/memory/GlobHeapPtr.h>
8 #include <dash/GlobSharedRef.h>
9 #include <dash/Allocator.h>
10 #include <dash/Team.h>
11 #include <dash/Onesided.h>
12 
13 #include <dash/map/UnorderedMapLocalIter.h>
14 
15 #include <dash/internal/Logging.h>
16 
17 #include <type_traits>
18 #include <list>
19 #include <vector>
20 #include <iterator>
21 #include <sstream>
22 #include <iostream>
23 
24 namespace dash {
25 
26 // Forward-declaration
27 template<
28  typename Key,
29  typename Mapped,
30  typename Hash,
31  typename Pred,
32  typename LMemSpace >
34 
35 template <
36  typename Key,
37  typename Mapped,
38  typename Hash,
39  typename Pred,
40  typename GlobMemType>
42  : public std::iterator<
43  std::random_access_iterator_tag,
44  std::pair<const Key, Mapped>,
45  dash::default_index_t,
46  GlobHeapPtr<std::pair<const Key, Mapped>, GlobMemType>,
47  GlobSharedRef<std::pair<const Key, Mapped>, GlobMemType>> {
48  template<typename K_, typename M_, typename H_, typename P_, typename G_>
49  friend class UnorderedMapGlobIter;
50 
51  template<typename K_, typename M_, typename H_, typename P_, typename G_>
52  friend std::ostream & dash::operator<<(
53  std::ostream & os,
55 
56 private:
58  self_t;
59 
61  map_t;
62 
67 
68 public:
69  typedef typename map_t::value_type value_type;
70  typedef dash::default_index_t index_type;
71  typedef dash::default_size_t size_type;
72 
73  typedef typename map_t::pointer pointer;
74  typedef typename map_t::const_pointer const_pointer;
75 
76  typedef typename map_t::reference reference;
77  typedef typename map_t::const_reference const_reference;
78 
79  typedef value_type* raw_pointer;
80  typedef const value_type* const_raw_pointer;
81 
82  typedef typename
83  std::conditional<
84  std::is_const<value_type>::value,
86  typename map_t::local_iterator
87  >::type
88  local_pointer;
89 
90  typedef struct {
91  team_unit_t unit;
92  index_type index{};
93  } local_index;
94 
95 public:
100  : UnorderedMapGlobIter(nullptr)
101  { }
102 
107  map_t * map,
108  index_type position)
109  : _map(map),
110  _idx(0),
111  _myid(map->team().myid()),
112  _idx_unit_id(0),
113  _idx_local_idx(0)
114  {
115  DASH_LOG_TRACE_VAR("UnorderedMapGlobIter(map,pos)", _idx);
116  increment(position);
117  DASH_LOG_TRACE("UnorderedMapGlobIter(map,pos) >");
118  }
119 
125  map_t * map,
126  team_unit_t unit,
127  index_type local_index)
128  : _map(map),
129  _idx(0),
130  _myid(map->team().myid()),
131  _idx_unit_id(unit),
132  _idx_local_idx(local_index)
133  {
134  DASH_LOG_TRACE("UnorderedMapGlobIter(map,unit,lidx)()");
135  DASH_LOG_TRACE_VAR("UnorderedMapGlobIter(map,unit,lidx)", unit);
136  DASH_LOG_TRACE_VAR("UnorderedMapGlobIter(map,unit,lidx)", local_index);
137  // Unit and local offset to global position:
138  size_type unit_l_cumul_size_prev = 0;
139  if (unit > 0) {
140  unit_l_cumul_size_prev = _map->_local_cumul_sizes[unit-1];
141  }
142  _idx = unit_l_cumul_size_prev + _idx_local_idx;
143  DASH_LOG_TRACE_VAR("UnorderedMapGlobIter(map,unit,lidx)", _idx);
144  DASH_LOG_TRACE("UnorderedMapGlobIter(map,unit,lidx) >");
145  }
146 
151  const self_t & other) = default;
152 
156  self_t & operator=(
157  const self_t & other) = default;
158 
162  UnorderedMapGlobIter(std::nullptr_t)
163  : _map(nullptr)
164  , _myid(DART_UNDEFINED_UNIT_ID)
165  , _idx_unit_id(DART_UNDEFINED_UNIT_ID)
166  , _is_nullptr(true)
167  {
168  DASH_LOG_TRACE("UnorderedMapGlobIter(nullptr)");
169  }
170 
174  self_t & operator=(std::nullptr_t) noexcept
175  {
176  _is_nullptr = true;
177  return *this;
178  }
179 
180  constexpr bool operator==(std::nullptr_t) const noexcept
181  {
182  return _is_nullptr;
183  }
184 
185  constexpr bool operator!=(std::nullptr_t) const noexcept
186  {
187  return !_is_nullptr;
188  }
189 
193  reference operator[](index_type offset)
194  {
195  auto res = *this;
196  res += offset;
197  return *this;
198  }
199 
205  constexpr operator pointer() const
206  {
207  return pointer(dart_gptr());
208  }
209 
216  constexpr dart_gptr_t dart_gptr() const
217  {
218  return _map->globmem().at(
219  _idx_unit_id,
220  _idx_local_idx
221  ).dart_gptr();
222  }
223 
229  reference operator*()
230  {
231  if (is_local()) {
232  // To local map iterator:
233  auto l_map_it = local();
234  DASH_ASSERT_MSG(l_map_it != nullptr,
235  "Converting global iterator at local position to "
236  "local iterator failed");
237  // To native pointer via conversion:
238  return reference(static_cast<raw_pointer>(l_map_it));
239  } else {
240  return reference(dart_gptr());
241  }
242  }
243 
249  const_reference operator*() const
250  {
251  if (is_local()) {
252  // To local map iterator:
253  auto l_map_it = local();
254  DASH_ASSERT_MSG(l_map_it != nullptr,
255  "Converting global iterator at local position to "
256  "local iterator failed");
257  // To native pointer via conversion:
258  return reference(static_cast<raw_pointer>(l_map_it));
259  } else {
260  return reference(dart_gptr());
261  }
262  }
263 
264 #if 0
265 
268  pointer operator->() const
269  {
270  return static_cast<pointer>(*this);
271  }
272 #endif
273 
278  constexpr bool is_local() const noexcept
279  {
280  return (_myid == _idx_unit_id);
281  }
282 
286  local_iterator local()
287  {
288  if (_myid != _idx_unit_id) {
289  // Iterator position does not point to local element
290  return local_iterator(nullptr);
291  }
292  return (_map->lbegin() + _idx_local_idx);
293  }
294 
298  const_local_iterator local() const
299  {
300  if (_myid != _idx_unit_id) {
301  // Iterator position does not point to local element
302  return local_iterator(nullptr);
303  }
304  return (_map->lbegin() + _idx_local_idx);
305  }
306 
310  inline local_index lpos() const noexcept
311  {
312  local_index local_pos;
313  local_pos.unit = _idx_unit_id;
314  local_pos.index = _idx_local_idx;
315  return local_pos;
316  }
317 
321  constexpr self_t global() const noexcept
322  {
323  return *this;
324  }
325 
329  constexpr index_type pos() const noexcept
330  {
331  return _idx;
332  }
333 
337  constexpr index_type gpos() const noexcept
338  {
339  return _idx;
340  }
341 
345  inline self_t & operator++()
346  {
347  increment(1);
348  return *this;
349  }
350 
354  inline self_t & operator--()
355  {
356  decrement(1);
357  return *this;
358  }
359 
363  inline self_t operator++(int)
364  {
365  auto result = *this;
366  increment(1);
367  return result;
368  }
369 
373  inline self_t operator--(int)
374  {
375  auto result = *this;
376  decrement(1);
377  return result;
378  }
379 
380  template<typename K_, typename M_, typename H_, typename P_, typename A_>
381  constexpr bool operator==(
382  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
383  {
384  return (this == std::addressof(other) || _idx == other._idx);
385  }
386 
387  template<typename K_, typename M_, typename H_, typename P_, typename A_>
388  constexpr bool operator!=(
389  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
390  {
391  return !(*this == other);
392  }
393 
394  self_t & operator+=(index_type offset)
395  {
396  increment(offset);
397  return *this;
398  }
399 
400  self_t & operator-=(index_type offset)
401  {
402  decrement(offset);
403  return *this;
404  }
405 
406  self_t operator+(index_type offset) const
407  {
408  auto res = *this;
409  res += offset;
410  return res;
411  }
412 
413  self_t operator-(index_type offset) const
414  {
415  auto res = *this;
416  res -= offset;
417  return res;
418  }
419 
420  constexpr index_type operator+(
421  const self_t & other) const noexcept
422  {
423  return _idx + other._idx;
424  }
425 
426  constexpr index_type operator-(
427  const self_t & other) const noexcept
428  {
429  return _idx - other._idx;
430  }
431 
432  template<typename K_, typename M_, typename H_, typename P_, typename A_>
433  constexpr bool operator<(
434  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
435  {
436  return (_idx < other._idx);
437  }
438 
439  template<typename K_, typename M_, typename H_, typename P_, typename A_>
440  constexpr bool operator<=(
441  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
442  {
443  return (_idx <= other._idx);
444  }
445 
446  template<typename K_, typename M_, typename H_, typename P_, typename A_>
447  constexpr bool operator>(
448  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
449  {
450  return (_idx > other._idx);
451  }
452 
453  template<typename K_, typename M_, typename H_, typename P_, typename A_>
454  constexpr bool operator>=(
455  const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
456  {
457  return (_idx >= other._idx);
458  }
459 
460 private:
464  void increment(index_type offset)
465  {
466  DASH_LOG_TRACE("UnorderedMapGlobIter.increment()",
467  "gidx:", _idx, "-> (",
468  "unit:", _idx_unit_id,
469  "lidx:", _idx_local_idx, ")",
470  "offset:", offset);
471  if (offset < 0) {
472  decrement(-offset);
473  } else {
474  // Note:
475  //
476  // increment(0) is not a no-op as UnorderedMapGlobIter(map, 0) should
477  // reference the first existing element, not the first possible element
478  // position.
479  // The first existing element has gidx:0 and lidx:0 but might not be
480  // located at unit 0.
481  // Example:
482  //
483  // unit 0 unit 1 unit 2
484  // [ (empty) | (empty) | elem_0, elem_1 ]
485  // |
486  // '- first element
487  //
488  // --> UnorderedMapGlobIter(map, 0) -> (gidx:0, unit:2, lidx:0)
489  //
490  _idx += offset;
491  _idx_local_idx = _idx;
492  auto & l_cumul_sizes = _map->_local_cumul_sizes;
493  // Find unit at global offset:
494  while (_idx >= l_cumul_sizes[_idx_unit_id] &&
495  _idx_unit_id < l_cumul_sizes.size() - 1) {
496  DASH_LOG_TRACE("UnorderedMapGlobIter.increment",
497  "local cumulative size of unit", _idx_unit_id, ":",
498  l_cumul_sizes[_idx_unit_id]);
499  _idx_unit_id++;
500  }
501  if (_idx_unit_id > 0) {
502  _idx_local_idx = _idx - l_cumul_sizes[_idx_unit_id-1];
503  }
504  }
505  DASH_LOG_TRACE("UnorderedMapGlobIter.increment >", *this);
506  }
507 
511  void decrement(index_type offset)
512  {
513  DASH_LOG_TRACE("UnorderedMapGlobIter.decrement()",
514  "gidx:", _idx, "-> (",
515  "unit:", _idx_unit_id,
516  "lidx:", _idx_local_idx, ")",
517  "offset:", -offset);
518  if (offset < 0) {
519  increment(-offset);
520  } else if (offset > 0) {
521  // TODO
522  _idx -= offset;
523  _idx_local_idx = _idx;
524  }
525  DASH_LOG_TRACE("UnorderedMapGlobIter.decrement >", *this);
526  }
527 
528 private:
530  map_t * _map = nullptr;
532  index_type _idx = -1;
534  team_unit_t _myid;
536  team_unit_t _idx_unit_id;
538  index_type _idx_local_idx = -1;
540  bool _is_nullptr = false;
541 
542 }; // class UnorderedMapGlobIter
543 
544 template<
545  typename Key,
546  typename Mapped,
547  typename Hash,
548  typename Pred,
549  typename GlobMemType >
550 std::ostream & operator<<(
551  std::ostream & os,
553  Key, Mapped, Hash, Pred, GlobMemType> & it)
554 {
555  std::ostringstream ss;
556  ss << "dash::UnorderedMapGlobIter<"
557  << typeid(Key).name() << ","
558  << typeid(Mapped).name() << ">"
559  << "("
560  << "idx:" << it._idx << ", "
561  << "unit:" << it._idx_unit_id << ", "
562  << "lidx:" << it._idx_local_idx
563  << ")";
564  return operator<<(os, ss.str());
565 }
566 
567 } // namespace dash
568 
569 #endif // DASH__MAP__UNORDERED_MAP_GLOB_ITER_H__INCLUDED
reference operator[](index_type offset)
Random access operator.
UnorderedMapGlobIter(map_t *map, index_type position)
Constructor, creates iterator at specified global position.
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
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
self_t & operator=(const self_t &other)=default
Assignment operator.
constexpr index_type gpos() const noexcept
Position of the iterator in global index range.
self_t operator--(int)
Postfix decrement operator.
UnorderedMapGlobIter()
Default constructor.
constexpr dart_gptr_t dart_gptr() const
Explicit conversion to dart_gptr_t.
self_t operator++(int)
Postfix increment operator.
UnorderedMapGlobIter(map_t *map, team_unit_t unit, index_type local_index)
Constructor, creates iterator at local position relative to the specified unit&#39;s local iteration spac...
constexpr bool operator<=(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Less-than-or-equal operator implemented in terms of less-than operator.
Definition: Pair.h:172
self_t & operator++()
Prefix increment operator.
const_reference operator*() const
Dereference operator.
const_local_iterator local() const
Conversion to local bucket iterator.
constexpr bool operator>=(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than-or-equal operator implemented in terms of less-than operator.
Definition: Pair.h:182
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
local_index lpos() const noexcept
Unit and local offset at the iterator&#39;s position.
constexpr bool operator>(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than operator implemented in terms of less-than operator.
Definition: Pair.h:162
UnorderedMapGlobIter(std::nullptr_t)
Null-pointer constructor.
Iterator on global buckets.
Definition: GlobHeapMem.h:32
DART Global pointer type.
Definition: dart_globmem.h:77
self_t & operator--()
Prefix decrement operator.
constexpr index_type pos() const noexcept
Position of the iterator in global index space.
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 bool is_local() const noexcept
Checks whether the element referenced by this global iterator is in the calling unit&#39;s local memory...
self_t & operator=(std::nullptr_t) noexcept
Null-pointer assignment operator.
reference operator*()
Dereference operator.
constexpr self_t global() const noexcept
Map iterator to global index domain.
#define DART_UNDEFINED_UNIT_ID
Undefined unit ID.
Definition: dart_types.h:160
constexpr bool operator<(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
A pair is smaller than another pair if the first member is smaller or the first is equal and the seco...
Definition: Pair.h:140
local_iterator local()
Conversion to local bucket iterator.