1 #ifndef DASH__MEMORY__GLOB_HEAP_PTR_H__INCLUDED 2 #define DASH__MEMORY__GLOB_HEAP_PTR_H__INCLUDED 6 #include <dash/Types.h> 7 #include <dash/Allocator.h> 9 #include <dash/GlobSharedRef.h> 11 #include <dash/internal/Logging.h> 13 #include <type_traits> 30 typedef MemSpaceT GlobHeapMemType;
31 typedef GlobHeapPtr<ElementType, GlobHeapMemType> self_t;
33 template <
typename ElementType_,
class MemSpaceT_>
34 friend std::ostream &operator<<(
39 typedef typename GlobHeapMemType::index_type index_type;
40 typedef typename std::make_unsigned<index_type>::type size_type;
42 typedef ElementType value_type;
44 typedef GlobSharedRef< value_type, self_t> reference;
45 typedef GlobSharedRef<const value_type, self_t> const_reference;
47 typedef value_type * raw_pointer;
49 typedef GlobHeapMemType globmem_type;
50 typedef typename GlobHeapMemType::local_pointer local_pointer;
61 typedef std::vector<std::vector<size_type> >
62 bucket_cumul_sizes_map;
66 const globmem_type * _globmem =
nullptr;
68 const bucket_cumul_sizes_map * _bucket_cumul_sizes =
nullptr;
70 local_pointer _lbegin;
74 index_type _max_idx = 0;
80 index_type _idx_local_idx = -1;
82 index_type _idx_bucket_idx = -1;
84 index_type _idx_bucket_phase = -1;
92 _bucket_cumul_sizes(nullptr),
101 DASH_LOG_TRACE_VAR(
"GlobHeapPtr()", _idx);
102 DASH_LOG_TRACE_VAR(
"GlobHeapPtr()", _max_idx);
110 const MemSpaceT * gmem,
111 index_type position = 0)
112 : _globmem(reinterpret_cast<const globmem_type *>(gmem)),
113 _bucket_cumul_sizes(&_globmem->_bucket_cumul_sizes),
114 _lbegin(_globmem->lbegin()),
116 _max_idx(gmem->
size() - 1),
117 _myid(gmem->team().
myid()),
123 DASH_LOG_TRACE(
"GlobHeapPtr(gmem,idx)",
"gidx:", position);
124 for (
auto unit_bucket_cumul_sizes : *_bucket_cumul_sizes) {
125 DASH_LOG_TRACE_VAR(
"GlobHeapPtr(gmem,idx)",
126 unit_bucket_cumul_sizes);
127 size_type bucket_cumul_size_prev = 0;
128 for (
auto bucket_cumul_size : unit_bucket_cumul_sizes) {
129 DASH_LOG_TRACE_VAR(
"GlobHeapPtr(gmem,idx)", bucket_cumul_size);
130 if (position < bucket_cumul_size) {
131 DASH_LOG_TRACE_VAR(
"GlobHeapPtr(gmem,idx)", position);
132 _idx_bucket_phase -= bucket_cumul_size;
134 _idx_local_idx = position;
135 _idx_bucket_phase = position - bucket_cumul_size_prev;
138 bucket_cumul_size_prev = bucket_cumul_size;
146 position -= unit_bucket_cumul_sizes.back();
149 DASH_LOG_TRACE(
"GlobHeapPtr(gmem,idx)",
151 "unit:", _idx_unit_id,
152 "lidx:", _idx_local_idx,
153 "bucket:", _idx_bucket_idx,
154 "phase:", _idx_bucket_phase);
162 const MemSpaceT * gmem,
165 : _globmem(reinterpret_cast<const globmem_type *>(gmem)),
166 _bucket_cumul_sizes(&_globmem->_bucket_cumul_sizes),
167 _lbegin(_globmem->lbegin()),
169 _max_idx(gmem->
size() - 1),
170 _myid(gmem->team().
myid()),
176 DASH_LOG_TRACE(
"GlobHeapPtr(gmem,unit,lidx)",
178 "lidx:", local_index);
179 DASH_ASSERT_LT(unit, _bucket_cumul_sizes->size(),
"invalid unit id");
181 for (size_type unit = 0; unit < _idx_unit_id; ++unit) {
182 auto prec_unit_local_size = (*_bucket_cumul_sizes)[unit].back();
183 _idx += prec_unit_local_size;
185 increment(local_index);
186 DASH_LOG_TRACE(
"GlobHeapPtr(gmem,unit,lidx) >",
189 "unit:", _idx_unit_id,
190 "lidx:", _idx_local_idx,
191 "bucket:", _idx_bucket_idx,
192 "phase:", _idx_bucket_phase);
198 template<
typename E_,
typename M_>
201 : _globmem(other._globmem),
202 _bucket_cumul_sizes(other._bucket_cumul_sizes),
203 _lbegin(other._lbegin),
205 _max_idx(other._max_idx),
206 _idx_unit_id(other._idx_unit_id),
207 _idx_local_idx(other._idx_local_idx),
208 _idx_bucket_idx(other._idx_bucket_idx),
209 _idx_bucket_phase(other._idx_bucket_phase)
215 template<
typename E_,
typename M_>
219 _globmem = other._globmem;
220 _bucket_cumul_sizes = other._bucket_cumul_sizes;
221 _lbegin = other._lbegin;
223 _max_idx = other._max_idx;
224 _idx_unit_id = other._idx_unit_id;
225 _idx_local_idx = other._idx_local_idx;
226 _idx_bucket_idx = other._idx_bucket_idx;
227 _idx_bucket_phase = other._idx_bucket_phase;
238 DASH_LOG_TRACE_VAR(
"GlobHeapPtr.dart_gptr()", _idx);
244 DASH_LOG_TRACE_VAR(
"GlobHeapPtr.dart_gptr >", dart_gptr);
256 if (lptr !=
nullptr) {
257 return reference(static_cast<raw_pointer>(lptr));
269 index_type g_index)
const 271 DASH_LOG_TRACE_VAR(
"GlobHeapPtr.[]()", g_index);
274 auto lptr = git.local();
275 if (lptr !=
nullptr) {
276 return reference(lptr);
279 DASH_LOG_TRACE_VAR(
"GlobHeapPtr.[] >", gref);
290 return (_myid == _idx_unit_id);
298 if (_myid != _idx_unit_id) {
302 return (_lbegin + _idx_local_idx);
311 local_pos.unit = _idx_unit_id;
312 local_pos.index = _idx_local_idx;
327 inline index_type
pos()
const 396 inline self_t & operator+=(index_type offset)
402 inline self_t & operator-=(index_type offset)
408 inline self_t operator+(index_type offset)
const 411 res.increment(offset);
415 inline self_t operator-(index_type offset)
const 418 res.decrement(offset);
422 inline index_type operator+(
423 const self_t & other)
const 425 return _idx + other._idx;
428 inline index_type operator-(
429 const self_t & other)
const 431 return _idx - other._idx;
434 template<
typename E_,
typename M_>
435 inline bool operator<(const GlobHeapPtr<E_, M_> & other)
const 437 return (_idx < other._idx);
440 template<
typename E_,
typename M_>
441 inline bool operator<=(const GlobHeapPtr<E_, M_> & other)
const 443 return (_idx <= other._idx);
446 template<
typename E_,
typename M_>
449 return (_idx > other._idx);
452 template<
typename E_,
typename M_>
455 return (_idx >= other._idx);
458 template<
typename E_,
typename M_>
461 return _idx == other._idx;
464 template<
typename E_,
typename M_>
467 return _idx != other._idx;
474 void increment(
int offset)
476 DASH_LOG_TRACE(
"GlobHeapPtr.increment()",
478 "unit:", _idx_unit_id,
479 "lidx:", _idx_local_idx,
480 "bidx:", _idx_bucket_idx,
481 "bphase:", _idx_bucket_phase,
484 auto current_bucket_size =
485 (*_bucket_cumul_sizes)[_idx_unit_id][_idx_bucket_idx];
486 if (_idx_local_idx + offset < current_bucket_size) {
487 DASH_LOG_TRACE(
"GlobHeapPtr.increment",
"position current bucket");
489 _idx_bucket_phase += offset;
490 _idx_local_idx += offset;
492 DASH_LOG_TRACE(
"GlobHeapPtr.increment",
493 "position in succeeding bucket");
495 auto unit_id_max = _bucket_cumul_sizes->size() - 1;
496 for (; _idx_unit_id <= unit_id_max; ++_idx_unit_id) {
500 auto unit_bkt_sizes = (*_bucket_cumul_sizes)[_idx_unit_id];
501 auto unit_bkt_sizes_total = unit_bkt_sizes.back();
502 auto unit_num_bkts = unit_bkt_sizes.size();
503 DASH_LOG_TRACE(
"GlobHeapPtr.increment",
504 "unit:", _idx_unit_id,
505 "remaining offset:", offset,
506 "total local bucket size:", unit_bkt_sizes_total);
507 if (_idx_local_idx + offset >= unit_bkt_sizes_total) {
509 DASH_LOG_TRACE(
"GlobHeapPtr.increment",
510 "position in remote range");
512 offset -= (unit_bkt_sizes_total - _idx_local_idx);
513 if (_idx_unit_id == unit_id_max) {
515 _idx_bucket_idx = unit_num_bkts - 1;
516 auto last_bkt_size = unit_bkt_sizes.back();
517 if (unit_num_bkts > 1) {
518 last_bkt_size -= unit_bkt_sizes[_idx_bucket_idx-1];
520 _idx_bucket_phase = last_bkt_size + offset;
521 _idx_local_idx += unit_bkt_sizes_total + offset;
526 _idx_bucket_phase = 0;
529 DASH_LOG_TRACE(
"GlobHeapPtr.increment",
530 "position in local range",
531 "current bucket phase:", _idx_bucket_phase,
532 "cumul. bucket sizes:", unit_bkt_sizes);
533 _idx_local_idx += offset;
535 for (; _idx_bucket_idx < unit_num_bkts; ++_idx_bucket_idx) {
536 auto cumul_bucket_size = unit_bkt_sizes[_idx_bucket_idx];
537 if (_idx_local_idx < cumul_bucket_size) {
538 auto cumul_prev = _idx_bucket_idx > 0
539 ? unit_bkt_sizes[_idx_bucket_idx-1]
542 _idx_bucket_phase = _idx_local_idx - cumul_prev;
553 DASH_LOG_TRACE(
"GlobHeapPtr.increment >",
555 "unit:", _idx_unit_id,
556 "lidx:", _idx_local_idx,
557 "bidx:", _idx_bucket_idx,
558 "bphase:", _idx_bucket_phase);
564 void decrement(
int offset)
566 DASH_LOG_TRACE(
"GlobHeapPtr.decrement()",
568 "unit:", _idx_unit_id,
569 "lidx:", _idx_local_idx,
570 "bidx:", _idx_bucket_idx,
571 "bphase:", _idx_bucket_phase,
575 "offset " << offset <<
" is out of range");
578 if (offset <= _idx_bucket_phase) {
580 _idx_bucket_phase -= offset;
581 _idx_local_idx -= offset;
584 auto first_unit = _idx_unit_id;
585 for (; _idx_unit_id >= 0; --_idx_unit_id) {
586 auto unit_bkt_sizes = (*_bucket_cumul_sizes)[_idx_unit_id];
587 auto unit_bkt_sizes_total = unit_bkt_sizes.back();
588 auto unit_num_bkts = unit_bkt_sizes.size();
589 if (_idx_unit_id != first_unit) {
591 _idx_bucket_idx = unit_num_bkts - 1;
592 _idx_local_idx = unit_bkt_sizes_total - 1;
593 auto last_bkt_size = unit_bkt_sizes.back();
594 if (unit_num_bkts > 1) {
595 last_bkt_size -= unit_bkt_sizes[_idx_bucket_idx-1];
597 _idx_bucket_phase = last_bkt_size - 1;
599 if (offset <= _idx_local_idx) {
602 for (; _idx_bucket_idx >= 0; --_idx_bucket_idx) {
603 auto bucket_size = unit_bkt_sizes[_idx_bucket_idx];
604 if (offset <= _idx_bucket_phase) {
606 _idx_local_idx -= offset;
607 _idx_bucket_phase -= offset;
612 _idx_local_idx -= (_idx_bucket_phase + 1);
613 offset -= (_idx_bucket_phase + 1);
614 _idx_bucket_phase = unit_bkt_sizes[_idx_bucket_idx-1] - 1;
619 offset -= _idx_local_idx;
626 DASH_LOG_TRACE(
"GlobHeapPtr.decrement >",
628 "unit:", _idx_unit_id,
629 "lidx:", _idx_local_idx,
630 "bidx:", _idx_bucket_idx,
631 "bphase:", _idx_bucket_phase);
643 template <
typename ElementType,
class MemSpaceT>
651 if (last._globmem ==
first._globmem) {
655 return std::numeric_limits<typename MemSpaceT::index_type>::max();
659 template <
typename ElementType,
class MemSpaceT>
660 std::ostream &operator<<(
663 std::ostringstream ss;
664 ss <<
"dash::GlobHeapPtr<" <<
typeid(ElementType).name() <<
">(" 665 <<
"gidx:" << gptr._idx <<
", (" 666 <<
"unit:" << gptr._idx_unit_id <<
", " 667 <<
"lidx:" << gptr._idx_local_idx <<
"), (" 668 <<
"bidx:" << gptr._idx_bucket_idx <<
", " 669 <<
"bphase:" << gptr._idx_bucket_phase <<
")" 671 return operator<<(os, ss.str());
676 #endif // DASH__MEMORY__GLOB_HEAP_PTR_H__INCLUDED reference operator*() const
Dereference operator.
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
self_t operator--(int)
Postfix decrement operator.
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
size_t size()
Return the number of units in the global team.
This class is a simple memory pool which holds allocates elements of size ValueType.
local_index lpos() const
Unit and local offset at the pointer's position.
index_type pos() const
Position of the pointer in global index space.
GlobHeapPtr(const MemSpaceT *gmem, index_type position=0)
Constructor, creates a global pointer on global memory from global offset in logical storage order...
self_t & operator=(const GlobHeapPtr< E_, M_ > &other)
Assignment operator.
GlobHeapPtr(const MemSpaceT *gmem, team_unit_t unit, index_type local_index)
Constructor, creates a global pointer on global memory from unit and local offset in logical storage ...
self_t operator++(int)
Postfix increment operator.
index_type gpos() const
Position of the pointer in global index range.
dart_gptr_t dart_gptr() const
Explicit conversion to dart_gptr_t.
A Team instance specifies a subset of all available units.
GlobHeapPtr()
Default constructor.
const globmem_type & globmem() const
The instance of GlobStaticMem used by this pointer to resolve addresses in global memory...
GlobHeapPtr(const GlobHeapPtr< E_, M_ > &other)
Copy constructor.
Iterator on global buckets.
self_t & operator--()
Prefix decrement operator.
DART Global pointer type.
self_t global() const
Map pointer to global index domain.
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
bool is_local() const
Checks whether the element referenced by this global pointer is in the calling unit's local memory...
globmem_type & globmem()
The instance of GlobStaticMem used by this pointer to resolve addresses in global memory...
self_t & operator++()
Prefix increment operator.
#define DART_UNDEFINED_UNIT_ID
Undefined unit ID.
local_pointer local() const
Conversion to local bucket pointer.
reference operator[](index_type g_index) const
Subscript operator, returns global reference to element at given global index.
dash::gptrdiff_t distance(GlobPtr< T, MemSpaceT > gbegin, GlobPtr< T, MemSpaceT > gend)
Returns the number of hops from gbegin to gend.