Nektar++
Comm.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File Comm.h
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Base communication class
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 #ifndef NEKTAR_LIB_UTILITIES_COMM_H
35 #define NEKTAR_LIB_UTILITIES_COMM_H
36 
37 #include <vector>
38 #include <memory>
39 #include <type_traits>
40 
43 
47 
48 namespace Nektar
49 {
50 namespace LibUtilities
51 {
52 // Forward declarations
53 class Comm;
54 
55 /// Pointer to a Communicator object.
56 typedef std::shared_ptr<Comm> CommSharedPtr;
57 
58 /// Datatype of the NekFactory used to instantiate classes derived from
59 /// the EquationSystem class.
61 
63 
64 /// Type of operation to perform in AllReduce.
66 {
71 };
72 
73 const char* const ReduceOperatorMap[] =
74 {
75  "ReduceSum",
76  "ReduceMax",
77  "ReduceMin"
78 };
79 
80 /// Base communications class
81 class Comm : public std::enable_shared_from_this<Comm>
82 {
83 public:
84  LIB_UTILITIES_EXPORT Comm(int narg, char *arg[]);
85  LIB_UTILITIES_EXPORT virtual ~Comm();
86 
87  LIB_UTILITIES_EXPORT inline void Finalise();
88 
89  /// Returns number of processes
90  LIB_UTILITIES_EXPORT inline int GetSize();
91  LIB_UTILITIES_EXPORT inline int GetRank();
92  LIB_UTILITIES_EXPORT inline const std::string &GetType() const;
93 
94  /// Block execution until all processes reach this point
95  LIB_UTILITIES_EXPORT inline void Block();
96 
97  /// Return the time in seconds
99 
100  template <class T> void Send(int pProc, T &pData);
101  template <class T> void Recv(int pProc, T &pData);
102  template <class T>
103  void SendRecv(int pSendProc, T &pSendData, int pRecvProc, T &pRecvData);
104  template <class T>
105  void SendRecvReplace(int pSendProc, int pRecvProc, T &pData);
106 
107  template <class T> void AllReduce(T &pData, enum ReduceOperator pOp);
108 
109  template <class T> void AlltoAll(T &pSendData, T &pRecvData);
110  template <class T1, class T2>
111  void AlltoAllv(T1 &pSendData,
112  T2 &pSendDataSizeMap,
113  T2 &pSendDataOffsetMap,
114  T1 &pRecvData,
115  T2 &pRecvDataSizeMap,
116  T2 &pRecvDataOffsetMap);
117 
118  template <class T> void AllGather(T &pSendData, T &pRecvData);
119  template <class T>
120  void AllGatherv(T &pSendData,
121  T &pRecvData,
122  Array<OneD, int> &pRecvDataSizeMap,
123  Array<OneD, int> &pRecvDataOffsetMap);
124  template <class T>
125  void AllGatherv(T &pRecvData,
126  Array<OneD, int> &pRecvDataSizeMap,
127  Array<OneD, int> &pRecvDataOffsetMap);
128 
129  template <class T> void Bcast(T &data, int rootProc);
130 
131  template <class T>
132  void Exscan(T &pData, const enum ReduceOperator pOp, T &ans);
133 
134  template <class T> T Gather(const int rootProc, T &val);
135  template <class T> T Scatter(const int rootProc, T &pData);
136 
137  LIB_UTILITIES_EXPORT inline CommSharedPtr CommCreateIf(int flag);
138 
139  LIB_UTILITIES_EXPORT inline void SplitComm(int pRows, int pColumns);
140  LIB_UTILITIES_EXPORT inline CommSharedPtr GetRowComm();
141  LIB_UTILITIES_EXPORT inline CommSharedPtr GetColumnComm();
142 
143  LIB_UTILITIES_EXPORT inline bool TreatAsRankZero(void);
144  LIB_UTILITIES_EXPORT inline bool IsSerial(void);
145  LIB_UTILITIES_EXPORT inline bool RemoveExistingFiles(void);
146 
147 protected:
148  int m_size; ///< Number of processes
149  std::string m_type; ///< Type of communication
150  CommSharedPtr m_commRow; ///< Row communicator
151  CommSharedPtr m_commColumn; ///< Column communicator
152 
153  Comm();
154 
155  virtual void v_Finalise() = 0;
156  virtual int v_GetRank() = 0;
157  virtual void v_Block() = 0;
158  virtual NekDouble v_Wtime() = 0;
159  virtual void v_Send(void *buf, int count, CommDataType dt, int dest) = 0;
160  virtual void v_Recv(void *buf, int count, CommDataType dt, int source) = 0;
161  virtual void v_SendRecv(void *sendbuf, int sendcount, CommDataType sendtype,
162  int dest, void *recvbuf, int recvcount,
163  CommDataType recvtype, int source) = 0;
164  virtual void v_SendRecvReplace(void *buf, int count, CommDataType dt,
165  int pSendProc, int pRecvProc) = 0;
166  virtual void v_AllReduce(void *buf, int count, CommDataType dt,
167  enum ReduceOperator pOp) = 0;
168  virtual void v_AlltoAll(void *sendbuf, int sendcount, CommDataType sendtype,
169  void *recvbuf, int recvcount,
170  CommDataType recvtype) = 0;
171  virtual void v_AlltoAllv(void *sendbuf, int sendcounts[], int sensdispls[],
172  CommDataType sendtype, void *recvbuf,
173  int recvcounts[], int rdispls[],
174  CommDataType recvtype) = 0;
175  virtual void v_AllGather(void *sendbuf, int sendcount, CommDataType sendtype,
176  void *recvbuf, int recvcount,
177  CommDataType recvtype) = 0;
178  virtual void v_AllGatherv(void *sendbuf, int sendcount, CommDataType sendtype,
179  void *recvbuf, int recvcounts[], int rdispls[],
180  CommDataType recvtype) = 0;
181  virtual void v_AllGatherv(void *recvbuf, int recvcounts[], int rdispls[],
182  CommDataType recvtype) = 0;
183  virtual void v_Bcast(void *buffer, int count, CommDataType dt,
184  int root) = 0;
185 
186  virtual void v_Exscan(Array<OneD, unsigned long long> &pData,
187  const enum ReduceOperator pOp,
189 
190  virtual void v_Gather(void *sendbuf, int sendcount, CommDataType sendtype,
191  void *recvbuf, int recvcount, CommDataType recvtype,
192  int root) = 0;
193  virtual void v_Scatter(void *sendbuf, int sendcount, CommDataType sendtype,
194  void *recvbuf, int recvcount, CommDataType recvtype,
195  int root) = 0;
196 
197  virtual CommSharedPtr v_CommCreateIf(int flag) = 0;
198  virtual void v_SplitComm(int pRows, int pColumns) = 0;
199  virtual bool v_TreatAsRankZero(void) = 0;
200  virtual bool v_IsSerial(void) = 0;
201  LIB_UTILITIES_EXPORT virtual bool v_RemoveExistingFiles(void);
202 };
203 
204 /**
205  *
206  */
207 inline void Comm::Finalise()
208 {
209  v_Finalise();
210 }
211 
212 /**
213  *
214  */
215 inline int Comm::GetSize()
216 {
217  return m_size;
218 }
219 
220 /**
221  *
222  */
223 inline int Comm::GetRank()
224 {
225  return v_GetRank();
226 }
227 
228 /**
229  *
230  */
231 inline const std::string &Comm::GetType() const
232 {
233  return m_type;
234 }
235 
236 /**
237  *
238  */
239 inline void Comm::Block()
240 {
241  v_Block();
242 }
243 
244 /**
245  *
246  */
247 inline double Comm::Wtime()
248 {
249  return v_Wtime();
250 }
251 
252 template <class T> void Comm::Send(int pProc, T &pData)
253 {
257 }
258 
259 template <class T> void Comm::Recv(int pProc, T &pData)
260 {
264 }
265 
266 /**
267  *
268  */
269 template <class T>
270 void Comm::SendRecv(int pSendProc, T &pSendData, int pRecvProc, T &pRecvData)
271 {
278 }
279 
280 /**
281  *
282  */
283 template <class T>
284 void Comm::SendRecvReplace(int pSendProc, int pRecvProc, T &pData)
285 {
289  pRecvProc);
290 }
291 
292 /**
293  *
294  */
295 template <class T> void Comm::AllReduce(T &pData, enum ReduceOperator pOp)
296 {
300 }
301 
302 template <class T> void Comm::AlltoAll(T &pSendData, T &pRecvData)
303 {
304  static_assert(
306  "AlltoAll only valid with Array or vector arguments.");
307  int sendSize = CommDataTypeTraits<T>::GetCount(pSendData);
308  int recvSize = CommDataTypeTraits<T>::GetCount(pRecvData);
309  ASSERTL0(sendSize == recvSize,
310  "Send and Recv arrays have incompatible sizes in AlltoAll");
311 
312  int count = sendSize / GetSize();
313  ASSERTL0(count * GetSize() == sendSize,
314  "Array size incompatible with size of communicator");
315 
318  CommDataTypeTraits<T>::GetPointer(pRecvData), count,
320 }
321 
322 /**
323  *
324  */
325 template <class T1, class T2>
326 void Comm::AlltoAllv(T1 &pSendData,
327  T2 &pSendDataSizeMap,
328  T2 &pSendDataOffsetMap,
329  T1 &pRecvData,
330  T2 &pRecvDataSizeMap,
331  T2 &pRecvDataOffsetMap)
332 {
333  static_assert(
335  "AlltoAllv only valid with Array or vector arguments.");
336  static_assert(
337  std::is_same<T2, std::vector<int>>::value ||
338  std::is_same<T2, Array<OneD, int>>::value,
339  "Alltoallv size and offset maps should be integer vectors.");
340  v_AlltoAllv(
342  (int *)CommDataTypeTraits<T2>::GetPointer(pSendDataSizeMap),
343  (int *)CommDataTypeTraits<T2>::GetPointer(pSendDataOffsetMap),
346  (int *)CommDataTypeTraits<T2>::GetPointer(pRecvDataSizeMap),
347  (int *)CommDataTypeTraits<T2>::GetPointer(pRecvDataOffsetMap),
349 }
350 
351 template <class T> void Comm::AllGather(T &pSendData, T &pRecvData)
352 {
353  BOOST_STATIC_ASSERT_MSG(
355  "AllGather only valid with Array or vector arguments.");
356 
357  int sendSize = CommDataTypeTraits<T>::GetCount(pSendData);
358  int recvSize = sendSize;
359 
360  pRecvData = T(recvSize * GetSize());
361 
362  v_AllGather(CommDataTypeTraits<T>::GetPointer(pSendData), sendSize,
364  CommDataTypeTraits<T>::GetPointer(pRecvData), recvSize,
366 }
367 
368 /**
369  *
370  */
371 template <class T>
372 void Comm::AllGatherv(T &pSendData,
373  T &pRecvData,
374  Array<OneD, int> &pRecvDataSizeMap,
375  Array<OneD, int> &pRecvDataOffsetMap)
376 {
377  BOOST_STATIC_ASSERT_MSG(
379  "AllGatherv only valid with Array or vector arguments.");
380 
381  int sendSize = CommDataTypeTraits<T>::GetCount(pSendData);
382 
383  v_AllGatherv(CommDataTypeTraits<T>::GetPointer(pSendData), sendSize,
386  pRecvDataSizeMap.get(),
387  pRecvDataOffsetMap.get(),
389 }
390 
391 /**
392  *
393  */
394 template <class T>
395 void Comm::AllGatherv(T &pRecvData,
396  Array<OneD, int> &pRecvDataSizeMap,
397  Array<OneD, int> &pRecvDataOffsetMap)
398 {
399  BOOST_STATIC_ASSERT_MSG(
401  "AllGatherv only valid with Array or vector arguments.");
402 
404  pRecvDataSizeMap.get(),
405  pRecvDataOffsetMap.get(),
407 }
408 
409 /**
410  *
411  */
412 template <class T> void Comm::Bcast(T &pData, int pRoot)
413 {
417 }
418 
419 template <class T>
420 void Comm::Exscan(T &pData, const enum ReduceOperator pOp, T &ans)
421 {
424  "Input and output array sizes don't match");
429 }
430 
431 /**
432  * Concatenate all the input arrays, in rank order, onto the process with rank
433  * == rootProc
434  */
435 template <class T> T Comm::Gather(const int rootProc, T &val)
436 {
437  static_assert(
439  "Gather only valid with Array or vector arguments.");
440  bool amRoot = (GetRank() == rootProc);
441  unsigned nEl = CommDataTypeTraits<T>::GetCount(val);
442 
443  unsigned nOut = amRoot ? GetSize() * nEl : 0;
444  T ans(nOut);
445  void *recvbuf = amRoot ? CommDataTypeTraits<T>::GetPointer(ans) : NULL;
446 
447  v_Gather(CommDataTypeTraits<T>::GetPointer(val), nEl,
448  CommDataTypeTraits<T>::GetDataType(), recvbuf, nEl,
450  return ans;
451 }
452 /**
453  * Scatter pData across ranks in chunks of len(pData)/num_ranks
454  */
455 template <class T> T Comm::Scatter(const int rootProc, T &pData)
456 {
457  static_assert(
459  "Scatter only valid with Array or vector arguments.");
460 
461  bool amRoot = (GetRank() == rootProc);
462  unsigned nEl = CommDataTypeTraits<T>::GetCount(pData) / GetSize();
463 
464  void *sendbuf = amRoot ? CommDataTypeTraits<T>::GetPointer(pData) : NULL;
465  T ans(nEl);
466 
468  CommDataTypeTraits<T>::GetPointer(ans), nEl,
470  return ans;
471 }
472 
473 /**
474  * @brief If the flag is non-zero create a new communicator.
475  */
476 inline CommSharedPtr Comm::CommCreateIf(int flag)
477 {
478  return v_CommCreateIf(flag);
479 }
480 
481 /**
482  * @brief Splits this communicator into a grid of size pRows*pColumns
483  * and creates row and column communicators. By default the communicator
484  * is a single row.
485  */
486 inline void Comm::SplitComm(int pRows, int pColumns)
487 {
488  v_SplitComm(pRows, pColumns);
489 }
490 
491 /**
492  * @brief Retrieve the row communicator to which this process belongs.
493  */
494 inline CommSharedPtr Comm::GetRowComm()
495 {
496  if (!m_commRow.get())
497  {
498  return shared_from_this();
499  }
500  else
501  {
502  return m_commRow;
503  }
504 }
505 
506 /**
507  * @brief Retrieve the column communicator to which this process
508  * belongs.
509  */
510 inline CommSharedPtr Comm::GetColumnComm()
511 {
512  if (!m_commColumn.get())
513  {
514  return shared_from_this();
515  }
516  else
517  {
518  return m_commColumn;
519  }
520 }
521 
522 inline bool Comm::TreatAsRankZero(void)
523 {
524  return v_TreatAsRankZero();
525 }
526 
527 inline bool Comm::IsSerial(void)
528 {
529  return v_IsSerial();
530 }
531 
532 inline bool Comm::RemoveExistingFiles(void)
533 {
534  return v_RemoveExistingFiles();
535 }
536 
537 }
538 }
539 
540 #endif
void Exscan(T &pData, const enum ReduceOperator pOp, T &ans)
Definition: Comm.h:420
void Recv(int pProc, T &pData)
Definition: Comm.h:259
void AllReduce(T &pData, enum ReduceOperator pOp)
Definition: Comm.h:295
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
virtual void v_Recv(void *buf, int count, CommDataType dt, int source)=0
ReduceOperator
Type of operation to perform in AllReduce.
Definition: Comm.h:65
virtual bool v_IsSerial(void)=0
CommSharedPtr m_commColumn
Column communicator.
Definition: Comm.h:151
virtual void v_AllGather(void *sendbuf, int sendcount, CommDataType sendtype, void *recvbuf, int recvcount, CommDataType recvtype)=0
virtual void v_AllReduce(void *buf, int count, CommDataType dt, enum ReduceOperator pOp)=0
std::string m_type
Type of communication.
Definition: Comm.h:149
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
bool TreatAsRankZero(void)
Definition: Comm.h:522
void AllGatherv(T &pSendData, T &pRecvData, Array< OneD, int > &pRecvDataSizeMap, Array< OneD, int > &pRecvDataOffsetMap)
Definition: Comm.h:372
array buffer
Definition: GsLib.hpp:61
virtual void v_AlltoAllv(void *sendbuf, int sendcounts[], int sensdispls[], CommDataType sendtype, void *recvbuf, int recvcounts[], int rdispls[], CommDataType recvtype)=0
virtual void v_Send(void *buf, int count, CommDataType dt, int dest)=0
bool IsSerial(void)
Definition: Comm.h:527
CommFactory & GetCommFactory()
CommSharedPtr m_commRow
Row communicator.
Definition: Comm.h:150
void AlltoAll(T &pSendData, T &pRecvData)
Definition: Comm.h:302
void SendRecv(int pSendProc, T &pSendData, int pRecvProc, T &pRecvData)
Definition: Comm.h:270
virtual void v_SendRecv(void *sendbuf, int sendcount, CommDataType sendtype, int dest, void *recvbuf, int recvcount, CommDataType recvtype, int source)=0
virtual bool v_RemoveExistingFiles(void)
virtual void v_Exscan(Array< OneD, unsigned long long > &pData, const enum ReduceOperator pOp, Array< OneD, unsigned long long > &ans)=0
virtual void v_Bcast(void *buffer, int count, CommDataType dt, int root)=0
NekDouble Wtime()
Return the time in seconds.
Definition: Comm.h:247
virtual void v_AllGatherv(void *sendbuf, int sendcount, CommDataType sendtype, void *recvbuf, int recvcounts[], int rdispls[], CommDataType recvtype)=0
CommSharedPtr GetRowComm()
Retrieve the row communicator to which this process belongs.
Definition: Comm.h:494
virtual void v_Gather(void *sendbuf, int sendcount, CommDataType sendtype, void *recvbuf, int recvcount, CommDataType recvtype, int root)=0
virtual CommSharedPtr v_CommCreateIf(int flag)=0
T Scatter(const int rootProc, T &pData)
Definition: Comm.h:455
LibUtilities::NekFactory< std::string, Comm, int, char ** > CommFactory
Datatype of the NekFactory used to instantiate classes derived from the EquationSystem class...
Definition: Comm.h:60
virtual void v_Scatter(void *sendbuf, int sendcount, CommDataType sendtype, void *recvbuf, int recvcount, CommDataType recvtype, int root)=0
#define LIB_UTILITIES_EXPORT
virtual int v_GetRank()=0
void Bcast(T &data, int rootProc)
Definition: Comm.h:412
virtual bool v_TreatAsRankZero(void)=0
virtual void v_Finalise()=0
void Send(int pProc, T &pData)
Definition: Comm.h:252
void AlltoAllv(T1 &pSendData, T2 &pSendDataSizeMap, T2 &pSendDataOffsetMap, T1 &pRecvData, T2 &pRecvDataSizeMap, T2 &pRecvDataOffsetMap)
Definition: Comm.h:326
double NekDouble
void SplitComm(int pRows, int pColumns)
Splits this communicator into a grid of size pRows*pColumns and creates row and column communicators...
Definition: Comm.h:486
Base communications class.
Definition: Comm.h:81
const char *const ReduceOperatorMap[]
Definition: Comm.h:73
virtual void v_AlltoAll(void *sendbuf, int sendcount, CommDataType sendtype, void *recvbuf, int recvcount, CommDataType recvtype)=0
void Block()
Block execution until all processes reach this point.
Definition: Comm.h:239
T Gather(const int rootProc, T &val)
Definition: Comm.h:435
const std::string & GetType() const
Definition: Comm.h:231
void AllGather(T &pSendData, T &pRecvData)
Definition: Comm.h:351
void SendRecvReplace(int pSendProc, int pRecvProc, T &pData)
Definition: Comm.h:284
int GetSize()
Returns number of processes.
Definition: Comm.h:215
virtual void v_SplitComm(int pRows, int pColumns)=0
CommSharedPtr CommCreateIf(int flag)
If the flag is non-zero create a new communicator.
Definition: Comm.h:476
virtual NekDouble v_Wtime()=0
virtual void v_Block()=0
virtual void v_SendRecvReplace(void *buf, int count, CommDataType dt, int pSendProc, int pRecvProc)=0
int m_size
Number of processes.
Definition: Comm.h:148
bool RemoveExistingFiles(void)
Definition: Comm.h:532
Provides a generic Factory class.
Definition: NekFactory.hpp:103
CommSharedPtr GetColumnComm()
Retrieve the column communicator to which this process belongs.
Definition: Comm.h:510