PlasCom2  1.0
XPACC Multi-physics simluation application
COMM.H
Go to the documentation of this file.
1 #ifndef _COMM_H_
8 #define _COMM_H_
9 #include "mpi.h"
10 #include <cstdlib>
11 
12 #include "primitive_utilities.H"
13 
14 namespace ix {
15 
17  namespace comm {
22 
27  class MobileObject
28  {
29  protected:
30  void *_buf;
31  bool _mine;
32  int _bsize;
33  public:
34  MobileObject(): _buf(NULL), _mine(false), _bsize(0) {};
35  void **GetBufPtr() { return(_buf ? &_buf : NULL); };
36  const void *GetBuffer() const { return (_buf); };
37  void *GetBuffer() {return (_buf); };
38  int BufSize() { return(_bsize); };
39  virtual int PrepareBuffer(size_t bsize);
40  virtual int Pack(void **inbuf = NULL);
41  virtual int UnPack(const void *outbuf = NULL);
42  virtual void DestroyBuffer()
43  {
44  if(_buf && _mine)
45  delete [] (char*)_buf;
46  _buf = NULL;
47  _mine = false;
48  _bsize = 0;
49  };
50  virtual ~MobileObject()
51  {
52  DestroyBuffer();
53  };
54  };
55 
63  {
64  private:
65  int _rank;
66  MPI_Comm _comm;
67  MPI_Comm _cart_comm;
69  bool _master;
70  bool _own_comm;
71  bool _initd;
72  int _error;
73  int _rc;
74  int _nproc;
75  std::vector<MPI_Request> _send_requests;
76  std::vector<MPI_Request> _recv_requests;
77  std::vector<int> _send_tags;
78  std::vector<int> _recv_tags;
79  std::vector<MPI_Status> _status;
80  std::vector<int> _cart_coords;
81  std::vector<int> _cart_dims;
82  std::vector<int> _cart_periodic;
83  public:
84  int RenewCommunicator(MPI_Comm &inComm);
85  MPI_Comm GetCommunicator() const{ return (_comm); };
86  int SetCommunicator(MPI_Comm &inComm){
87  return(RenewCommunicator(inComm));
88  };
89  void TakeOwnership(){_own_comm = true;};
90  MPI_Datatype IntegerTypeID; // = MPI_INTEGER;
91 
93  CommunicatorObject(MPI_Comm &incomm);
94  CommunicatorObject(int* narg,char*** args);
96 
97  MPI_Datatype ResolveDataType(const comm::DataTypes &dt);
98  MPI_Op ResolveOp(const comm::Ops &op);
99  int Split(int color,int key,CommunicatorObject &newcomm);
100  int WaitRecv(int recvid);
101  // wait on any and all messages
102  int WaitAll();
103  // clear up any persistent requests
104  void ClearRequests();
105  int NOpenRequests() { return(_send_requests.size() + _recv_requests.size()); };
106  int Initialize(CommunicatorObject &incomm);
107  int Initialize(int* narg = NULL,char*** args = NULL);
108  bool Good() { return(_initd); };
109  int SetExit(int errin){return(_error = errin);};
110  int SetErr(int errin){return(_error = errin);};
111  void ClearErr(){_error = 0;};
112  int Check(comm::Ops op=comm::MAXOP);
113  int NProc(){return(_nproc);}
114  int Rank();
115  int CartRank(){ return (_cart_rank); };
116  std::string Hostname();
117  std::vector<int> &CartCoordinates(){return(_cart_coords);};
118  std::vector<int> &CartDimensions(){return(_cart_dims);};
119  int CartNeighbors(std::vector<int> &neighborRanks);
120  MPI_Comm CartComm(){return(_cart_comm);};
121  MPI_Comm World(){return(_comm);};
122  MPI_Comm Comm(){return(_comm);};
123  int Finalize();
124  int Barrier(){return(MPI_Barrier(_comm));};
125  int Size();
126  int ComputeCartesianDims(int numNodes,int numDims);
127  int InitializeCartesianTopology(int numNodes,int numDims,std::vector<int> &dimDir,
128  const std::vector<int> &isPeriodic,bool reOrder,
129  CommunicatorObject &cartComm);
131  int StartSend(unsigned int rid);
132  int SendAll();
133  int StartRecv(unsigned int rid);
134  int RecvAll();
135  int BroadCast(std::string &sval,int root_rank = 0);
136  int BroadCast(MobileObject *mo,int root_rank = 0);
137  int _ASend(void *buf,int sendsize,unsigned int remote_rank,int tag = 0);
138  int _SetSend(void *buf,int sendsize,unsigned int remote_rank,int tag = 0);
139  int _ARecv(void *buf,int recvsize,unsigned int remote_rank,int tag = 0);
140  int _SetRecv(void *buf,int recvsize,unsigned int remote_rank,int tag = 0);
141  int _AllGatherv(void *sendbuf,int mysendcnt,int datasize,void *recvbuf);
142  int _Send(void *buf,int sendsize,unsigned int remote_rank,int tag = 0);
143  int _Recv(void *buf,int recvsize,unsigned int remote_rank,int tag = 0);
144  // Native support for Mobile Objects
145  int _BroadCastMOV(std::vector<MobileObject *> &mos,int root_rank=0);
146  int _GatherMO(MobileObject *sPtr,std::vector<MobileObject *> &rVec,int sndcnt,int root = 0);
147  int _GatherMOV(std::vector<MobileObject *> &sVec,std::vector<MobileObject *> &rVec,
148  std::vector<int> &nsend_all,int root = 0);
149  int _AllGatherMO(MobileObject *sPtr,std::vector<MobileObject *> &rVec,int sndcnt=1);
150  int _AllGatherMOV(std::vector<MobileObject *> &sVec,std::vector<MobileObject *> &rVec,
151  std::vector<int> &nsend_all);
152 
153 
154  template<typename DataType>
155  int ASendBuf(DataType *sendBuf,size_t nVal,unsigned int remote_rank,
156  int tag = -1)
157  {
158  int sizeofdata = sizeof(DataType);
159  return(_ASend(sendBuf,sizeofdata*nVal,remote_rank,tag));
160  };
161 
162  template<typename DataType>
163  int ARecvBuf(DataType *recvbuf,size_t nVal,unsigned int remote_rank,
164  int tag=0)
165  {
166  int sizeofdata = sizeof(DataType);
167  return(_ARecv(recvbuf,sizeofdata*nVal,remote_rank,tag));
168  };
169 
170  template<typename DataType>
171  int ASend(std::vector<DataType> &sendbuf,unsigned int remote_rank,
172  int tag = 0)
173  {
174  int sizeofdata = sizeof(DataType);
175  int sendcnt = sendbuf.size();
176  return (_ASend(&sendbuf[0],sizeofdata*sendcnt,remote_rank,tag));
177  };
178 
179  template<typename DataType>
180  int ASend(std::vector<DataType> &sendbuf,unsigned int startIndex,
181  unsigned int sendSize,unsigned int remote_rank,
182  int tag = 0)
183  {
184  int sizeofdata = sizeof(DataType);
185  return (_ASend(&sendbuf[startIndex],sizeofdata*sendSize,remote_rank,tag));
186  };
187 
188  template<typename DataType>
189  int SetSend(std::vector<DataType> &sendbuf,unsigned int remote_rank,
190  int tag = 0)
191  {
192  int sizeofdata = sizeof(DataType);
193  int sendcnt = sendbuf.size();
194  return(_SetSend(&sendbuf[0],sendcnt*sizeofdata,remote_rank,tag));
195  };
196 
197  template<typename DataType>
198  int SetRecv(std::vector<DataType> &recvbuf,unsigned int remote_rank,
199  int tag = 0)
200  {
201  int sizeofdata = sizeof(DataType);
202  int recvcnt = recvbuf.size();
203  return(_SetRecv(&recvbuf[0],recvcnt*sizeofdata,remote_rank,tag));
204  };
205 
206  template<typename DataType>
207  int ARecv(std::vector<DataType> &recvbuf,unsigned int remote_rank,
208  int tag=0)
209  {
210  int sizeofdata = sizeof(DataType);
211  int recvcnt = recvbuf.size();
212  return(_ARecv(&recvbuf[0],sizeofdata*recvcnt,remote_rank,tag));
213  };
214 
215  template<typename DataType>
216  int ARecv(std::vector<DataType> &recvbuf,unsigned int startIndex,
217  unsigned int numRecv,unsigned int remote_rank,
218  int tag=0)
219  {
220  int sizeofdata = sizeof(DataType);
221  return(_ARecv(&recvbuf[startIndex],sizeofdata*numRecv,remote_rank,tag));
222  };
223 
224  template<typename DataType>
225  int StreamBroadCast(DataType &inData,int root_rank=0)
226  {
227  int numBytes = 0;
228  if(_rank == root_rank){
229  std::ostringstream Ostr;
230  Ostr << inData;
231  std::string sendString(Ostr.str());
232  numBytes = sendString.size();
233  _rc = MPI_Bcast(&numBytes,1,MPI_INT,root_rank,_comm);
234  if(_rc == MPI_SUCCESS){
235  const char *sendData = sendString.c_str();
236  _rc = MPI_Bcast((void *)sendData,numBytes,MPI_CHAR,root_rank,_comm);
237  }
238  } else {
239  _rc = MPI_Bcast(&numBytes,1,MPI_INT,root_rank,_comm);
240  if(_rc == MPI_SUCCESS){
241  char *recvData = new char [numBytes+1];
242  _rc = MPI_Bcast(recvData,numBytes,MPI_CHAR,root_rank,_comm);
243  recvData[numBytes] = '\0';
244  std::istringstream Istr(recvData);
245  Istr >> inData;
246  delete [] recvData;
247  }
248  }
249  return(_rc);
250  };
251 
252  template<typename DataType>
253  int BroadCast(DataType &buf,int root_rank)
254  {
255  int sizeofdata = sizeof(DataType);
256  return((_rc = MPI_Bcast(&buf,sizeofdata,MPI_CHAR,root_rank,_comm)));
257  };
258 
259  template<typename DataType>
260  int BroadCast(std::vector<DataType> &buf,int root_rank)
261  {
262  int sizeofdata = sizeof(DataType);
263  int bufsize = buf.size();
264  _rc = MPI_Bcast(&bufsize,1,MPI_INT,root_rank,_comm);
265  if(_rank != root_rank)
266  buf.resize(bufsize);
267  _rc = MPI_Bcast(&buf[0],buf.size()*sizeofdata,MPI_CHAR,root_rank,_comm);
268  return(_rc);
269  };
270 
271  // doesn't work, duh
272  template<typename DataType>
273  int Reduce(DataType &send,DataType &recv,
274  const comm::DataTypes &dt,const comm::Ops &op,int root)
275  {
276  _rc = MPI_Reduce(&send,&recv,1,ResolveDataType(dt),
277  ResolveOp(op),root,_comm);
278  assert(_rc == 0);
279  return(_rc);
280  };
281 
282  // doesn't work, duh - can't reduce arbitrary DataType
283  template<typename DataType>
284  int Reduce(std::vector<DataType> &send,std::vector<DataType> &recv,
285  const comm::DataTypes &dt,const comm::Ops &op,int root)
286  {
287  int count = send.size();
288  // size_t datasize = sizeof(DataType);
289  // MPI_Datatype mpi_data_type = MPI_DOUBLE;
290  // if(datasize == sizeof(int))
291  // mpi_data_type = MPI_INTEGER;
292  if(_rank == root)
293  recv.resize(count);
294  _rc = MPI_Reduce(&send[0],&recv[0],count,ResolveDataType(dt),
295  ResolveOp(op),root,_comm);
296  assert(_rc == 0);
297  return(_rc);
298  };
299 
300  // doesn't work, duh
301  template<typename DataType>
302  int AllReduce(std::vector<DataType> &send,std::vector<DataType> &recv,
303  const comm::DataTypes &dt,const comm::Ops &op)
304  {
305  int count = send.size();
306  recv.resize(count);
307  _rc = MPI_Allreduce(&send[0],&recv[0],count,ResolveDataType(dt),
308  ResolveOp(op),_comm);
309  assert(_rc == 0);
310  return(_rc);
311  };
312 
313 
314  // doesn't work, duh
315  template<typename DataType>
316  int AllReduce(DataType &send,DataType &recv,
317  const comm::DataTypes &dt,const comm::Ops &op)
318  {
319  _rc = MPI_Allreduce(&send,&recv,1,ResolveDataType(dt),
320  ResolveOp(op),_comm);
321  assert(_rc == 0);
322  return(_rc);
323  };
324 
325  template<typename DataType>
326  int AllGather(std::vector<DataType> &sendvec,std::vector<DataType> &recvvec,
327  int sndcnt=0,int recvcnt=0)
328  {
329  size_t datasize = sizeof(DataType);
330  if(sndcnt == 0)
331  sndcnt = sendvec.size();
332  if(recvcnt == 0)
333  recvcnt = sndcnt;
334  std::cout << "Sendcount = " << sndcnt << " ReceiveCount = " << recvcnt << std::endl;
335  _rc = MPI_Allgather((void *)(&(sendvec[0])),sndcnt*datasize,MPI_CHAR,
336  (void *)(&(recvvec[0])),recvcnt*datasize,MPI_CHAR,_comm);
337  assert(_rc == 0);
338  return(_rc);
339  };
340 
341 
342  // template<typename T>
343  // int BroadCastMOVector(std::vector<T> &mov,int root_rank = 0)
344  // {
345  // std::vector<MobileObject *> moc;
346  // moc.resize(mov.size());
347  // std::vector<MobileObject *>::iterator moci = moc.begin();
348  // typename std::vector<T>::iterator oi = mov.begin();
349  // while(moci != moc.end())
350  // *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
351  // return(_BroadCastMOV(moc,root_rank));
352  // };
353 
354  template<typename DataType>
355  int AllGather(DataType &sendval,std::vector<DataType> &recvvec)
356  {
357  size_t messagesize = sizeof(DataType);
358  recvvec.resize(_nproc);
359  _rc = MPI_Allgather((void *)&sendval,messagesize,MPI_CHAR,
360  (void *)&recvvec[0],messagesize,MPI_CHAR,_comm);
361  assert(_rc == 0);
362  return(_rc);
363  };
364 
365  template<typename DataType>
366  int AllGatherv(std::vector<DataType> &sendvec,std::vector<DataType> &recvvec,std::vector<int> &nsend_all)
367  {
368  int datasize = sizeof(DataType);
369  int mysendcnt = sendvec.size();
370  int totalcnt = 0;
371  if(nsend_all.empty()){
372  nsend_all.resize(_nproc,0);
373  this->AllGather(mysendcnt,nsend_all);
374  }
375  this->AllReduce(mysendcnt,totalcnt,DTINT,SUMOP);
376  recvvec.resize(totalcnt);
377  return(_AllGatherv(&sendvec[0],mysendcnt,datasize,&recvvec[0]));
378  };
379 
380  template<typename DataType>
381  int AllGatherv(std::vector<DataType> &sendvec,std::vector<DataType> &recvvec)
382  {
383  int datasize = sizeof(DataType);
384  int mysendcnt = sendvec.size();
385  int totalcnt = 0;
386  std::vector<int> nsend_all;
387  nsend_all.resize(_nproc,0);
388  this->AllGather(mysendcnt,nsend_all);
389  this->AllReduce(mysendcnt,totalcnt,DTINT,SUMOP);
390  recvvec.resize(totalcnt);
391  return(_AllGatherv(&sendvec[0],mysendcnt,datasize,&recvvec[0]));
392  };
393 
394  template<typename DataType>
395  int Gather(DataType &sendval,std::vector<DataType> &recvvec,int root=0)
396  {
397  size_t messagesize = sizeof(DataType);
398  if(this->Rank() == root){
399  recvvec.resize(this->Size());
400  }
401  _rc = MPI_Gather((void *)&sendval,messagesize,MPI_CHAR,
402  (void *)&recvvec[0],messagesize,MPI_CHAR,
403  root,_comm);
404  assert(_rc == 0);
405  return(_rc);
406  };
407 
408  template<typename DataType>
409  int StreamGather(DataType &sendval,std::vector<DataType> &recvvec,int root=0)
410  {
411  std::ostringstream outStream;
412  outStream << sendval;
413  std::string sendVal(outStream.str());
414  const char *sendData = sendVal.c_str();
415  int messageSize = sendVal.size();
416  std::vector<int> allSizes(_nproc,0);
417  std::vector<int> allDisps(_nproc,0);
418  allSizes[_rank] = messageSize;
419  this->Gather(messageSize,allSizes,root);
420  int totalSize = 0;
421  for(int iRank = 0;iRank < _nproc;iRank++){
422  allDisps[iRank] = totalSize;
423  totalSize += allSizes[iRank];
424  }
425  char *recvData = new char [totalSize];
426  _rc = MPI_Gatherv(const_cast<void *>(static_cast<const void *>(sendData)),
427  allSizes[_rank],MPI_CHAR,
428  (void *)(&(recvData[0])),&allSizes[0],
429  &allDisps[0],MPI_CHAR,root,_comm);
430  assert(_rc == 0);
431  if(_rank == root){
432  for(int iRank = 0;iRank < _nproc;iRank++){
433  std::string rankString(&recvData[allDisps[iRank]],allSizes[iRank]);
434  recvvec.push_back(rankString);
435  }
436  }
437  delete [] recvData;
438  return(_rc);
439  };
440 
441  template<typename DataType>
442  int Gather(std::vector<DataType> &sendvec,std::vector<DataType> &recvvec,
443  int sndcnt=0,int recvcnt=0,int root=0)
444  {
445  size_t datasize = sizeof(DataType);
446  if(sndcnt == 0)
447  sndcnt = sendvec.size();
448  if(recvcnt == 0)
449  recvcnt = sndcnt;
450  if(_rank == root)
451  recvvec.resize(recvcnt*_nproc);
452  _rc = MPI_Gather((void *)(&(sendvec[0])),sndcnt*datasize,MPI_CHAR,
453  (void *)(&(recvvec[0])),recvcnt*datasize,MPI_CHAR,
454  root,_comm);
455  assert(_rc == 0);
456  return(_rc);
457  };
458 
459  template<typename DataType>
460  int Gatherv(std::vector<DataType> &sendvec,std::vector<DataType> &recvvec,
461  std::vector<int> &nsend_all,int nsend = 0,int root=0)
462  {
463  int datasize = sizeof(DataType);
464  if(nsend == 0)
465  nsend = sendvec.size();
466  int nrecv = 0;
467  if(nsend_all.empty()){
468  nsend_all.resize(_nproc);
469  nsend_all[_rank] = nsend;
470  this->Gather(nsend,nsend_all,root);
471  }
472  for(int i = 0;i < _nproc;i++)
473  nrecv += nsend_all[i];
474  std::vector<int> allsizes(_nproc,0);
475  std::vector<int> disps(_nproc,0);
476  if(_rank == root){
477  recvvec.resize(nrecv);
478  for(int i = 0; i < _nproc;i++){
479  allsizes[i] = nsend_all[i] * datasize;
480  if(i > 0)
481  disps[i] = disps[i-1]+allsizes[i-1];
482  }
483  }
484  _rc = MPI_Gatherv((void *)(&(sendvec[0])),allsizes[_rank],MPI_CHAR,
485  (void *)(&(recvvec[0])),&allsizes[0],&disps[0],MPI_CHAR,
486  root,_comm);
487  assert(_rc == 0);
488  return(_rc);
489  };
490 
491 
492  // Native Mobile Object support below
493  // ------------------------------------
494 
495  template<typename MOType>
496  int BroadCastMobileObject(MOType &mo,int root_rank = 0)
497  {
498  return(this->BroadCast(dynamic_cast<MobileObject *>(&mo),root_rank));
499  };
500 
501  template<typename MOType>
502  int BroadCastMO(MOType &mo,int root_rank = 0)
503  {
504  return(this->BroadCast(dynamic_cast<MobileObject *>(&mo),root_rank));
505  };
506 
507  template<typename MOType>
508  int BroadCastMO(std::vector<MOType> &mov,int root_rank = 0)
509  {
510  std::vector<MobileObject *> moc;
511  moc.resize(mov.size());
512  std::vector<MobileObject *>::iterator moci = moc.begin();
513  typename std::vector<MOType>::iterator oi = mov.begin();
514  while(moci != moc.end())
515  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
516  return(_BroadCastMOV(moc,root_rank));
517  };
518 
519  template<typename MOType>
520  int BroadCastMOVector(std::vector<MOType> &mov,int root_rank = 0)
521  {
522  int nobjs = mov.size();
523  _rc = 0;
524  // This broadcast is superfluous since nobjs should already be
525  // identical on every processor.
526  if((_rc = MPI_Bcast(&nobjs,1,MPI_INT,root_rank,_comm)))
527  return(1);
528  if(_rank != root_rank)
529  mov.resize(nobjs);
530  std::vector<MobileObject *> moc;
531  moc.resize(mov.size());
532  std::vector<MobileObject *>::iterator moci = moc.begin();
533  typename std::vector<MOType>::iterator oi = mov.begin();
534  while(moci != moc.end())
535  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
536  return(_BroadCastMOV(moc,root_rank));
537  };
538 
539  // To do this properly, we need a GATHERV underneath the covers. The
540  // mobile object on each processor can be of a different size depending
541  // on the actual object's local implementation of the pack/unpack
542  // routines.
543  template<typename MOType>
544  int GatherMO(MOType &sendval,std::vector<MOType> &recvvec,int root = 0)
545  {
546  recvvec.resize(0);
547  MobileObject *sendPtr = dynamic_cast<MobileObject *>(&sendval);
548  std::vector<MobileObject *> recv_v;
549  recv_v.resize(0);
550  if(_rank == root){
551  recvvec.resize(_nproc);
552  recv_v.resize(_nproc,NULL);
553  std::vector<MobileObject *>::iterator moci = recv_v.begin();
554  typename std::vector<MOType>::iterator oi = recvvec.begin();
555  while(moci != recv_v.end())
556  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
557  }
558  _rc = this->_GatherMO(sendPtr,recv_v,1,root);
559  // assert(_rc == 0);
560  return(_rc);
561  };
562 
563  template<typename MOType>
564  int GatherMO(std::vector<MOType> &sendvec,std::vector<MOType> &recvvec,
565  std::vector<int> &nsend_all,int root = 0)
566  {
567  int nsend = sendvec.size();
568  if(nsend_all.empty()){
569  nsend_all.resize(_nproc,0);
570  nsend_all[_rank] = nsend;
571  this->Gather(nsend,nsend_all,root);
572  }
573  int nrecv = 0;
574  if(_rank == root){
575  std::vector<int>::iterator nsi = nsend_all.begin();
576  while(nsi != nsend_all.end())
577  nrecv += *nsi++;
578  recvvec.resize(nrecv);
579  }
580  std::vector<MobileObject *> send_v(nsend,NULL);
581  std::vector<MobileObject *> recv_v(nrecv,NULL);
582  std::vector<MobileObject *>::iterator moci = recv_v.begin();
583  typename std::vector<MOType>::iterator oi = recvvec.begin();
584  while(moci != recv_v.end())
585  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
586  moci = send_v.begin();
587  oi = sendvec.begin();
588  while(moci != send_v.end())
589  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
590  _rc = this->_GatherMOV(send_v,recv_v,nsend_all,root);
591  // assert(_rc == 0);
592  return(_rc);
593  };
594 
595  template<typename MOType>
596  int AllGatherMO(MOType &sendval,std::vector<MOType> &recvvec)
597  {
598  recvvec.resize(_nproc);
599  MobileObject *sendPtr = dynamic_cast<MobileObject *>(&sendval);
600  std::vector<MobileObject *> recv_v(_nproc,NULL);
601  std::vector<MobileObject *>::iterator moci = recv_v.begin();
602  typename std::vector<MOType>::iterator oi = recvvec.begin();
603  while(moci != recv_v.end())
604  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
605  _rc = this->_AllGatherMO(sendPtr,recv_v);
606  assert(_rc == 0);
607  return(_rc);
608  };
609 
610  template<typename MOType>
611  int AllGatherMO(std::vector<MOType> &sendvec,std::vector<MOType> &recvvec,
612  std::vector<int> &nsend_all,int root = 0)
613  {
614  int nsend = sendvec.size();
615  if(nsend_all.empty()){
616  nsend_all.resize(_nproc,0);
617  nsend_all[_rank] = nsend;
618  this->Gather(nsend,nsend_all,root);
619  }
620  int nrecv = 0;
621  if(_rank == root){
622  std::vector<int>::iterator nsi = nsend_all.begin();
623  while(nsi != nsend_all.end())
624  nrecv += *nsi++;
625  recvvec.resize(nrecv);
626  }
627  std::vector<MobileObject *> send_v(nsend,NULL);
628  std::vector<MobileObject *> recv_v(nrecv,NULL);
629  std::vector<MobileObject *>::iterator moci = recv_v.begin();
630  typename std::vector<MOType>::iterator oi = recvvec.begin();
631  while(moci != recv_v.end())
632  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
633  moci = send_v.begin();
634  oi = sendvec.begin();
635  while(moci != send_v.end())
636  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
637  _rc = this->_GatherMOV(send_v,recv_v,nsend_all,root);
638  // assert(_rc == 0);
639  return(_rc);
640  };
641 
642  template<typename MOType>
643  int GatherMOV(std::vector<MOType> &sendvec,std::vector<MOType> &recvvec,
644  std::vector<int> &nsend_all,int root = 0)
645  {
646  int nsend = sendvec.size();
647  if(nsend_all.empty()){
648  nsend_all.resize(_nproc,0);
649  nsend_all[_rank] = nsend;
650  this->Gather(nsend,nsend_all,root);
651  }
652  int nrecv = 0;
653  if(_rank == root){
654  std::vector<int>::iterator nsi = nsend_all.begin();
655  while(nsi != nsend_all.end())
656  nrecv += *nsi++;
657  recvvec.resize(nrecv);
658  }
659  std::vector<MobileObject *> send_v(nsend,NULL);
660  std::vector<MobileObject *> recv_v(nrecv,NULL);
661  std::vector<MobileObject *>::iterator moci = recv_v.begin();
662  typename std::vector<MOType>::iterator oi = recvvec.begin();
663  while(moci != recv_v.end())
664  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
665  moci = send_v.begin();
666  oi = sendvec.begin();
667  while(moci != send_v.end())
668  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
669  _rc = this->_GatherMOV(send_v,recv_v,nsend_all,root);
670  // assert(_rc == 0);
671  return(_rc);
672  };
673 
674  template<typename MOType>
675  int AllGatherMOV(std::vector<MOType> &sendvec,std::vector<MOType> &recvvec,
676  std::vector<int> &nsend_all,int root = 0)
677  {
678  int nsend = sendvec.size();
679  if(nsend_all.empty()){
680  nsend_all.resize(_nproc,0);
681  nsend_all[_rank] = nsend;
682  this->Gather(nsend,nsend_all,root);
683  }
684  int nrecv = 0;
685  if(_rank == root){
686  std::vector<int>::iterator nsi = nsend_all.begin();
687  while(nsi != nsend_all.end())
688  nrecv += *nsi++;
689  recvvec.resize(nrecv);
690  }
691  std::vector<MobileObject *> send_v(nsend,NULL);
692  std::vector<MobileObject *> recv_v(nrecv,NULL);
693  std::vector<MobileObject *>::iterator moci = recv_v.begin();
694  typename std::vector<MOType>::iterator oi = recvvec.begin();
695  while(moci != recv_v.end())
696  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
697  moci = send_v.begin();
698  oi = sendvec.begin();
699  while(moci != send_v.end())
700  *moci++ = dynamic_cast<MobileObject *>(&(*oi++));
701  _rc = this->_AllGatherMOV(send_v,recv_v,nsend_all);
702  // assert(_rc == 0);
703  return(_rc);
704  };
705 
706  template < typename T >
707  int Union(std::vector< T > &input_data,std::vector< T > &output_data)
708  {
709  std::vector< T > all_items;
710  int err = AllGatherv< T >(input_data,all_items);
711  std::sort(all_items.begin(),all_items.end());
712  typename std::vector< T >::iterator ui = std::unique(all_items.begin(),all_items.end());
713  output_data.resize(ui - all_items.begin());
714  std::copy(all_items.begin(),ui,output_data.begin());
715  return err;
716  };
717 
718 
719 
720  };
721 
722 
729  protected:
731  public:
734  _communicator.Initialize(incomm);
735  };
736  virtual ~ParallelObject(){};
737  virtual CommunicatorObject &Communicator(){return(_communicator);};
738  };
739  };
740 };
741 #endif
int SetCommunicator(MPI_Comm &inComm)
Definition: COMM.H:86
int AllGatherv(std::vector< DataType > &sendvec, std::vector< DataType > &recvvec)
Definition: COMM.H:381
Utility class for creating derived objects that are parallel.
Definition: COMM.H:728
const void * GetBuffer() const
Definition: COMM.H:36
int GatherMO(MOType &sendval, std::vector< MOType > &recvvec, int root=0)
Definition: COMM.H:544
int ARecvBuf(DataType *recvbuf, size_t nVal, unsigned int remote_rank, int tag=0)
Definition: COMM.H:163
ParallelObject(CommunicatorObject &incomm)
Definition: COMM.H:733
int BroadCastMO(MOType &mo, int root_rank=0)
Definition: COMM.H:502
int AllGatherMO(MOType &sendval, std::vector< MOType > &recvvec)
Definition: COMM.H:596
provides communication for complex objects.
Definition: COMM.H:27
Basic utility header.
std::vector< int > _cart_periodic
Definition: COMM.H:82
DataTypes
Supported data types.
Definition: COMM.H:19
std::vector< int > _cart_dims
Definition: COMM.H:81
std::vector< MPI_Request > _recv_requests
Definition: COMM.H:76
int BroadCastMobileObject(MOType &mo, int root_rank=0)
Definition: COMM.H:496
int ARecv(std::vector< DataType > &recvbuf, unsigned int remote_rank, int tag=0)
Definition: COMM.H:207
Defines MPI-specific parallel global and program classes.
int ASend(std::vector< DataType > &sendbuf, unsigned int remote_rank, int tag=0)
Definition: COMM.H:171
int SetRecv(std::vector< DataType > &recvbuf, unsigned int remote_rank, int tag=0)
Definition: COMM.H:198
int AllGather(DataType &sendval, std::vector< DataType > &recvvec)
Definition: COMM.H:355
int SetErr(int errin)
Definition: COMM.H:110
int Union(std::vector< T > &input_data, std::vector< T > &output_data)
Definition: COMM.H:707
int AllReduce(std::vector< DataType > &send, std::vector< DataType > &recv, const comm::DataTypes &dt, const comm::Ops &op)
Definition: COMM.H:302
std::vector< int > _cart_coords
Definition: COMM.H:80
int ASendBuf(DataType *sendBuf, size_t nVal, unsigned int remote_rank, int tag=-1)
Definition: COMM.H:155
int AllReduce(DataType &send, DataType &recv, const comm::DataTypes &dt, const comm::Ops &op)
Definition: COMM.H:316
int SetSend(std::vector< DataType > &sendbuf, unsigned int remote_rank, int tag=0)
Definition: COMM.H:189
int AllGatherMO(std::vector< MOType > &sendvec, std::vector< MOType > &recvvec, std::vector< int > &nsend_all, int root=0)
Definition: COMM.H:611
MPI_Comm GetCommunicator() const
Definition: COMM.H:85
std::vector< int > _send_tags
Definition: COMM.H:77
void * GetBuffer()
Definition: COMM.H:37
int ASend(std::vector< DataType > &sendbuf, unsigned int startIndex, unsigned int sendSize, unsigned int remote_rank, int tag=0)
Definition: COMM.H:180
int BroadCast(std::vector< DataType > &buf, int root_rank)
Definition: COMM.H:260
virtual int Pack(void **inbuf=NULL)
Definition: COMM.C:22
virtual ~MobileObject()
Definition: COMM.H:50
virtual void DestroyBuffer()
Definition: COMM.H:42
Main encapsulation of MPI.
Definition: COMM.H:62
int AllGatherMOV(std::vector< MOType > &sendvec, std::vector< MOType > &recvvec, std::vector< int > &nsend_all, int root=0)
Definition: COMM.H:675
int Initialize(CommunicatorObject &incomm)
Definition: COMM.C:310
int AllGather(std::vector< DataType > &sendvec, std::vector< DataType > &recvvec, int sndcnt=0, int recvcnt=0)
Definition: COMM.H:326
int Gather(DataType &sendval, std::vector< DataType > &recvvec, int root=0)
Definition: COMM.H:395
int AllGatherv(std::vector< DataType > &sendvec, std::vector< DataType > &recvvec, std::vector< int > &nsend_all)
Definition: COMM.H:366
const std::string Hostname(bool longname=false)
Definition: UnixUtils.C:17
int StreamGather(DataType &sendval, std::vector< DataType > &recvvec, int root=0)
Definition: COMM.H:409
int ARecv(std::vector< DataType > &recvbuf, unsigned int startIndex, unsigned int numRecv, unsigned int remote_rank, int tag=0)
Definition: COMM.H:216
int BroadCastMO(std::vector< MOType > &mov, int root_rank=0)
Definition: COMM.H:508
int Gather(std::vector< DataType > &sendvec, std::vector< DataType > &recvvec, int sndcnt=0, int recvcnt=0, int root=0)
Definition: COMM.H:442
virtual CommunicatorObject & Communicator()
Definition: COMM.H:737
std::vector< MPI_Status > _status
Definition: COMM.H:79
virtual int PrepareBuffer(size_t bsize)
Definition: COMM.C:10
void ** GetBufPtr()
Definition: COMM.H:35
virtual int UnPack(const void *outbuf=NULL)
Definition: COMM.C:52
int SetExit(int errin)
Definition: COMM.H:109
int BroadCastMOVector(std::vector< MOType > &mov, int root_rank=0)
Definition: COMM.H:520
Ops
Operations for collectives.
Definition: COMM.H:21
int Initialize(base &stencilSet, int interiorOrder)
Initialize the sbp::base stencilset with the SBP operator of given order.
Definition: Stencil.C:360
int GatherMOV(std::vector< MOType > &sendvec, std::vector< MOType > &recvvec, std::vector< int > &nsend_all, int root=0)
Definition: COMM.H:643
std::vector< MPI_Request > _send_requests
Definition: COMM.H:75
virtual ~ParallelObject()
Definition: COMM.H:736
int Reduce(DataType &send, DataType &recv, const comm::DataTypes &dt, const comm::Ops &op, int root)
Definition: COMM.H:273
int Reduce(std::vector< DataType > &send, std::vector< DataType > &recv, const comm::DataTypes &dt, const comm::Ops &op, int root)
Definition: COMM.H:284
int StreamBroadCast(DataType &inData, int root_rank=0)
Definition: COMM.H:225
std::vector< int > & CartDimensions()
Definition: COMM.H:118
CommunicatorObject _communicator
Definition: COMM.H:730
int BroadCast(DataType &buf, int root_rank)
Definition: COMM.H:253
int Gatherv(std::vector< DataType > &sendvec, std::vector< DataType > &recvvec, std::vector< int > &nsend_all, int nsend=0, int root=0)
Definition: COMM.H:460
std::vector< int > & CartCoordinates()
Definition: COMM.H:117
int GatherMO(std::vector< MOType > &sendvec, std::vector< MOType > &recvvec, std::vector< int > &nsend_all, int root=0)
Definition: COMM.H:564
std::vector< int > _recv_tags
Definition: COMM.H:78