DASH  0.3.0
GlobRef.h
1 #ifndef DASH__GLOBREF_H_
2 #define DASH__GLOBREF_H_
3 
4 #include <dash/GlobPtr.h>
5 #include <dash/Onesided.h>
6 #include <dash/iterator/internal/GlobRefBase.h>
7 
8 namespace dash {
9 
10 // forward declaration
11 template<typename T>
12 class GlobAsyncRef;
13 
14 // Forward declarations
15 template<typename T, class MemSpaceT> class GlobPtr;
16 
17 template<typename T>
18 class GlobRef
19 {
20  template<typename U>
21  friend std::ostream & operator<<(
22  std::ostream & os,
23  const GlobRef<U> & gref);
24 
25  template <typename ElementT>
26  friend class GlobRef;
27 
28 public:
29  using value_type = T;
30  using const_value_type = typename std::add_const<T>::type;
31  using nonconst_value_type = typename std::remove_const<T>::type;
32  using self_t = GlobRef<T>;
33  using const_type = GlobRef<const_value_type>;
34 
35 
36  template <class _T, class _M>
37  friend class GlobPtr;
38 
39  template <class _T, class _Pat, class _M, class _Ptr, class _Ref>
40  friend class GlobIter;
41 
42  template <class _T, class _Pat, class _M, class _Ptr, class _Ref>
43  friend class GlobViewIter;
44 
45 private:
50  template<class ElementT, class MemSpaceT>
51  explicit constexpr GlobRef(
53  const GlobPtr<ElementT, MemSpaceT> & gptr)
54  : GlobRef(gptr.dart_gptr())
55  { }
56 
57 public:
61  GlobRef() = delete;
62 
63  GlobRef(const GlobRef & other) = delete;
64 
69  explicit constexpr GlobRef(dart_gptr_t dart_gptr) noexcept
70  : _gptr(dart_gptr)
71  {
72  }
73 
82  template <
83  typename _T,
84  long = internal::enable_implicit_copy_ctor<value_type, _T>::value>
85  constexpr GlobRef(const GlobRef<_T>& gref) noexcept
86  : GlobRef(gref.dart_gptr())
87  {
88  }
89 
96  template <
97  typename _T,
98  int = internal::enable_explicit_copy_ctor<value_type, _T>::value>
99  explicit constexpr GlobRef(const GlobRef<_T>& gref) noexcept
100  : GlobRef(gref.dart_gptr())
101  {
102  }
103 
108  template <
109  typename _T,
110  long = internal::enable_implicit_copy_ctor<value_type, _T>::value>
111  constexpr GlobRef(const GlobAsyncRef<_T>& gref) noexcept
112  : _gptr(gref.dart_gptr())
113  {
114  }
115 
116  template <
117  typename _T,
118  int = internal::enable_explicit_copy_ctor<value_type, _T>::value>
119  explicit constexpr GlobRef(const GlobAsyncRef<_T>& gref) noexcept
120  : GlobRef(gref.dart_gptr())
121  {
122  }
123 
127  GlobRef(self_t&& other) noexcept
128  :_gptr(std::move(other._gptr))
129  {
130  DASH_LOG_TRACE("GlobRef.GlobRef(GlobRef &&)", _gptr);
131  }
132 
136  const self_t & operator=(const self_t & other) const
137  {
138  if (DART_GPTR_EQUAL(_gptr, other._gptr)) {
139  return *this;
140  }
141  set(static_cast<T>(other));
142  return *this;
143  }
144 
148  self_t& operator=(self_t&& other) noexcept {
149  DASH_LOG_TRACE("GlobRef.operator=(GlobRef &&)", _gptr);
150  operator=(other);
151  return *this;
152  }
153 
157  const self_t & operator=(const value_type& val) const {
158  set(val);
159  return *this;
160  }
161 
162 
163  operator nonconst_value_type() const {
164  DASH_LOG_TRACE("GlobRef.T()", "conversion operator");
165  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
166  nonconst_value_type t;
167  dash::internal::get_blocking(_gptr, &t, 1);
168  DASH_LOG_TRACE_VAR("GlobRef.T >", _gptr);
169  return t;
170  }
171 
172  template <typename ValueT>
173  bool operator==(const GlobRef<ValueT> & other) const {
174  ValueT val = other.get();
175  return operator==(val);
176  }
177 
178  template <typename ValueT>
179  bool operator!=(const GlobRef<ValueT> & other) const {
180  return !(*this == other);
181  }
182 
183  template<typename ValueT>
184  constexpr bool operator==(const ValueT& value) const
185  {
186  return static_cast<T>(*this) == value;
187  }
188 
189  template<typename ValueT>
190  constexpr bool operator!=(const ValueT& value) const
191  {
192  return !(*this == value);
193  }
194 
195  void
196  set(const value_type & val) const {
197  static_assert(std::is_same<value_type, nonconst_value_type>::value,
198  "Cannot modify value referenced by GlobRef<const T>!");
199 
200  DASH_LOG_TRACE_VAR("GlobRef.set()", val);
201  DASH_LOG_TRACE_VAR("GlobRef.set", _gptr);
202  // TODO: Clarify if dart-call can be avoided if
203  // _gptr->is_local()
204  dash::internal::put_blocking(_gptr, &val, 1);
205  DASH_LOG_TRACE_VAR("GlobRef.set >", _gptr);
206  }
207 
208  nonconst_value_type get() const {
209  DASH_LOG_TRACE("T GlobRef.get()", "explicit get");
210  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
211  nonconst_value_type t;
212  dash::internal::get_blocking(_gptr, &t, 1);
213  return t;
214  }
215 
216  void get(nonconst_value_type *tptr) const {
217  DASH_LOG_TRACE("GlobRef.get(T*)", "explicit get into provided ptr");
218  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
219  dash::internal::get_blocking(_gptr, tptr, 1);
220  }
221 
222  void get(nonconst_value_type& tref) const {
223  DASH_LOG_TRACE("GlobRef.get(T&)", "explicit get into provided ref");
224  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
225  dash::internal::get_blocking(_gptr, &tref, 1);
226  }
227 
228  void
229  put(const_value_type& tref) const {
230  static_assert(std::is_same<value_type, nonconst_value_type>::value,
231  "Cannot assign to GlobRef<const T>!");
232  DASH_LOG_TRACE("GlobRef.put(T&)", "explicit put of provided ref");
233  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
234  dash::internal::put_blocking(_gptr, &tref, 1);
235  }
236 
237  void
238  put(const_value_type* tptr) const {
239  static_assert(std::is_same<value_type, nonconst_value_type>::value,
240  "Cannot modify value referenced by GlobRef<const T>!");
241  DASH_LOG_TRACE("GlobRef.put(T*)", "explicit put of provided ptr");
242  DASH_LOG_TRACE_VAR("GlobRef.T()", _gptr);
243  dash::internal::put_blocking(_gptr, tptr, 1);
244  }
245 
246  const self_t &
247  operator+=(const nonconst_value_type& ref) const {
248  static_assert(std::is_same<value_type, nonconst_value_type>::value,
249  "Cannot modify value referenced by GlobRef<const T>!");
250 #if 0
251  // TODO: Alternative implementation, possibly more efficient:
252  T add_val = ref;
253  T old_val;
254  dart_ret_t result = dart_fetch_and_op(
255  _gptr,
256  reinterpret_cast<void *>(&add_val),
257  reinterpret_cast<void *>(&old_val),
260  dash::Team::All().dart_id());
261  dart_flush(_gptr);
262  #else
263  nonconst_value_type val = operator nonconst_value_type();
264  val += ref;
265  operator=(val);
266  #endif
267  return *this;
268  }
269 
270  const self_t &
271  operator-=(const nonconst_value_type& ref) const {
272  static_assert(std::is_same<value_type, nonconst_value_type>::value,
273  "Cannot modify value referenced by GlobRef<const T>!");
274  nonconst_value_type val = operator nonconst_value_type();
275  val -= ref;
276  operator=(val);
277  return *this;
278  }
279 
280  const self_t &
281  operator++() const {
282  static_assert(std::is_same<value_type, nonconst_value_type>::value,
283  "Cannot modify value referenced by GlobRef<const T>!");
284  nonconst_value_type val = operator nonconst_value_type();
285  operator=(++val);
286  return *this;
287  }
288 
289  nonconst_value_type
290  operator++(int) const {
291  static_assert(std::is_same<value_type, nonconst_value_type>::value,
292  "Cannot modify value referenced by GlobRef<const T>!");
293  nonconst_value_type val = operator nonconst_value_type();
294  nonconst_value_type res = val++;
295  operator=(val);
296  return res;
297  }
298 
299  const self_t &
300  operator--() const {
301  static_assert(std::is_same<value_type, nonconst_value_type>::value,
302  "Cannot modify value referenced by GlobRef<const T>!");
303  nonconst_value_type val = operator nonconst_value_type();
304  operator=(--val);
305  return *this;
306  }
307 
308  nonconst_value_type
309  operator--(int) const {
310  static_assert(std::is_same<value_type, nonconst_value_type>::value,
311  "Cannot modify value referenced by GlobRef<const T>!");
312  nonconst_value_type val = operator nonconst_value_type();
313  nonconst_value_type res = val--;
314  operator=(val);
315  return res;
316  }
317 
318  const self_t &
319  operator*=(const_value_type& ref) const {
320  static_assert(std::is_same<value_type, nonconst_value_type>::value,
321  "Cannot modify value referenced by GlobRef<const T>!");
322  nonconst_value_type val = operator nonconst_value_type();
323  val *= ref;
324  operator=(val);
325  return *this;
326  }
327 
328  const self_t &
329  operator/=(const_value_type& ref) const {
330  static_assert(std::is_same<value_type, nonconst_value_type>::value,
331  "Cannot modify value referenced by GlobRef<const T>!");
332  nonconst_value_type val = operator nonconst_value_type();
333  val /= ref;
334  operator=(val);
335  return *this;
336  }
337 
338  const self_t &
339  operator^=(const_value_type& ref) const {
340  static_assert(std::is_same<value_type, nonconst_value_type>::value,
341  "Cannot modify value referenced by GlobRef<const T>!");
342  nonconst_value_type val = operator nonconst_value_type();
343  val ^= ref;
344  operator=(val);
345  return *this;
346  }
347 
348  constexpr dart_gptr_t dart_gptr() const noexcept {
349  return _gptr;
350  }
351 
356  bool is_local() const {
357  dart_team_unit_t luid;
358  dart_team_myid(_gptr.teamid, &luid);
359  return _gptr.unitid == luid.id;
360  }
361 
366  template<typename MEMTYPE>
368  member(size_t offs) const {
369  dart_gptr_t dartptr = _gptr;
370  DASH_ASSERT_RETURNS(
371  dart_gptr_incaddr(&dartptr, offs),
372  DART_OK);
374  }
375 
379  template<class MEMTYPE, class P=T>
382  const MEMTYPE P::*mem) const {
383  // TODO: Thaaaat ... looks hacky.
384  auto offs = (size_t) & (reinterpret_cast<P*>(0)->*mem);
385  return member<typename internal::add_const_from_type<T, MEMTYPE>::type>(offs);
386  }
387 
391  inline void swap(dash::GlobRef<T> & b) const{
392  static_assert(std::is_same<value_type, nonconst_value_type>::value,
393  "Cannot modify value referenced by GlobRef<const T>!");
394  auto tmp = static_cast<T>(*this);
395  *this = b;
396  b = tmp;
397  }
398 
399 private:
400  dart_gptr_t _gptr{};
401 };
402 
403 template<typename T>
404 std::ostream & operator<<(
405  std::ostream & os,
406  const GlobRef<T> & gref)
407 {
408  char buf[100]; //
409  sprintf(buf,
410  "(%06X|%02X|%04X|%04X|%016lX)",
411  gref._gptr.unitid,
412  gref._gptr.flags,
413  gref._gptr.segid,
414  gref._gptr.teamid,
415  gref._gptr.addr_or_offs.offset);
416  os << dash::typestr(gref) << buf;
417  return os;
418 }
419 
423 template<typename T>
424 inline void swap(dash::GlobRef<T> && a, dash::GlobRef<T> && b){
425  a.swap(b);
426 }
427 
431 template <class MemSpaceT, class T>
432 inline auto addressof(dash::GlobRef<T> const & ref)
433 {
434  return dash::GlobPtr<T, MemSpaceT>(ref.dart_gptr());
435 }
436 
437 } // namespace dash
438 
439 #endif // DASH__GLOBREF_H_
GlobRef(self_t &&other) noexcept
Move Constructor.
Definition: GlobRef.h:127
Reduce operands to their sum.
Definition: Operation.h:163
GlobRef()=delete
Reference semantics forbid declaration without definition.
int16_t teamid
The team associated with the allocation.
Definition: dart_globmem.h:89
GlobRef< typename internal::add_const_from_type< T, MEMTYPE >::type > member(size_t offs) const
Get a global ref to a member of a certain type at the specified offset.
Definition: GlobRef.h:368
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
auto addressof(dash::GlobRef< T > const &ref)
specialization for unqualified calls to swap
Definition: GlobRef.h:432
Signals success.
Definition: dart_types.h:33
constexpr GlobRef(dart_gptr_t dart_gptr) noexcept
Constructor, creates an GlobRef object referencing an element in global memory.
Definition: GlobRef.h:69
constexpr GlobRef(const GlobRef< _T > &gref) noexcept
Copy constructor, implicit if at least one of the following conditions is satisfied: 1) value_type an...
Definition: GlobRef.h:85
dart_unit_t unitid
The unit holding the memory element.
Definition: dart_globmem.h:83
void swap(dash::GlobRef< T > &b) const
specialization which swappes the values of two global references
Definition: GlobRef.h:391
Data type for storing a unit ID relative to a team.
Definition: dart_types.h:180
const self_t & operator=(const self_t &other) const
Copy Assignment.
Definition: GlobRef.h:136
dart_gptr_t dart_gptr() const
Returns the underlying DART global pointer.
Definition: GlobAsyncRef.h:302
DART Global pointer type.
Definition: dart_globmem.h:77
Type trait for mapping to DART data types.
Definition: Types.h:96
#define DART_GPTR_EQUAL(gptr1_, gptr2_)
Compare two global pointers.
Definition: dart_globmem.h:128
self_t & operator=(self_t &&other) noexcept
Move Assignment: Redirects to Copy Assignment.
Definition: GlobRef.h:148
dart_ret_t
Return values of functions in the DART interface.
Definition: dart_types.h:30
const self_t & operator=(const value_type &val) const
Value-assignment operator.
Definition: GlobRef.h:157
std::string typestr(const T &obj)
Returns string containing the type name of the given object.
Definition: TypeInfo.h:20
bool is_local() const
Checks whether the globally referenced element is in the calling unit&#39;s local memory.
Definition: GlobRef.h:356
Pointer in global memory space with random access arithmetics.
Definition: GlobPtr.h:33
GlobRef< typename internal::add_const_from_type< T, MEMTYPE >::type > member(const MEMTYPE P::*mem) const
Get the member via pointer to member.
Definition: GlobRef.h:381
dart_ret_t dart_fetch_and_op(dart_gptr_t gptr, const void *value, void *result, dart_datatype_t dtype, dart_operation_t op)
Perform an element-wise atomic update on the value of type dtype pointed to by gptr by applying the o...
Global value reference for asynchronous / non-blocking operations.
Definition: GlobAtomicRef.h:17
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
Query the underlying dart_operation_t for arbitrary binary operations.
Definition: Operation.h:111
constexpr GlobRef(const GlobAsyncRef< _T > &gref) noexcept
Constructor to convert GlobAsyncRef to GlobRef.
Definition: GlobRef.h:111
dart_ret_t dart_flush(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on a certain unit...