00001 
00002 
00003 
00004 
00005 
00006 
00007 #ifndef __UIUC_CHARM_PUP_MPI_H
00008 #define __UIUC_CHARM_PUP_MPI_H
00009 
00010 #include "pup.h"
00011 #include "mpi.h"
00012 
00013 #define pup_checkMPI(err) pup_checkMPIerr(err,__FILE__,__LINE__);
00014 inline void pup_checkMPIerr(int mpi_err,const char *file,int line) {
00015     if (mpi_err!=MPI_SUCCESS) {
00016         CmiError("MPI Routine returned error %d at %s:%d\n",
00017             mpi_err,file,line);
00018         CmiAbort("MPI Routine returned error code");
00019     }
00020 }
00021 
00023 inline int MPI_Incoming_pup(MPI_Datatype dt,int from,int tag,MPI_Comm comm) {
00024     MPI_Status sts;
00025     pup_checkMPI(MPI_Probe(from,tag,comm,&sts));
00026     int len; pup_checkMPI(MPI_Get_count(&sts,dt,&len));
00027     return len;
00028 }
00029 
00031 template <class T>
00032 inline void MPI_Recv_pup(T &t, int from,int tag,MPI_Comm comm) {
00033     int len=MPI_Incoming_pup(MPI_BYTE,from,tag,comm);
00034     MPI_Status sts;
00035     char *buf=new char[len];
00036     pup_checkMPI(MPI_Recv(buf,len,MPI_BYTE, from,tag,comm,&sts));
00037     PUP::fromMemBuf(t,buf,len);
00038     delete[] buf;
00039 }
00040 
00042 template <class T>
00043 inline void MPI_Send_pup(T &t, int to,int tag,MPI_Comm comm) {
00044     size_t len=PUP::size(t); char *buf=new char[len];
00045     PUP::toMemBuf(t,buf,len);
00046     pup_checkMPI(MPI_Send(buf,len,MPI_BYTE, to,tag,comm));
00047     delete[] buf;
00048 }
00049 
00051 template <class T>
00052 inline void MPI_Bcast_pup(T &t, int root,MPI_Comm comm) {
00053     int myRank;
00054     MPI_Comm_rank(comm,&myRank);
00055     
00056     size_t len=0;
00057     if(myRank == root) len=PUP::size(t); 
00058     pup_checkMPI(MPI_Bcast(&len,1,MPI_INT,root,comm));
00059     
00060     char *buf=new char[len];
00061     if(myRank == root) PUP::toMemBuf(t,buf,len);
00062     pup_checkMPI(MPI_Bcast(buf,len,MPI_BYTE, root,comm));
00063     PUP::fromMemBuf(t,buf,len);
00064     delete [] buf;
00065 }
00066 
00067 
00068 #endif