DASH  0.3.0
Utils.h
1 #ifndef DASH__COARRAY_UTILS_H__
2 #define DASH__COARRAY_UTILS_H__
3 
4 #include <dash/Types.h>
5 
6 #define DART_TAG_SYNC_IMAGES 10016;
7 
17 namespace dash {
18 namespace coarray {
19 
30  return dash::myid();
31 }
32 
43 inline ssize_t num_images() {
44  return dash::size();
45 }
46 
56 inline void sync_all(){
57  dash::barrier();
58 }
59 
74 template<typename Container>
75 inline void sync_images(const Container & image_ids){
76  using element = typename Container::value_type;
77 
78  auto myid = this_image();
79 
80  if(std::find(image_ids.begin(),
81  image_ids.end(),
82  static_cast<element>(myid)) == image_ids.end())
83  {
84  // I do not participate
85  return;
86  }
87 
88  auto root = global_unit_t{
89  *(std::min(image_ids.begin(), image_ids.end()))};
90  auto tag = DART_TAG_SYNC_IMAGES;
91  // DART does not specify if nullptr is allowed as target
92  char buffer = 0;
93 
94  if(myid == root){
95  // I am root, recv messages from leaves
96  std::for_each(image_ids.begin(), image_ids.end(), [&](const element & el){
97  if(el != root){
99  tag,
100  global_unit_t{el}
101  );
102  }
103  });
104  } else {
105  // I am a leave, send message to root
106  dart_send(&buffer, 1, DART_TYPE_BYTE,
107  tag,
108  global_unit_t{root});
109  }
110 
111  // Second phase: recieve message from root
112  DASH_LOG_DEBUG("Begin second phase of sync_images");
113  if(myid == root){
114  std::for_each(image_ids.begin(), image_ids.end(), [&](const element & el)
115  {
116  if(el != root){
118  tag,
119  global_unit_t{el}
120  );
121  }
122  });
123  } else {
125  tag,
126  global_unit_t{root}
127  );
128  }
129 }
130 
141 template<typename T>
142 void cobroadcast(Coarray<T> & coarr, const team_unit_t & master){
143  using value_type = typename Coarray<T>::value_type;
144  const dash::dart_storage<value_type> ds(coarr.local_size());
145  DASH_ASSERT_RETURNS(
146  dart_bcast(coarr.lbegin(),
147  ds.nelem,
148  ds.dtype,
149  master,
150  coarr.team().dart_id()),
151  DART_OK);
152 }
153 
162 template<typename T, typename BinaryOp>
163 void coreduce(Coarray<T> & coarr,
164  const BinaryOp &op,
165  team_unit_t master = team_unit_t{-1})
166 {
167  using value_type = typename Coarray<T>::value_type;
168  using index_type = typename Coarray<T>::index_type;
169 
170  static_assert(dash::dart_datatype<value_type>::value != DART_TYPE_UNDEFINED,
171  "Cannot reduce unknown type!");
172 
173  constexpr auto ndim = Coarray<T>::ndim();
174  const auto team_dart_id = coarr.team().dart_id();
175  bool broadcast_result = (master < 0);
176  if(master < 0){master = team_unit_t{0};}
177 
178  // position of first element on master
179  const auto & global_coords = coarr.pattern().global(master,
180  std::array<index_type,ndim> {});
181  const auto & global_idx = coarr.pattern().at(global_coords);
182 
183  const auto dart_gptr = (coarr.begin() + global_idx).dart_gptr();
184  const dash::dart_storage<value_type> ds(coarr.local_size());
185 
186  // as source and destination location is equal, master must not contribute
187  // in accumulation as otherwise it's value is counted twice
188  if(coarr.team().myid() != master){
189  DASH_ASSERT_RETURNS(
191  dart_gptr,
192  coarr.lbegin(),
193  ds.nelem,
194  ds.dtype,
195  op.dart_operation()
196  ),
197  DART_OK);
198  }
199  if(broadcast_result){
200  dart_flush(dart_gptr);
201  dart_barrier(team_dart_id);
202  DASH_ASSERT_RETURNS(
203  dart_bcast(coarr.lbegin(),
204  ds.nelem,
205  ds.dtype,
206  master,
207  team_dart_id),
208  DART_OK);
209  }
210 }
211 
212 } // namespace co_array
213 } // namespace dash
214 
215 
216 #endif /* DASH__COARRAY_UTILS_H__ */
217 
dart_ret_t dart_send(const void *sendbuf, size_t nelem, dart_datatype_t dtype, int tag, dart_global_unit_t unit)
DART Equivalent to MPI send.
void sync_images(const Container &image_ids)
Blocks until all selected units reach this statement.
Definition: Utils.h:75
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
ssize_t num_images()
Return the number of units in the global team.
Definition: Utils.h:43
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.
Definition: AllOf.h:8
Signals success.
Definition: dart_types.h:33
void sync_all()
blocks until all units reach this statement.
Definition: Utils.h:56
struct dash::unit_id< dash::global_unit, dart_global_unit_t > global_unit_t
Unit ID to use for global IDs.
Definition: Types.h:332
dart_ret_t dart_bcast(void *buf, size_t nelem, dart_datatype_t dtype, dart_team_unit_t root, dart_team_t team)
DART Equivalent to MPI broadcast.
dash::global_unit_t this_image()
Shortcut to query the global unit ID of the calling unit.
Definition: Utils.h:29
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...
#define DART_TYPE_BYTE
integral data types
Definition: dart_types.h:125
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
void cobroadcast(Coarray< T > &coarr, const team_unit_t &master)
Broadcasts the value on master to all other members of this co_array.
Definition: Utils.h:142
dart_ret_t dart_barrier(dart_team_t team)
DART Equivalent to MPI_Barrier.
Type trait for mapping to DART data types.
Definition: Types.h:96
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
dart_ret_t dart_recv(void *recvbuf, size_t nelem, dart_datatype_t dtype, int tag, dart_global_unit_t unit)
DART Equivalent to MPI recv.
GlobIter find(GlobIter first, GlobIter last, const ElementType &value)
Returns an iterator to the first element in the range [first,last) that compares equal to val...
Definition: Find.h:22
void barrier()
A global barrier involving all units.
A fortran style coarray.
Definition: Coarray.h:184
Convencience wrapper to determine the DART type and number of elements required for the given templat...
Definition: Types.h:295
void for_each(const GlobInputIt &first, const GlobInputIt &last, UnaryFunction func)
Invoke a function on every element in a range distributed by a pattern.
Definition: ForEach.h:32
void coreduce(Coarray< T > &coarr, const BinaryOp &op, team_unit_t master=team_unit_t{-1})
Performes a broadside reduction of the Coarray images.
Definition: Utils.h:163
dart_ret_t dart_flush(dart_gptr_t gptr)
Guarantee completion of all outstanding operations involving a segment on a certain unit...