Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DReducible.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
26 #ifndef GALOIS_DISTACCUMULATOR_H
27 #define GALOIS_DISTACCUMULATOR_H
28 
29 #include <limits>
30 #include "galois/Galois.h"
31 #include "galois/Reduction.h"
32 #include "galois/AtomicHelpers.h"
33 #include "galois/runtime/LWCI.h"
35 
36 namespace galois {
37 
44 template <typename Ty>
48 
50  Ty local_mdata, global_mdata;
51 
52 #ifdef GALOIS_USE_LCI
53 
56  inline void reduce_lwci() {
57  lc_alreduce(&local_mdata, &global_mdata, sizeof(Ty),
58  &galois::runtime::internal::ompi_op_sum<Ty>, lc_col_ep);
59  }
60 #else
61 
64  inline void reduce_mpi() {
65  if (typeid(Ty) == typeid(int32_t)) {
66  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_INT, MPI_SUM,
67  MPI_COMM_WORLD);
68  } else if (typeid(Ty) == typeid(int64_t)) {
69  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG, MPI_SUM,
70  MPI_COMM_WORLD);
71  } else if (typeid(Ty) == typeid(uint32_t)) {
72  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED, MPI_SUM,
73  MPI_COMM_WORLD);
74  } else if (typeid(Ty) == typeid(uint64_t)) {
75  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED_LONG, MPI_SUM,
76  MPI_COMM_WORLD);
77  } else if (typeid(Ty) == typeid(float)) {
78  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_FLOAT, MPI_SUM,
79  MPI_COMM_WORLD);
80  } else if (typeid(Ty) == typeid(double)) {
81  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_DOUBLE, MPI_SUM,
82  MPI_COMM_WORLD);
83  } else if (typeid(Ty) == typeid(long double)) {
84  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG_DOUBLE, MPI_SUM,
85  MPI_COMM_WORLD);
86  } else {
87  static_assert(true,
88  "Type of DGAccumulator not supported for MPI reduction");
89  }
90  }
91 #endif
92 
93 public:
96 
103  DGAccumulator& operator+=(const Ty& rhs) {
104  mdata += rhs;
105  return *this;
106  }
107 
113  void operator=(const Ty rhs) {
114  mdata.reset();
115  mdata += rhs;
116  }
117 
123  void set(const Ty rhs) {
124  mdata.reset();
125  mdata += rhs;
126  }
127 
133  Ty read_local() {
134  if (local_mdata == 0)
135  local_mdata = mdata.reduce();
136  return local_mdata;
137  }
138 
146  Ty read() { return global_mdata; }
147 
153  Ty reset() {
154  Ty retval = global_mdata;
155  mdata.reset();
156  local_mdata = global_mdata = 0;
157  return retval;
158  }
159 
169  Ty reduce(std::string runID = std::string()) {
170  std::string timer_str("ReduceDGAccum_" + runID);
171 
172  galois::CondStatTimer<GALOIS_COMM_STATS> reduceTimer(timer_str.c_str(),
173  "DGReducible");
174  reduceTimer.start();
175 
176  if (local_mdata == 0)
177  local_mdata = mdata.reduce();
178 
179 #ifdef GALOIS_USE_LCI
180  reduce_lwci();
181 #else
182  reduce_mpi();
183 #endif
184 
185  reduceTimer.stop();
186 
187  return global_mdata;
188  }
189 };
190 
192 
199 template <typename Ty>
200 class DGReduceMax {
203 
204  galois::GReduceMax<Ty> mdata; // local max reducer
205  Ty local_mdata, global_mdata;
206 
207 #ifdef GALOIS_USE_LCI
208 
211  inline void reduce_lwci() {
212  lc_alreduce(&local_mdata, &global_mdata, sizeof(Ty),
213  &galois::runtime::internal::ompi_op_max<Ty>, lc_col_ep);
214  }
215 #else
216 
219  inline void reduce_mpi() {
220  if (typeid(Ty) == typeid(int32_t)) {
221  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_INT, MPI_MAX,
222  MPI_COMM_WORLD);
223  } else if (typeid(Ty) == typeid(int64_t)) {
224  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG, MPI_MAX,
225  MPI_COMM_WORLD);
226  } else if (typeid(Ty) == typeid(uint32_t)) {
227  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED, MPI_MAX,
228  MPI_COMM_WORLD);
229  } else if (typeid(Ty) == typeid(uint64_t)) {
230  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED_LONG, MPI_MAX,
231  MPI_COMM_WORLD);
232  } else if (typeid(Ty) == typeid(float)) {
233  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_FLOAT, MPI_MAX,
234  MPI_COMM_WORLD);
235  } else if (typeid(Ty) == typeid(double)) {
236  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_DOUBLE, MPI_MAX,
237  MPI_COMM_WORLD);
238  } else if (typeid(Ty) == typeid(long double)) {
239  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG_DOUBLE, MPI_MAX,
240  MPI_COMM_WORLD);
241  } else {
242  static_assert(true, "Type of DGReduceMax not supported for MPI "
243  "reduction");
244  }
245  }
246 #endif
247 
248 public:
253  local_mdata = 0;
254  global_mdata = 0;
255  }
256 
262  void update(const Ty rhs) { mdata.update(rhs); }
263 
272  Ty read_local() {
273  if (local_mdata == 0)
274  local_mdata = mdata.reduce();
275  return local_mdata;
276  }
277 
284  Ty read() { return global_mdata; }
285 
292  Ty reset() {
293  Ty retval = global_mdata;
294  mdata.reset();
295  local_mdata = global_mdata = 0;
296  return retval;
297  }
298 
305  Ty reduce(std::string runID = std::string()) {
306  std::string timer_str("ReduceDGReduceMax_" + runID);
307 
308  galois::CondStatTimer<GALOIS_COMM_STATS> reduceTimer(timer_str.c_str(),
309  "DGReduceMax");
310 
311  reduceTimer.start();
312  if (local_mdata == 0)
313  local_mdata = mdata.reduce();
314 
315 #ifdef GALOIS_USE_LCI
316  reduce_lwci();
317 #else
318  reduce_mpi();
319 #endif
320  reduceTimer.stop();
321 
322  return global_mdata;
323  }
324 };
325 
327 
334 template <typename Ty>
335 class DGReduceMin {
338 
339  galois::GReduceMin<Ty> mdata; // local min reducer
340  Ty local_mdata, global_mdata;
341 
342 #ifdef GALOIS_USE_LCI
343 
346  inline void reduce_lwci() {
347  lc_alreduce(&local_mdata, &global_mdata, sizeof(Ty),
348  &galois::runtime::internal::ompi_op_min<Ty>, lc_col_ep);
349  }
350 #else
351 
354  inline void reduce_mpi() {
355  if (typeid(Ty) == typeid(int32_t)) {
356  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_INT, MPI_MIN,
357  MPI_COMM_WORLD);
358  } else if (typeid(Ty) == typeid(int64_t)) {
359  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG, MPI_MIN,
360  MPI_COMM_WORLD);
361  } else if (typeid(Ty) == typeid(uint32_t)) {
362  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED, MPI_MIN,
363  MPI_COMM_WORLD);
364  } else if (typeid(Ty) == typeid(uint64_t)) {
365  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_UNSIGNED_LONG, MPI_MIN,
366  MPI_COMM_WORLD);
367  } else if (typeid(Ty) == typeid(float)) {
368  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_FLOAT, MPI_MIN,
369  MPI_COMM_WORLD);
370  } else if (typeid(Ty) == typeid(double)) {
371  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_DOUBLE, MPI_MIN,
372  MPI_COMM_WORLD);
373  } else if (typeid(Ty) == typeid(long double)) {
374  MPI_Allreduce(&local_mdata, &global_mdata, 1, MPI_LONG_DOUBLE, MPI_MIN,
375  MPI_COMM_WORLD);
376  } else {
377  static_assert(true, "Type of DGReduceMin not supported for MPI "
378  "reduction");
379  }
380  }
381 #endif
382 
383 public:
388  local_mdata = std::numeric_limits<Ty>::max();
389  global_mdata = std::numeric_limits<Ty>::max();
390  ;
391  }
392 
398  void update(const Ty rhs) { mdata.update(rhs); }
399 
408  Ty read_local() {
409  if (local_mdata == std::numeric_limits<Ty>::max())
410  local_mdata = mdata.reduce();
411  return local_mdata;
412  }
413 
420  Ty read() { return global_mdata; }
421 
428  Ty reset() {
429  Ty retval = global_mdata;
430  mdata.reset();
431  local_mdata = global_mdata = std::numeric_limits<Ty>::max();
432  return retval;
433  }
434 
441  Ty reduce(std::string runID = std::string()) {
442  std::string timer_str("ReduceDGReduceMin_" + runID);
443 
444  galois::CondStatTimer<GALOIS_COMM_STATS> reduceTimer(timer_str.c_str(),
445  "DGReduceMin");
446 
447  reduceTimer.start();
448  if (local_mdata == std::numeric_limits<Ty>::max())
449  local_mdata = mdata.reduce();
450 
451 #ifdef GALOIS_USE_LCI
452  reduce_lwci();
453 #else
454  reduce_mpi();
455 #endif
456  reduceTimer.stop();
457 
458  return global_mdata;
459  }
460 };
461 
462 } // namespace galois
463 #endif
Ty read_local()
Read the local reduced max value; if it has never been reduced, it will attempt get the global value ...
Definition: DReducible.h:272
Distributed sum-reducer for getting the sum of some value across multiple hosts.
Definition: DReducible.h:45
Ty reset()
Reset this accumulator.
Definition: DReducible.h:292
void update(const Ty rhs)
Update the local min-reduced value.
Definition: DReducible.h:398
DGAccumulator & operator+=(const Ty &rhs)
Adds to accumulated value.
Definition: DReducible.h:103
void set(const Ty rhs)
Sets current value stored in accumulator.
Definition: DReducible.h:123
void reset()
Definition: Reduction.h:113
DGReduceMax()
Default constructor; initializes everything to 0.
Definition: DReducible.h:252
DGReduceMin()
Default constructor; initializes everything to the max value of the type.
Definition: DReducible.h:387
Ty reduce(std::string runID=std::string())
Do a min reduction across all hosts by sending data to all other hosts and reducing received data...
Definition: DReducible.h:441
Ty reset()
Reset this accumulator.
Definition: DReducible.h:428
Ty reset()
Reset the entire accumulator.
Definition: DReducible.h:153
Ty read_local()
Read the local reduced min value; if it has never been reduced, it will attempt get the global value ...
Definition: DReducible.h:408
Ty read()
Read the global reduced min value.
Definition: DReducible.h:420
LWCI header that includes lc.h (LCI library) and internal helper functions on arrays.
const Ty max(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:40
Contains declaration of DistStatManager, which reports runtime statistics of a distributed applicatio...
Distributed min-reducer for getting the min of some value across multiple hosts.
Definition: DReducible.h:335
NetworkInterface & getSystemNetworkInterface()
Get the network interface.
Definition: Network.cpp:131
void update(const Ty rhs)
Update the local max-reduced value.
Definition: DReducible.h:262
Distributed max-reducer for getting the max of some value across multiple hosts.
Definition: DReducible.h:200
void operator=(const Ty rhs)
Sets current value stored in accumulator.
Definition: DReducible.h:113
void start()
Definition: Timer.cpp:82
Ty read_local()
Read local accumulated value.
Definition: DReducible.h:133
T & reduce()
Returns the final reduction value.
Definition: Reduction.h:102
DGAccumulator()
Default constructor.
Definition: DReducible.h:95
Ty read()
Read the global reduced max value.
Definition: DReducible.h:284
Ty reduce(std::string runID=std::string())
Reduce data across all hosts, saves the value, and returns the reduced value.
Definition: DReducible.h:169
void update(T &&rhs)
Updates the thread local value by applying the reduction operator to current and newly provided value...
Definition: Reduction.h:90
A class that defines functions that a network interface in Galois should have.
Definition: Network.h:52
Ty reduce(std::string runID=std::string())
Do a max reduction across all hosts by sending data to all other hosts and reducing received data...
Definition: DReducible.h:305
Definition: Timer.h:88
Ty read()
Read the value returned by the last reduce call.
Definition: DReducible.h:146