mpidatatransfer.hh

Go to the documentation of this file.
00001 // mpidatatransfer.H
00002 // created by ADP 3/21/05
00003 // modified by WWS spring 06
00004 
00005 // This file defines a templated function for selecting the proper
00006 // enumerated type to match a given basic type, and two functions for
00007 // sending and receiving data to/from a LDC.
00008 
00009 #ifndef __PARAMS_MPI_DATA_TRANSFER_
00010 #define __PARAMS_MPI_DATA_TRANSFER_
00011 
00012 #include "mpi.h"
00013 #include "std_cpp_includes.hh"
00014 #include "mpiutils.hh"
00015 #include "except.hh"
00016 
00017 namespace RVL {
00018 
00021   template<typename Scalar>
00022   inline static MPI_Datatype findMPIDatatype() {
00023     RVLException e;
00024     e<<"Error: call to base findMPIDatatype template - undefined \n";
00025     throw e;
00026   }
00027 
00028   template<>
00029   inline MPI_Datatype findMPIDatatype<char>() {return MPI_CHAR;}
00030 
00031   template<>
00032   inline MPI_Datatype findMPIDatatype<short>() {return MPI_SHORT;}
00033 
00034   template<>
00035   inline MPI_Datatype findMPIDatatype<int>() {return MPI_INT;}
00036 
00037   template<>
00038   inline MPI_Datatype findMPIDatatype<long>() {return MPI_LONG;}
00039 
00040   template<>
00041   inline MPI_Datatype findMPIDatatype<unsigned char>() {return MPI_UNSIGNED_CHAR;}
00042 
00043   template<>
00044   inline MPI_Datatype findMPIDatatype<unsigned short>() {return MPI_UNSIGNED_SHORT;}
00045 
00046   template<>
00047   inline MPI_Datatype findMPIDatatype<unsigned int>() {return MPI_UNSIGNED;}
00048 
00049   template<>
00050   inline MPI_Datatype findMPIDatatype<unsigned long>() {return MPI_UNSIGNED_LONG;}
00051 
00052   template<>
00053   inline MPI_Datatype findMPIDatatype<float>() {return MPI_FLOAT;}
00054 
00055   template<>
00056   inline MPI_Datatype findMPIDatatype<double>() {return MPI_DOUBLE;}
00057 
00058   template<>
00059   inline MPI_Datatype findMPIDatatype<long double>() {return MPI_LONG_DOUBLE;}
00060 
00063   template<typename T>
00064   void Build_MPI_Datatype(MPI_Datatype * mpitype) {
00065     try {
00066       *mpitype=findMPIDatatype<T>();
00067     }
00068     catch (RVLException & e) {
00069       e<<"\ncalled from BuildMPI_Datatype\n";
00070       throw e;
00071     }
00072   }
00073       
00079   template<typename T>
00080   class MPI_Sender {
00081 
00082   private:
00083 
00084     int dest;
00085     MPI_Comm comm;
00086 
00087   public:
00088 
00089     MPI_Sender(int _dest=0, MPI_Comm _comm = MPI_COMM_WORLD) 
00090       : dest(_dest), comm(_comm) {}
00091     MPI_Sender(MPI_Sender<T> const & s) 
00092       : dest(s.dest), comm(s.comm) {}
00093     ~MPI_Sender() {}
00094 
00095     bool setDestination( int d ){ return MPIRVL_SetRank(dest,d,comm); }
00096 
00097     bool operator()(T & x) const {
00098       try {
00099     int tag=0;
00100     MPI_Datatype dt;
00101     Build_MPI_Datatype<T>(&dt);
00102     if (MPI_SUCCESS == MPI_Send(&x,1,dt,dest,tag,comm)) return true;
00103     return false;
00104       }
00105       catch (RVLException & e) {
00106     e<<"\ncalled from MPI_Sender::operator()\n";
00107     throw e;
00108       }
00109     }
00110   };
00111 
00112   template<typename T>
00113   class MPI_Receiver {
00114 
00115     MPI_Status * status;
00116     int src;
00117     MPI_Comm comm;
00118 
00119   public:
00120 
00121     MPI_Receiver(MPI_Status * _status,
00122          int _src=0, 
00123          MPI_Comm _comm = MPI_COMM_WORLD) 
00124       : status(_status), src(_src), comm(_comm) {}
00125     MPI_Receiver(MPI_Receiver<T> const & s) 
00126       : status(s.status),src(s.src), comm(s.comm) {}
00127     ~MPI_Receiver() {}
00128 
00129     bool setSource( int s ){ return MPIRVL_SetRank(src,s,comm); }
00130 
00131     bool operator()(T & x) const {
00132       try {
00133     int tag=0;
00134     MPI_Datatype dt;
00135     Build_MPI_Datatype<T>(&dt);
00136     if (MPI_SUCCESS == MPI_Recv(&x,1,dt,src,tag,comm,status)) return true;
00137     return false;
00138       }
00139       catch (RVLException & e) {
00140     e<<"\ncalled from MPI_Receiver::operator()\n";
00141     throw e;
00142       }
00143     }
00144   };
00145 
00146   template<typename T>
00147   class MPI_Broadcaster {
00148 
00149     int root;
00150     MPI_Comm comm;
00151 
00152   public:
00153 
00154     MPI_Broadcaster(int _root=0, MPI_Comm _comm = MPI_COMM_WORLD)
00155       : root(_root), comm(_comm) {
00156       int rt;
00157       if (!MPIRVL_SetRank(rt,root,comm)) {
00158     RVLException e;
00159     e<<"Error: MPI_Broadcaster constructor\n";
00160     e<<"root outside range of ranks for assigned MPI_Comm\n";
00161     throw e;
00162       }
00163     }
00164     MPI_Broadcaster(MPI_Broadcaster<T> const & b)
00165       : root(b.root), comm(b.comm) {}
00166     ~MPI_Broadcaster() {}
00167 
00168     bool operator()(T & x) const {
00169       try {
00170     MPI_Datatype dt;
00171     Build_MPI_Datatype<T>(&dt);
00172     if (MPI_SUCCESS == MPI_Bcast(&x,1,dt,root,comm)) return true;
00173     return false;
00174       }
00175       catch (RVLException & e) {
00176     e<<"\ncalled from MPI_Broadcaster::operator()\n";
00177     throw e;
00178       }
00179     }
00180   };
00181 
00182   template<typename T>
00183   class MPI_Reducer {
00184 
00185     MPI_Op op;
00186     int root;
00187     MPI_Comm comm;
00188 
00189   public:
00190 
00191     MPI_Reducer(MPI_Op _op= MPI_SUM,
00192         int _root=0, 
00193         MPI_Comm _comm = MPI_COMM_WORLD)
00194       : op(_op), root(_root), comm(_comm) {
00195       int rt;
00196       if (!MPIRVL_SetRank(rt,root,comm)) {
00197     RVLException e;
00198     e<<"Error: MPI_Reducer constructor\n";
00199     e<<"root outside range of ranks for assigned MPI_Comm\n";
00200     throw e;
00201       }
00202     }
00203     MPI_Reducer(MPI_Reducer<T> const & b)
00204       : op(b.op), root(b.root), comm(b.comm) {}
00205     ~MPI_Reducer() {}
00206 
00207     bool operator()(T & xout, T const & xin) const {
00208       try {
00209     MPI_Datatype dt;
00210     Build_MPI_Datatype<T>(&dt);
00211     if (MPI_SUCCESS == MPI_Reduce(&xin,&xout,1,dt,op,root,comm)) return true;
00212     return false;
00213       }
00214       catch (RVLException & e) {
00215     e<<"\ncalled from MPI_Reducer::operator()\n";
00216     throw e;
00217       }
00218     }
00219   };
00220 
00221 }
00222 
00223 #endif // __PARAMS_MPI_DATA_TRANSFER_

Generated on 5 Jan 2017 for MPIRVL by  doxygen 1.4.7