00001 // 00002 //------------------------------------------------------------------------ 00003 // 00004 // File : MPICommunicator.h 00005 // Author : Patrick McCormick (pat@acl.lanl.gov) 00006 // 00007 // $Date: 2003/08/04 04:57:49 $ 00008 // $Revision: 1.11 $ 00009 // 00010 // 00011 // This class implements the details of an MPI based communicator 00012 // object. Most of the details in this class and its implementation 00013 // are taken straight from MPI. 00014 // 00015 // TODO: At the moment we use a map to keep tabs on async message handles. 00016 // This is necessary because we had to keep tabs on more than just the 00017 // MPI specific handle -- we need to update the KokoBuffer to reflect the 00018 // size of the message recevied... This leads to a couple of issues in 00019 // the current implementation: 00020 // 00021 // * The current implementation allocates an AsyncMesgHandle class 00022 // per async call -- if this turns out to be an issue the easiest 00023 // fix is to build a free list of AsyncMesgHandle objects that can 00024 // be reused. 00025 // 00026 // * We need to write some code to test drive the async messages. The 00027 // map approach has not be validated with real tests yet. 00028 // 00029 // * The current code uses an unsigned integer value for the message 00030 // handle data. It attempts to catch a wrap-around condition when 00031 // a maximum unsigned int value is reached but perhaps it might be 00032 // better to consider unsigned long values instead? 00033 // 00034 //------------------------------------------------------------------------ 00035 00036 #ifndef KOKO_MPI_COMMUNICATOR_H_ 00037 #define KOKO_MPI_COMMUNICATOR_H_ 00038 00039 #include "Communicator.h" 00040 00041 #include <map> 00042 00043 class AsyncMesgHandle; 00044 00045 class MPICommunicator : public Communicator 00046 { 00047 public: 00048 MPICommunicator(void); 00049 ~MPICommunicator(void); 00050 bool Send(KokoProcID id, KokoBuffer &buf, KokoTag tag); 00051 bool Barrier(void); 00052 int Recv(KokoProcID id, KokoBuffer &buf, KokoTag tag); 00053 int SendRecv(int dest, KokoBuffer &sendbuf, KokoTag stag, 00054 int src, KokoBuffer &recvbuf, KokoTag rtag); 00055 00056 KokoMesgHandle ASend(KokoProcID id, KokoBuffer &buf, KokoTag tag); 00057 KokoMesgHandle ARecv(KokoProcID id, KokoBuffer &buf, KokoTag tag); 00058 bool Wait(KokoMesgHandle &hand); 00059 bool Test(KokoMesgHandle &hand); 00060 00061 bool Broadcast(KokoBuffer &buffer, KokoProcID root, KokoTag tag); 00062 00063 protected: 00064 void ErrorMesg(int err); 00065 00066 private: 00067 // Help out a little to cut back on all the STL syntax goop... 00068 typedef std::pair<KokoMesgHandle, AsyncMesgHandle *> AMHPair; 00069 typedef std::map<KokoMesgHandle, AsyncMesgHandle *> AMHMap; 00070 typedef AMHMap::iterator AMHIterator; 00071 typedef std::pair<AMHIterator, bool> AMHBool; 00072 00073 int _maxtag; // Maximum tag value supported. 00074 KokoMesgHandle _handlecount; // Total handle count. 00075 AMHMap _handlemap; // Map of handles to async mesg info. 00076 }; 00077 00078 #endif 00079