ESyS-Particle
4.0.1
|
00001 00002 // // 00003 // Copyright (c) 2003-2011 by The University of Queensland // 00004 // Earth Systems Science Computational Centre (ESSCC) // 00005 // http://www.uq.edu.au/esscc // 00006 // // 00007 // Primary Business: Brisbane, Queensland, Australia // 00008 // Licensed under the Open Software License version 3.0 // 00009 // http://www.opensource.org/licenses/osl-3.0.php // 00010 // // 00012 00013 00014 //--- point to point communication primitives for TML_Comm --- 00015 #include "tml/message/packed_message.h" 00016 00017 //--- STL --- 00018 #include <map> 00019 using std::map; 00020 00030 template <typename T> 00031 void TML_Comm::send_array(T* data,int ndata,int dest,int tag) 00032 { 00033 MPI_Send(data,ndata,GetType(*data),dest,tag,m_comm); 00034 } 00035 00045 template <typename T> 00046 void TML_Comm::receive_array(T* data,int ndata,int source,int tag) 00047 { 00048 MPI_Recv(data,ndata,GetType(*data),source,tag,m_comm,&m_status); 00049 } 00050 00063 template <typename T,typename P> 00064 void TML_Comm::sendrecv_array(T* send_data,int send_count,P* recv_data,int recv_count,int dest,int source,int tag) 00065 { 00066 MPI_Sendrecv(send_data,send_count,GetType(*send_data),dest,tag,recv_data,recv_count,GetType(*recv_data),source,tag,m_comm,&m_status); 00067 } 00068 00076 template <typename T> 00077 void TML_Comm::send(T data,int dest,int tag) 00078 { 00079 MPI_Send(&data,1,GetType(data),dest,tag,m_comm); 00080 } 00081 00082 00091 template <typename T> 00092 void TML_Comm::receive(T& data,int source ,int tag) 00093 { 00094 MPI_Recv(&data,1,GetType(data),source,tag,m_comm,&m_status); 00095 } 00096 template <typename T,typename P> 00107 void TML_Comm::sendrecv(T send_data,P& recv_data,int dest,int source,int tag) 00108 { 00109 MPI_Sendrecv(&send_data,1,GetType(send_data),dest,tag,&recv_data,1,GetType(recv_data),source,tag,m_comm,&m_status); 00110 } 00111 00119 template <typename T> 00120 void TML_Comm::send_cont(const T& data, int dest, int tag) 00121 { 00122 int data_size=data.size(); 00123 00124 // setup buffer 00125 typename T::value_type *buffer=new typename T::value_type[data_size]; 00126 00127 // put data into buffer 00128 int count=0; 00129 00130 for(typename T::const_iterator iter=data.begin(); 00131 iter!=data.end(); 00132 iter++){ 00133 void* buf=reinterpret_cast<void*>(&(buffer[count])); // get memory adress for buffer element 00134 new(buf)(typename T::value_type)(*iter); // initialize object at this adress 00135 // the placement new stuff (see Stroustrup, p.255ff) is necessary 00136 // because assignment buffer[count]=(*iter) doesn't work if the 00137 // T::value_type contains constant member data. Initialization by 00138 // calling the copy constructor directly doesn't work for builtin 00139 // types 00140 count++; 00141 } 00142 00143 //send size 00144 send(data_size,dest,tag); 00145 00146 //send data 00147 send_array(buffer,data_size,dest,tag+1024); 00148 00149 // clean up 00150 delete [] buffer; 00151 } 00152 00162 template <typename T> 00163 void TML_Comm::receive_cont(T& data,int source,int tag) 00164 { 00165 int data_size; 00166 00167 //get size 00168 receive(data_size,source,tag); 00169 // setup recv buffer 00170 typename T::value_type *buffer=new typename T::value_type[data_size]; 00171 00172 //get data 00173 receive_array(buffer,data_size,source,tag+1024); 00174 // insert into container 00175 for(int i=0;i<data_size;i++){ 00176 data.insert(data.end(),buffer[i]); 00177 } 00178 delete [] buffer; 00179 } 00180 00181 00191 template <typename T,typename P> 00192 void TML_Comm::sendrecv_cont(T send_data,P& recv_data,int dest,int source,int tag) 00193 { 00194 int send_count=send_data.size(); 00195 int recv_count; 00196 00197 // setup send buffer 00198 typename T::value_type *send_buffer=new typename T::value_type[send_count]; 00199 00200 // put data into send buffer 00201 int count=0; 00202 for(typename T::const_iterator iter=send_data.begin(); 00203 iter!=send_data.end(); 00204 iter++){ 00205 void* buf=reinterpret_cast<void*>(&(send_buffer[count])); // get memory adress for buffer element 00206 new(buf)(typename T::value_type)(*iter); // initialize object at this adress (see send_cont) 00207 count++; 00208 } 00209 00210 //send/receive size 00211 sendrecv(send_count,recv_count,dest,source,tag); 00212 // check for recv from Null process -> set recv_count to 0 if so 00213 if(source==MPI_PROC_NULL){ 00214 recv_count=0; 00215 } 00216 00217 // setup recv buffer 00218 typename T::value_type *recv_buffer=new typename T::value_type[recv_count]; 00219 00220 //send/receive data 00221 sendrecv_array(send_buffer,send_count,recv_buffer,recv_count,dest,source,tag+1024); 00222 00223 // insert into container 00224 for(int i=0;i<recv_count;i++){ 00225 recv_data.insert(recv_data.end(),recv_buffer[i]); 00226 } 00227 00228 delete [] send_buffer; 00229 delete [] recv_buffer; 00230 } 00231 00240 template <typename T> 00241 void TML_Comm::sendrecv_cont_replace(T& data,int dest,int source,int tag) 00242 { 00243 int send_count=data.size(); 00244 int recv_count; 00245 00246 // setup send buffer 00247 typename T::value_type *send_buffer=new typename T::value_type[send_count]; 00248 00249 // put data into send buffer 00250 int count=0; 00251 for(typename T::const_iterator iter=data.begin(); 00252 iter!=data.end(); 00253 iter++){ 00254 void* buf=reinterpret_cast<void*>(&(send_buffer[count])); // get memory adress for buffer element 00255 new(buf)(typename T::value_type)(*iter); // initialize object at this adress 00256 count++; 00257 } 00258 00259 //send/receive size 00260 sendrecv(send_count,recv_count,dest,source,tag); 00261 // check for recv from Null process -> set recv_count to 0 if so 00262 if(source==MPI_PROC_NULL){ 00263 recv_count=0; 00264 } 00265 00266 // setup recv buffer 00267 typename T::value_type *recv_buffer=new typename T::value_type[recv_count]; 00268 00269 //send/receive data 00270 sendrecv_array(send_buffer,send_count,recv_buffer,recv_count,dest,source,tag+1024); 00271 00272 // replace data 00273 data.erase(data.begin(),data.end()); 00274 // insert into container 00275 for(int i=0;i<recv_count;i++){ 00276 data.insert(data.end(),recv_buffer[i]); 00277 } 00278 00279 00280 delete [] send_buffer; 00281 delete [] recv_buffer; 00282 } 00283 00293 template <typename T> 00294 void TML_Comm::send_cont_packed(T data, int dest ,bool checked ,int tag) 00295 { 00296 TML_Packed_Message* msg=new TML_Packed_Message(m_comm); 00297 int nb_data=data.size(); 00298 00299 msg->pack(nb_data); // pack number of items first 00300 // pack data 00301 for(typename T::const_iterator iter=data.begin(); 00302 iter!=data.end(); 00303 iter++){ 00304 msg->pack(*iter); 00305 } 00306 00307 //send size 00308 send(msg->size(),dest,tag); 00309 00310 //send data 00311 send_array(msg->buffer(),msg->size(),dest,tag+1024); 00312 00313 delete msg; 00314 } 00315 00325 template <typename T> 00326 void TML_Comm::receive_cont_packed(T& data,int source,bool checked,int tag) 00327 { 00328 int msg_size; // total size of the message 00329 int nb_data; // number of data (i.e. the expected data.size()) 00330 00331 //get size 00332 receive(msg_size,source,tag); 00333 00334 TML_Packed_Message* msg=new TML_Packed_Message(m_comm,msg_size); 00335 00336 //get data 00337 receive_array(msg->buffer(),msg_size,source,tag+1024); 00338 00339 // extract nuber of items 00340 nb_data=msg->pop_int(); 00341 00342 // unpack data 00343 for(int i=0;i<nb_data;i++){ 00344 typename T::value_type tv; 00345 msg->unpack(tv); 00346 data.insert(data.end(),tv); 00347 } 00348 delete msg; 00349 } 00350 00361 template <typename T,typename P> 00362 void TML_Comm::sendrecv_cont_packed(T send_data, P& recv_data, int dest, int source, bool checked,int tag) 00363 { 00364 TML_Packed_Message* send_msg=new TML_Packed_Message(m_comm); 00365 00366 int send_nb_data=send_data.size(); 00367 int send_msg_size; 00368 int recv_nb_data; 00369 int recv_msg_size; 00370 00371 send_msg->pack(send_nb_data); // pack number of items first 00372 // pack data 00373 for(typename T::const_iterator iter=send_data.begin(); 00374 iter!=send_data.end(); 00375 iter++){ 00376 send_msg->pack(*iter); 00377 } 00378 send_msg_size=send_msg->size(); 00379 00380 //send/receive size 00381 sendrecv(send_msg_size,recv_msg_size,dest,source,tag); 00382 // check for recv from Null process -> set recv_count to 0 if so 00383 if(source==MPI_PROC_NULL){ 00384 recv_msg_size=0; 00385 } 00386 00387 // setup receive message 00388 TML_Packed_Message* recv_msg=new TML_Packed_Message(m_comm,recv_msg_size); 00389 00390 //send/receive data 00391 sendrecv_array(send_msg->buffer(),send_msg_size,recv_msg->buffer(),recv_msg_size,dest,source,tag+1024); 00392 00393 if(source!=MPI_PROC_NULL){ // if the source exists 00394 // extract nuber of items 00395 recv_nb_data=recv_msg->pop_int(); 00396 00397 // unpack data 00398 typename T::value_type tv; 00399 for(int i=0;i<recv_nb_data;i++){ 00400 recv_msg->unpack(tv); 00401 recv_data.insert(recv_data.end(),tv); 00402 } 00403 } 00404 delete send_msg; 00405 delete recv_msg; 00406 } 00407 00417 template <typename T> 00418 void TML_Comm::sendrecv_cont_packed_replace(T& data, int dest, int source, bool checked,int tag) 00419 { 00420 TML_Packed_Message* send_msg=new TML_Packed_Message(m_comm); 00421 00422 int send_nb_data=data.size(); 00423 int send_msg_size; 00424 int recv_nb_data; 00425 int recv_msg_size; 00426 00427 send_msg->pack(send_nb_data); // pack number of items first 00428 // pack data 00429 for(typename T::const_iterator iter=data.begin(); 00430 iter!=data.end(); 00431 iter++){ 00432 send_msg->pack(*iter); 00433 } 00434 send_msg_size=send_msg->size(); 00435 00436 //send/receive size 00437 sendrecv(send_msg_size,recv_msg_size,dest,source,tag); 00438 // check for recv from Null process -> set recv_count to 0 if so 00439 if(source==MPI_PROC_NULL){ 00440 recv_msg_size=0; 00441 } 00442 00443 // setup receive message 00444 TML_Packed_Message* recv_msg=new TML_Packed_Message(m_comm,recv_msg_size); 00445 00446 //send/receive data 00447 sendrecv_array(send_msg->buffer(),send_msg_size,recv_msg->buffer(),recv_msg_size,dest,source,tag+1024); 00448 00449 // extract nuber of items 00450 recv_nb_data=recv_msg->pop_int(); 00451 00452 // replace data 00453 data.erase(data.begin(),data.end()); 00454 for(int i=0;i<recv_nb_data;i++){ 00455 typename T::value_type tv; 00456 recv_msg->unpack(tv); 00457 data.insert(data.end(),tv); 00458 } 00459 00460 delete send_msg; 00461 delete recv_msg; 00462 } 00463