00001
00002
00003 #ifndef _gmpi_include_
00004 #define _gmpi_include_
00005
00006
00007 #include "mpi.h"
00008 #include <utility>
00009 #include <vector>
00010 #include <list>
00011 #include <deque>
00012
00013
00014
00015 namespace GMPI {
00016
00017 using std::pair; using std::vector; using std::list; using std::deque;
00018
00020 inline MPI::Datatype which_mpi_t (char) {return MPI::CHAR;}
00021
00022
00023 inline MPI::Datatype which_mpi_t (signed short) {return MPI::SHORT;}
00024 inline MPI::Datatype which_mpi_t (signed int) {return MPI::INT;}
00025 inline MPI::Datatype which_mpi_t (signed long) {return MPI::LONG;}
00026 inline MPI::Datatype which_mpi_t (unsigned char) {return MPI::UNSIGNED_CHAR;}
00027 inline MPI::Datatype which_mpi_t (unsigned short) {return MPI::UNSIGNED_SHORT;}
00028 inline MPI::Datatype which_mpi_t (unsigned) {return MPI::UNSIGNED;}
00029
00030 inline MPI::Datatype which_mpi_t (unsigned long) {return MPI::UNSIGNED_LONG;}
00031 inline MPI::Datatype which_mpi_t (double) {return MPI::DOUBLE;}
00032 inline MPI::Datatype which_mpi_t (long double) {return MPI::LONG_DOUBLE;}
00033
00034
00035
00036
00037 inline MPI::Datatype which_mpi_t (pair<int,int>) {return MPI::TWOINT;}
00038 inline MPI::Datatype which_mpi_t (pair<float,int>) {return MPI::FLOAT_INT;}
00039 inline MPI::Datatype which_mpi_t (pair<double,int>) {return MPI::DOUBLE_INT;}
00040 inline MPI::Datatype which_mpi_t (pair<long double,int>) {return MPI::LONG_DOUBLE_INT;}
00041 inline MPI::Datatype which_mpi_t (pair<short,int>) {return MPI::SHORT_INT;}
00042
00044 const MPI::Datatype mpi_size_t= which_mpi_t (size_t());
00045
00046 template <typename Base_t>
00047 class buffer_t {
00048 public:
00049 typedef Base_t base_t;
00050 MPI::Datatype mpi_t;
00051 const int base_t_size;
00052 private:
00053 vector<Base_t> my_buffer;
00054 mutable size_t write_pos,
00055 read_pos;
00056 mutable bool read_write;
00057 public:
00059 buffer_t () : mpi_t (which_mpi_t (Base_t())),
00060 base_t_size (sizeof (Base_t)),
00061 write_pos (0), read_pos (0), read_write (false) {}
00063 buffer_t (size_t n) : mpi_t (which_mpi_t (Base_t())),
00064 base_t_size (sizeof (Base_t)),
00065 write_pos (0), read_pos (0), read_write (false) {reserve (n);}
00066
00068 void reserve (size_t n) {
00069 if (read_write) {
00070 write_pos= 0; my_buffer.resize (n); read_write= false; return; }
00071 if (write_pos+n > my_buffer.size()) my_buffer.resize (write_pos+n);}
00072
00074 bool empty () const {
00075 return read_pos == write_pos; }
00076
00078 size_t remaining () const {
00079 return write_pos - read_pos; }
00080
00082 Base_t read () const {
00083 if (!read_write) {
00084 read_pos= 0; read_write= true; }
00085
00086 return my_buffer[read_pos++]; }
00087
00089 void unread () const {
00090
00091
00092 read_pos--; }
00093
00095 void write (Base_t output) {
00096 if (read_write) {
00097 write_pos= 0; my_buffer.resize (1); read_write= false; }
00098
00099 reserve (1);
00100 my_buffer[write_pos++]= output; }
00101
00103 void load (Base_t* address, size_t n) const {
00104 if (!read_write) {
00105 read_pos= 0; read_write= true; }
00106
00107 memcpy (address, &my_buffer[read_pos], n * base_t_size);
00108 read_pos+= n; }
00109
00111 void store (Base_t* address, size_t n) {
00112 if (read_write) {
00113 write_pos= 0; my_buffer.resize (n); read_write= false; }
00114 reserve (write_pos+n - my_buffer.size());
00115 memcpy (&my_buffer[write_pos], address, n * base_t_size);
00116 write_pos+= n; }
00117
00119 size_t size () const {return my_buffer.size(); }
00120
00122 Base_t* address () {return &my_buffer[0]; }
00123
00125 const Base_t* buffer_address () const {return &my_buffer[0]; }
00126
00128 void free () {
00129 my_buffer.resize (0); write_pos= read_pos= 0; read_write= false; }
00130 };
00131
00133 template <typename Base_t> inline
00134 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer, Base_t& input) {
00135 input= buffer.read (); return buffer; }
00136
00138 template <typename Base_t> inline
00139 buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer, const Base_t& output) {
00140 buffer.write (output); return buffer; }
00141
00143 template <typename Base_t> inline
00144 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer,
00145 vector<Base_t>& input) {
00146 int csize= input.size(), n= buffer.remaining();
00147 input.resize (csize + n);
00148 buffer.load (&input[csize], n);
00149 return buffer; }
00150
00152 template <typename Base_t> inline
00153 const buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer,
00154 const vector<Base_t>& output) {
00155 int n= output.size();
00156 buffer.store (&output[0], n);
00157 return buffer; }
00158
00159
00160
00162 template <typename Base_t, typename Scalar1_t, typename Scalar2_t> inline
00163 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer,
00164 pair<Scalar1_t, Scalar2_t>& input) {
00165 buffer >> input.first >> input.second; return buffer; }
00166
00168 template <typename Base_t, typename Scalar1_t, typename Scalar2_t> inline
00169 buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer,
00170 const pair<Scalar1_t, Scalar2_t>& output) {
00171 buffer << output.first << output.second; return buffer; }
00172
00174 template <typename Base_t, typename Scalar_t> inline
00175 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer,
00176 vector<Scalar_t>& input) {
00177 size_t size; buffer >> size;
00178 for (size_t c= 0; c < size; c++) {
00179 Scalar_t scalar; buffer >> scalar; input.push_back (scalar); }
00180 return buffer; }
00181
00183 template <typename Base_t, typename Scalar_t> inline
00184 buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer,
00185 const vector<Scalar_t>& output) {
00186 buffer << output.size();
00187 for (typename vector<Scalar_t>::const_iterator it= output.begin(), end= output.end();
00188 it != end;) buffer << *it++;
00189 return buffer; }
00190
00192 template <typename Base_t, typename Scalar_t> inline
00193 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer,
00194 list<Scalar_t>& input) {
00195 size_t size; buffer >> size;
00196 for (size_t c= 0; c < size; c++) {
00197 Scalar_t scalar; buffer >> scalar; input.push_back (scalar); }
00198 return buffer; }
00199
00201 template <typename Base_t, typename Scalar_t> inline
00202 buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer,
00203 const list<Scalar_t>& output) {
00204 buffer << output.size();
00205 for (typename list<Scalar_t>::const_iterator it= output.begin(), end= output.end(); it != end;)
00206 buffer << *it++;
00207 return buffer; }
00208
00210 template <typename Base_t, typename Scalar_t> inline
00211 const buffer_t<Base_t>& operator>> (const buffer_t<Base_t>& buffer,
00212 deque<Scalar_t>& input) {
00213 size_t size; buffer >> size;
00214 for (size_t c= 0; c < size; c++) {
00215 Scalar_t scalar; buffer >> scalar; input.push_back (scalar); }
00216 return buffer; }
00217
00219 template <typename Base_t, typename Scalar_t> inline
00220 buffer_t<Base_t>& operator<< (buffer_t<Base_t>& buffer,
00221 const deque<Scalar_t>& output) {
00222 buffer << output.size();
00223 for (typename deque<Scalar_t>::const_iterator it= output.begin(), end= output.end();
00224 it != end;) buffer << *it++;
00225 return buffer; }
00226
00227 template <typename Base_t, typename Object_t>
00228 class comm_ref_t {
00229 public:
00230 typedef Base_t base_t;
00231 typedef Object_t object_t;
00232 private:
00233 object_t& my_object_ref;
00234 public:
00235 comm_ref_t (object_t& o) : my_object_ref (o) {}
00236 object_t& object_ref() {return my_object_ref; }
00237 const object_t& object_ref() const {return my_object_ref; }
00238 };
00239
00240 class Comm {
00241 protected:
00242 MPI::Intracomm my_comm;
00243 public:
00244 Comm (const MPI::Intracomm& mpi_comm) : my_comm (mpi_comm.Dup()) {}
00245
00246 MPI::Intracomm& mpi_comm_ref () {return my_comm;}
00247 const MPI::Intracomm& mpi_comm_ref () const {return my_comm;}
00248
00250 template <typename Comm_ref_t>
00251 void Send (const Comm_ref_t& data, int dest, int tag) const;
00252
00253 template <typename Comm_ref_t>
00254 void Recv (Comm_ref_t& data, int source, int tag, MPI::Status& status) const;
00255
00256 int Get_size () const {return my_comm.Get_size (); }
00257
00258 int Get_rank () const {return my_comm.Get_rank (); }
00259 };
00260
00261 class Intracomm : public Comm {
00262 public:
00263 Intracomm (MPI::Intracomm& mpi_comm) : Comm (mpi_comm) {}
00264
00265 void Barrier () const {my_comm.Barrier (); }
00266
00267 template <typename Comm_ref_t>
00268 void Bcast (Comm_ref_t& data, int root) const;
00269
00270 void Bcast (void* buffer, int count, const MPI::Datatype& datatype, int root) const {
00271 my_comm.Bcast (buffer, count, datatype, root); }
00272
00273 template <typename Comm_ref_t>
00274 void Reduce (const Comm_ref_t& senddata, Comm_ref_t& recvdata,
00275 const MPI::Op& op, int root) const;
00276
00277 template <typename Comm_ref_t>
00278 void Allreduce (const Comm_ref_t& senddata, Comm_ref_t& recvdata,
00279 const MPI::Op& op) const;
00280
00281
00282
00283
00284
00285 void Allreduce (const void* sendbuf, void* recvbuf, int count,
00286 const MPI::Datatype& datatype, const MPI::Op& op) const {
00287 my_comm.Allreduce (sendbuf, recvbuf, count, datatype, op); }
00288
00289 void Gather (const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,
00290 void* recvbuf, int recvcount, const MPI::Datatype& recvtype, int root) const {
00291 my_comm.Gather (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root); }
00292 };
00293
00294 }
00295
00296 #include "gmpi_impl.hpp"
00297
00298 #endif // _gmpi_include_
00299
00300
00301
00302
00303
00304