DASH  0.3.0
GlobAtomicAsyncRef.h
1 #ifndef DASH__ATOMIC_ASYNC_GLOBREF_H_
2 #define DASH__ATOMIC_ASYNC_GLOBREF_H_
3 
4 #include <dash/Types.h>
5 #include <dash/GlobPtr.h>
6 #include <dash/algorithm/Operation.h>
7 #include <dash/GlobAsyncRef.h>
8 #include <dash/GlobRef.h>
9 
10 
11 namespace dash {
12 
13 // forward decls
14 template<typename T>
15 class Atomic;
16 
17 template<class T>
18 class GlobRef;
19 
24 template<typename T>
26 {
27  /* Notes on type compatibility:
28  *
29  * - The general support of atomic operations on values of type T is
30  * checked in `dash::Atomic` and is not verified here.
31  * - Whether arithmetic operations (like `fetch_add`) are supported
32  * for values of type T is implicitly tested in the DASH operation
33  * types (like `dash::plus<T>`) and is not verified here.
34  *
35  */
36 
37  template<typename U>
38  friend std::ostream & operator<<(
39  std::ostream & os,
40  const GlobAsyncRef<U> & gref);
41 
42 public:
43  using value_type = T;
44  using const_value_type = typename std::add_const<T>::type;
45  using nonconst_value_type = typename std::remove_const<T>::type;
46  using atomic_t = dash::Atomic<T>;
47  using const_atomic_t = typename dash::Atomic<const_value_type>;
48  using nonconst_atomic_t = typename dash::Atomic<nonconst_value_type>;
52 
53 
54 private:
55  dart_gptr_t _gptr{};
56 
61  template<typename GlobMemT>
62  explicit GlobAsyncRef(
65  : GlobAsyncRef(gptr.dart_gptr())
66  { }
67 
72  template<typename GlobMemT>
73  explicit GlobAsyncRef(
76  : GlobAsyncRef(gptr.dart_gptr())
77  {
78  static_assert(std::is_same<value_type, const_value_type>::value,
79  "Cannot create GlobAsyncRef<Atomic<T>> from GlobPtr<Atomic<const T>>!");
80  }
81 
82 
83 
84 public:
88  GlobAsyncRef() = delete;
89 
90 
96  : _gptr(dart_gptr)
97  {
98  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>(dart_gptr_t)", dart_gptr);
99  }
100 
109  template<typename _T,
110  int = internal::enable_implicit_copy_ctor<value_type, _T>::value>
112  : GlobAsyncRef(gref.dart_gptr())
113  { }
114 
121  template<typename _T,
122  long = internal::enable_explicit_copy_ctor<value_type, _T>::value>
123  explicit
125  : GlobAsyncRef(gref.dart_gptr())
126  { }
127 
128  template<typename _T,
129  int = internal::enable_implicit_copy_ctor<value_type, _T>::value>
131  : GlobAsyncRef(gref.dart_gptr())
132  { }
133 
134  template<typename _T,
135  long = internal::enable_explicit_copy_ctor<value_type, _T>::value>
136  explicit
137  GlobAsyncRef(const GlobRef<dash::Atomic<_T>>& gref)
138  : GlobAsyncRef(gref.dart_gptr())
139  { }
140 
141  ~GlobAsyncRef() = default;
142 
147  GlobAsyncRef(self_t && other) = default;
148 
152  self_t & operator=(const self_t & other) = delete;
153 
157  self_t & operator=(self_t && other) = default;
158 
159  inline bool operator==(const self_t & other) const noexcept
160  {
161  return this->get() == other.get();
162  }
163 
164  inline bool operator!=(const self_t & other) const noexcept
165  {
166  return !(*this == other);
167  }
168 
169  inline bool operator==(const T & value) const = delete;
170  inline bool operator!=(const T & value) const = delete;
171 
172  dart_gptr_t dart_gptr() const {
173  return _gptr;
174  }
175 
180  bool is_local() const {
181  return dash::internal::is_local(_gptr);
182  }
183 
194  T operator=(const T & value) const {
195  store(value);
196  return value;
197  }
198 
203  void set(const T & value) const
204  {
205  static_assert(std::is_same<value_type, nonconst_value_type>::value,
206  "Cannot modify value referenced by GlobAsyncRef<Atomic<const T>>!");
207  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.set()", value);
208  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.set", _gptr);
210  _gptr,
211  &value,
212  1,
215  DASH_ASSERT_EQ(DART_OK, ret, "dart_accumulate failed");
216  DASH_LOG_DEBUG("GlobAsyncRef<Atomic>.set >");
217  }
218 
224  void set(const T * ptr) const
225  {
226  static_assert(std::is_same<value_type, nonconst_value_type>::value,
227  "Cannot modify value referenced by GlobAsyncRef<Atomic<const T>>!");
228  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.set()", *ptr);
229  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.set", _gptr);
231  _gptr,
232  ptr,
233  1,
236  DASH_ASSERT_EQ(DART_OK, ret, "dart_accumulate failed");
237  DASH_LOG_DEBUG("GlobAsyncRef<Atomic>.set >");
238  }
239 
240 
245  inline void store(const T & value) const {
246  set(value);
247  }
248 
254  inline void store(const T * ptr) const {
255  set(ptr);
256  }
257 
264  T get() const
265  {
266  DASH_LOG_DEBUG("GlobAsyncRef<Atomic>.get()");
267  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.get", _gptr);
268  nonconst_value_type nothing;
269  nonconst_value_type result;
271  _gptr,
272  &nothing,
273  &result,
275  DART_OP_NO_OP);
276  dart_flush_local(_gptr);
277  DASH_ASSERT_EQ(DART_OK, ret, "dart_accumulate failed");
278  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.get >", result);
279  return result;
280  }
281 
289  void get(T * result) const
290  {
291  DASH_LOG_DEBUG("GlobAsyncRef<Atomic>.get()");
292  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.get", _gptr);
293  nonconst_value_type nothing;
295  _gptr,
296  &nothing,
297  result,
299  DART_OP_NO_OP);
300  DASH_ASSERT_EQ(DART_OK, ret, "dart_accumulate failed");
301  }
302 
309  inline T load() const {
310  return get();
311  }
312 
316  template<typename BinaryOp>
317  void op(
318  BinaryOp binary_op,
320  const T & value) const
321  {
322  static_assert(std::is_same<value_type, nonconst_value_type>::value,
323  "Cannot modify value referenced by GlobAsyncRef<Atomic<const T>>!");
324  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.op()", value);
325  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.op", _gptr);
326  DASH_LOG_TRACE("GlobAsyncRef<Atomic>.op", "dart_accumulate");
328  _gptr,
329  &value,
330  1,
332  binary_op.dart_operation());
333  DASH_ASSERT_EQ(DART_OK, ret, "dart_accumulate_blocking_local failed");
334  }
335 
342  template<typename BinaryOp>
343  void fetch_op(
344  BinaryOp binary_op,
346  const T & value,
347  T * result) const
348  {
349  static_assert(std::is_same<value_type, nonconst_value_type>::value,
350  "Cannot modify value referenced by GlobAsyncRef<Atomic<const T>>!");
351  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.fetch_op()", value);
352  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.fetch_op", _gptr);
353  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.fetch_op", typeid(value).name());
355  _gptr,
356  &value,
357  result,
359  binary_op.dart_operation());
360  DASH_ASSERT_EQ(DART_OK, ret, "dart_fetch_op failed");
361  }
362 
366  void exchange(
367  const T & value,
368  T * result) const {
369  fetch_op(dash::second<nonconst_value_type>(), value, result);
370  }
371 
384  const T & expected,
385  const T & desired,
386  T * result) const {
387  static_assert(std::is_same<value_type, nonconst_value_type>::value,
388  "Cannot modify value referenced by GlobAsyncRef<Atomic<const T>>!");
389  DASH_LOG_DEBUG_VAR("GlobAsyncRef<Atomic>.compare_exchange()", desired);
390  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.compare_exchange", _gptr);
391  DASH_LOG_TRACE_VAR("GlobAsyncRef<Atomic>.compare_exchange", expected);
392  DASH_LOG_TRACE_VAR(
393  "GlobAsyncRef<Atomic>.compare_exchange", typeid(desired).name());
395  _gptr,
396  &desired,
397  &expected,
398  result,
400  DASH_ASSERT_EQ(DART_OK, ret, "dart_compare_and_swap failed");
401  }
402 
407  void add(const T & value) const
408  {
409  op(dash::plus<nonconst_value_type>(), value);
410  }
411 
420  void fetch_add(
422  const T & value,
424  T * result) const
425  {
426  fetch_op(dash::plus<nonconst_value_type>(), value, result);
427  }
428 
433  void sub(const T & value) const
434  {
435  op(dash::plus<nonconst_value_type>(), -value);
436  }
437 
446  void fetch_sub (
448  const T & value,
450  T * result) const
451  {
452  fetch_op(dash::plus<nonconst_value_type>(), -value, result);
453  }
454 
459  void multiply(const T & value) const
460  {
462  }
463 
474  const T & value,
476  T * result) const
477  {
478  fetch_op(dash::multiply<nonconst_value_type>(), value, result);
479  }
480 
484  void flush() const
485  {
486  DASH_ASSERT_RETURNS(
487  dart_flush(_gptr),
488  DART_OK
489  );
490  }
491 
492 };
493 
494 } // namespace dash
495 
496 #endif // DASH__ATOMIC_ASYNC_GLOBREF_H_
Returns second operand.
Definition: Operation.h:218
Reduce operands to their sum.
Definition: Operation.h:163
void store(const T &value) const
Set the value of the shared atomic variable.
void fetch_sub(const T &value, T *result) const
Atomic fetch-and-sub operation on the referenced shared value.
dart_ret_t dart_accumulate_blocking_local(dart_gptr_t gptr, const void *values, size_t nelem, dart_datatype_t dtype, dart_operation_t op)
Perform an element-wise atomic update on the values pointed to by gptr by applying the operation op w...
GlobAsyncRef(dart_gptr_t dart_gptr)
Constructor, creates an GlobRef object referencing an element in global memory.
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
Signals success.
Definition: dart_types.h:33
GlobAsyncRef(const GlobAsyncRef< dash::Atomic< _T >> &gref)
Copy constructor: Implicit if at least one of the following conditions is satisfied: 1) value_type an...
void compare_exchange(const T &expected, const T &desired, T *result) const
Atomically compares the value with the value of expected and if thosei are bitwise-equal, replaces the former with desired.
No operation.
Definition: dart_types.h:97
void add(const T &value) const
DASH specific variant which is faster than fetch_add but does not return value.
dart_ret_t dart_flush_local(dart_gptr_t gptr)
Guarantee local completion of all outstanding operations involving a segment on a certain unit...
Type wrapper to mark any trivial type atomic.
dart_ret_t dart_accumulate(dart_gptr_t gptr, const void *values, size_t nelem, dart_datatype_t dtype, dart_operation_t op)
Perform an element-wise atomic update on the values pointed to by gptr by applying the operation op w...
Type trait for mapping to punned DART data type for reduce operations.
Definition: Types.h:104
void sub(const T &value) const
DASH specific variant which is faster than fetch_sub but does not return value.
void fetch_op(BinaryOp binary_op, const T &value, T *result) const
Atomic fetch-and-op operation on the referenced shared value.
Reduce operands to their product.
Definition: Operation.h:182
dart_ret_t dart_compare_and_swap(dart_gptr_t gptr, const void *value, const void *compare, void *result, dart_datatype_t dtype)
Atomically replace the single value pointed to by gptr with the the value in value if it is equal to ...
void exchange(const T &value, T *result) const
Atomically exchanges value.
void multiply(const T &value) const
DASH specific variant which is faster than fetch_mul but does not return value.
bool operator==(const GlobAsyncRef< ValueT > &other)=delete
Disallow implicit comparison with other global references.
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
void fetch_add(const T &value, T *result) const
Atomic fetch-and-add operation on the referenced shared value.
constexpr dart_gptr_t dart_gptr() const DASH_NOEXCEPT
The pointer&#39;s underlying global address.
Definition: GlobPtr.h:203
dart_ret_t
Return values of functions in the DART interface.
Definition: dart_types.h:30
Pointer in global memory space with random access arithmetics.
Definition: GlobPtr.h:33
void store(const T *ptr) const
Set the value of the shared atomic variable.
void flush() const
Flush all pending asynchronous operations on this asynchronous reference.
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...
Replace Value.
Definition: dart_types.h:95
void op(BinaryOp binary_op, const T &value) const
Atomically executes specified operation on the referenced shared value.
void fetch_multiply(const T &value, T *result) const
Atomic fetch-and-multiply operation on the referenced shared value.
Global value reference for asynchronous / non-blocking operations.
Definition: GlobAtomicRef.h:17
T load() const
Load the value of the shared atomic variable.
self_t & operator=(self_t &&other)=default
MOVE Assignment.
nonconst_value_type get() const
Return the value referenced by this GlobAsyncRef.
Definition: GlobAsyncRef.h:226
T operator=(const T &value) const
atomically assigns value
dart_ret_t dart_flush(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on a certain unit...
bool is_local() const
Checks whether the globally referenced element is in the calling unit&#39;s local memory.