Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef toolx_mpi_wrmpi 5 #define toolx_mpi_wrmpi 6 7 #include "wait_buffer" 8 9 #include <tools/impi> 10 #include <tools/vdata> 11 #include <tools/realloc> 12 #include <tools/mnmx> 13 14 #ifdef TOOLS_MEM 15 #include <tools/mem> 16 #endif 17 18 // the below must be in sync with tools/typede 19 #if defined(_MSC_VER) || defined(__MINGW32__) 20 //typedef __int64 int64; 21 //typedef unsigned __int64 uint64; 22 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG_LON 23 #define TOOLX_MPI_INT64 MPI_LONG_LONG 24 #elif defined(_LP64) 25 // 64 Bit Platforms 26 //typedef long int64; 27 //typedef unsigned long uint64; 28 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG 29 #define TOOLX_MPI_INT64 MPI_LONG 30 #else 31 // 32-Bit Platforms 32 //typedef long long int64; 33 //typedef unsigned long long uint64; 34 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG_LON 35 #define TOOLX_MPI_INT64 MPI_LONG_LONG 36 #endif 37 38 namespace toolx { 39 namespace mpi { 40 41 class wrmpi : public virtual tools::impi { 42 typedef tools::impi parent; 43 public: 44 typedef unsigned int num_t; 45 protected: 46 static const std::string& s_class() { 47 static const std::string s_v("toolx::mpi:: 48 return s_v; 49 } 50 public: //tools::impi 51 virtual bool pack(char a_val) { 52 tools::uint32 sz = tools::uint32(sizeof(ch 53 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 54 if(::MPI_Pack(&a_val,1,MPI_CHAR,m_buffer,m 55 m_out << "toolx::mpi::wrmpi : MPI_Pack(c 56 return false; 57 } 58 m_pos += sz; 59 return true; 60 } 61 virtual bool pack(short a_val) { 62 tools::uint32 sz = tools::uint32(sizeof(sh 63 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 64 if(::MPI_Pack(&a_val,1,MPI_SHORT,m_buffer, 65 m_out << "toolx::mpi::wrmpi : MPI_Pack(s 66 return false; 67 } 68 m_pos += sz; 69 return true; 70 } 71 virtual bool pack(int a_val) { 72 tools::uint32 sz = tools::uint32(sizeof(in 73 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 74 if(::MPI_Pack(&a_val,1,MPI_INT,m_buffer,m_ 75 m_out << "toolx::mpi::wrmpi : MPI_Pack(i 76 return false; 77 } 78 m_pos += sz; 79 return true; 80 } 81 virtual bool pack(unsigned int a_val) { 82 tools::uint32 sz = tools::uint32(sizeof(un 83 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 84 if(::MPI_Pack(&a_val,1,MPI_UNSIGNED,m_buff 85 m_out << "toolx::mpi::wrmpi : MPI_Pack(u 86 return false; 87 } 88 m_pos += sz; 89 return true; 90 } 91 virtual bool pack(tools::uint64 a_val) { 92 tools::uint32 sz = tools::uint32(sizeof(to 93 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 94 if(::MPI_Pack(&a_val,1,TOOLX_MPI_UINT64,m_ 95 m_out << "toolx::mpi::wrmpi : MPI_Pack(u 96 return false; 97 } 98 m_pos += sz; 99 return true; 100 } 101 virtual bool pack(tools::int64 a_val) { 102 tools::uint32 sz = tools::uint32(sizeof(to 103 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 104 if(::MPI_Pack(&a_val,1,TOOLX_MPI_INT64,m_b 105 m_out << "toolx::mpi::wrmpi : MPI_Pack(i 106 return false; 107 } 108 m_pos += sz; 109 return true; 110 } 111 virtual bool pack(float a_val) { 112 tools::uint32 sz = tools::uint32(sizeof(fl 113 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 114 if(::MPI_Pack(&a_val,1,MPI_FLOAT,m_buffer, 115 m_out << "toolx::mpi::wrmpi : MPI_Pack(f 116 return false; 117 } 118 m_pos += sz; 119 return true; 120 } 121 virtual bool pack(double a_val) { 122 tools::uint32 sz = tools::uint32(sizeof(do 123 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 124 if(::MPI_Pack(&a_val,1,MPI_DOUBLE,m_buffer 125 m_out << "toolx::mpi::wrmpi : MPI_Pack(d 126 return false; 127 } 128 m_pos += sz; 129 return true; 130 } 131 virtual bool bpack(bool a_val) { 132 tools::uint32 sz = tools::uint32(sizeof(un 133 if(m_pos+sz>m_max) {if(!expand2(m_size+sz) 134 unsigned char val = a_val?1:0; 135 if(::MPI_Pack(&val,1,MPI_UNSIGNED_CHAR,m_b 136 m_out << "toolx::mpi::wrmpi : MPI_Pack(b 137 return false; 138 } 139 m_pos += sz; 140 return true; 141 } 142 virtual bool spack(const std::string& a_s) { 143 if(!pack((num_t)a_s.size())) return false; 144 tools::uint32 sz = (tools::uint32)a_s.size 145 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 146 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 147 if(::MPI_Pack(const_cast<char*>(a_s.c_str( 148 #else 149 if(::MPI_Pack(a_s.c_str(),a_s.size(),MPI_C 150 #endif 151 m_out << "toolx::mpi::wrmpi : MPI_Pack(s 152 return false; 153 } 154 m_pos += sz; 155 return true; 156 } 157 virtual bool vpack(const std::vector<unsigne 158 if(!pack((num_t)a_v.size())) return false; 159 tools::uint32 sz = (tools::uint32)(a_v.siz 160 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 161 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 162 if(::MPI_Pack(const_cast<unsigned int*>(to 163 MPI_UNSIGNED,m_buffer,m_size 164 #else 165 if(::MPI_Pack(tools::vec_data(a_v),a_v.siz 166 #endif 167 m_out << "toolx::mpi::wrmpi : MPI_Pack(s 168 return false; 169 } 170 m_pos += sz; 171 return true; 172 } 173 virtual bool vpack(const std::vector<int>& a 174 if(!pack((num_t)a_v.size())) return false; 175 tools::uint32 sz = (tools::uint32)(a_v.siz 176 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 177 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 178 if(::MPI_Pack(const_cast<int*>(tools::vec_ 179 #else 180 if(::MPI_Pack(tools::vec_data(a_v),a_v.siz 181 #endif 182 m_out << "toolx::mpi::wrmpi : MPI_Pack(s 183 return false; 184 } 185 m_pos += sz; 186 return true; 187 } 188 virtual bool vpack(const std::vector<double> 189 if(!pack((num_t)a_v.size())) return false; 190 tools::uint32 sz = (tools::uint32)(a_v.siz 191 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 192 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 193 if(::MPI_Pack(const_cast<double*>(tools::v 194 #else 195 if(::MPI_Pack(tools::vec_data(a_v),a_v.siz 196 #endif 197 m_out << "toolx::mpi::wrmpi : MPI_Pack(s 198 return false; 199 } 200 m_pos += sz; 201 return true; 202 } 203 virtual bool pack(tools::uint32 a_size,const 204 if(!pack((num_t)a_size)) return false; 205 tools::uint32 sz = (tools::uint32)(a_size* 206 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 207 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 208 if(::MPI_Pack(const_cast<char*>(a_buffer), 209 #else 210 if(::MPI_Pack(a_buffer,a_size,MPI_CHAR,m_b 211 #endif 212 m_out << "toolx::mpi::wrmpi : MPI_Pack(c 213 return false; 214 } 215 m_pos += sz; 216 return true; 217 } 218 219 virtual bool pack(tools::uint32 a_size,const 220 if(!pack((num_t)a_size)) return false; 221 tools::uint32 sz = (tools::uint32)(a_size* 222 if((m_pos+sz)>m_max) {if(!expand2(m_size+s 223 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 224 if(::MPI_Pack(const_cast<int*>(a_buffer),a 225 #else 226 if(::MPI_Pack(a_buffer,a_size,MPI_INT,m_bu 227 #endif 228 m_out << "toolx::mpi::wrmpi : MPI_Pack(i 229 return false; 230 } 231 m_pos += sz; 232 return true; 233 } 234 public: //tools::impi 235 virtual bool unpack(char& a_val) { 236 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 237 m_out << "toolx::mpi::wrmpi : MPI_Unpack 238 a_val = 0; 239 return false; 240 } 241 return true; 242 } 243 virtual bool unpack(short& a_val) { 244 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 245 m_out << "toolx::mpi::wrmpi : MPI_Unpack 246 a_val = 0; 247 return false; 248 } 249 return true; 250 } 251 virtual bool unpack(int& a_val) { 252 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 253 m_out << "toolx::mpi::wrmpi : MPI_Unpack 254 a_val = 0; 255 return false; 256 } 257 return true; 258 } 259 virtual bool unpack(unsigned int& a_val) { 260 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 261 m_out << "toolx::mpi::wrmpi : MPI_Unpack 262 a_val = 0; 263 return false; 264 } 265 return true; 266 } 267 virtual bool unpack(tools::uint64& a_val) { 268 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 269 m_out << "toolx::mpi::wrmpi : MPI_Unpack 270 a_val = 0; 271 return false; 272 } 273 return true; 274 } 275 virtual bool unpack(tools::int64& a_val) { 276 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 277 m_out << "toolx::mpi::wrmpi : MPI_Unpack 278 a_val = 0; 279 return false; 280 } 281 return true; 282 } 283 virtual bool unpack(float& a_val) { 284 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 285 m_out << "toolx::mpi::wrmpi : MPI_Unpack 286 a_val = 0; 287 return false; 288 } 289 return true; 290 } 291 virtual bool unpack(double& a_val) { 292 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a 293 m_out << "toolx::mpi::wrmpi : MPI_Unpack 294 a_val = 0; 295 return false; 296 } 297 return true; 298 } 299 virtual bool bunpack(bool& a_val) { 300 typedef unsigned char bool_t; 301 bool_t val; 302 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&v 303 m_out << "toolx::mpi::wrmpi : MPI_Unpack 304 a_val = false; 305 return false; 306 } 307 a_val = val==1?true:false; 308 return true; 309 } 310 virtual bool vunpack(std::vector<unsigned in 311 num_t num; 312 if(!unpack(num)) {a_v.clear();return false 313 a_v.resize(num); 314 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,to 315 m_out << "toolx::mpi::wrmpi : MPI_Unpack 316 a_v.clear(); 317 return false; 318 } 319 return true; 320 } 321 virtual bool vunpack(std::vector<int>& a_v) 322 num_t num; 323 if(!unpack(num)) {a_v.clear();return false 324 a_v.resize(num); 325 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,to 326 m_out << "toolx::mpi::wrmpi : MPI_Unpack 327 a_v.clear(); 328 return false; 329 } 330 return true; 331 } 332 virtual bool vunpack(std::vector<double>& a_ 333 num_t num; 334 if(!unpack(num)) {a_v.clear();return false 335 a_v.resize(num); 336 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,to 337 m_out << "toolx::mpi::wrmpi : MPI_Unpack 338 a_v.clear(); 339 return false; 340 } 341 return true; 342 } 343 virtual bool sunpack(std::string& a_s) { 344 num_t num; 345 if(!unpack(num)) {a_s.clear();return false 346 a_s.resize(num); 347 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,co 348 m_out << "toolx::mpi::wrmpi : MPI_Unpack 349 a_s.clear(); 350 return false; 351 } 352 return true; 353 } 354 virtual bool unpack(tools::uint32& a_size,ch 355 num_t num; 356 if(!unpack(num)) {a_size = 0;a_buffer = 0; 357 a_buffer = new char[num]; 358 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,a_ 359 m_out << "toolx::mpi::wrmpi : MPI_Unpack 360 delete [] a_buffer; 361 a_size = 0; 362 a_buffer = 0; 363 return false; 364 } 365 a_size = num; 366 return true; 367 } 368 virtual bool unpack(tools::uint32& a_size,in 369 num_t num; 370 if(!unpack(num)) {a_size = 0;a_buffer = 0; 371 a_buffer = new int[num]; 372 if(::MPI_Unpack(m_buffer,m_size,&m_ipos,a_ 373 m_out << "toolx::mpi::wrmpi : MPI_Unpack 374 delete [] a_buffer; 375 a_size = 0; 376 a_buffer = 0; 377 return false; 378 } 379 a_size = num; 380 return true; 381 } 382 383 virtual void pack_reset() { 384 delete [] m_buffer; 385 m_size = 128; 386 m_buffer = new char[m_size]; 387 //if(!m_buffer) {} 388 m_max = m_buffer+m_size; 389 m_pos = m_buffer; 390 m_ipos = 0; //IMPORTANT 391 } 392 393 virtual bool send_buffer(int a_dest,int a_ta 394 if(::MPI_Send(m_buffer,m_ipos,MPI_CHAR,a_d 395 m_out << "toolx::mpi::wrmpi::send_buffer 396 return false; 397 } 398 return true; 399 } 400 401 virtual bool wait_buffer(int a_rank,int a_sr 402 int buffer_size = 0; 403 char* _buffer = 0; 404 if (!mpi::wait_buffer(m_out,a_rank,a_src,a 405 m_out << "toolx::mpi::wrmpi::wait_buffer 406 return false; 407 } 408 // we take ownership of buffer : 409 delete [] m_buffer; 410 m_size = buffer_size; 411 m_buffer = _buffer; 412 m_max = m_buffer+m_size; 413 m_pos = m_buffer; 414 m_ipos = 0; //IMPORTANT 415 return true; 416 } 417 418 virtual bool wait_buffer(int a_rank,int a_ta 419 return wait_buffer(a_rank,MPI_ANY_SOURCE,a 420 } 421 422 public: 423 wrmpi(std::ostream& a_out,const MPI_Comm& a_ 424 :m_out(a_out) 425 ,m_comm(a_comm) 426 ,m_size(0) 427 ,m_buffer(0) 428 ,m_max(0) 429 ,m_pos(0) 430 ,m_ipos(0) 431 { 432 #ifdef TOOLS_MEM 433 tools::mem::increment(s_class().c_str()); 434 #endif 435 m_size = a_size; 436 m_buffer = new char[m_size]; 437 //if(!m_buffer) {} 438 m_max = m_buffer+m_size; 439 m_pos = m_buffer; 440 } 441 wrmpi(std::ostream& a_out,const MPI_Comm& a 442 :m_out(a_out) 443 ,m_comm(a_comm) 444 ,m_size(a_size) 445 ,m_buffer(a_buffer) 446 ,m_max(0) 447 ,m_pos(0) 448 ,m_ipos(0) 449 { 450 #ifdef TOOLS_MEM 451 tools::mem::increment(s_class().c_str()); 452 #endif 453 m_max = m_buffer+m_size; 454 m_pos = m_buffer; 455 } 456 virtual ~wrmpi(){ 457 delete [] m_buffer; 458 #ifdef TOOLS_MEM 459 tools::mem::decrement(s_class().c_str()); 460 #endif 461 } 462 protected: 463 wrmpi(const wrmpi& a_from) 464 :parent(a_from) 465 ,m_out(a_from.m_out) 466 ,m_comm(a_from.m_comm) 467 ,m_size(0) 468 ,m_buffer(0) 469 ,m_max(0) 470 ,m_pos(0) 471 ,m_ipos(0) 472 { 473 #ifdef TOOLS_MEM 474 tools::mem::increment(s_class().c_str()); 475 #endif 476 } 477 wrmpi& operator=(const wrmpi&){return *this; 478 public: 479 int ipos() const {return m_ipos;} 480 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || d 481 char* buffer() {return m_buffer;} 482 #else 483 const char* buffer() const {return m_buffer; 484 #endif 485 486 protected: 487 bool expand2(tools::uint32 a_new_size) {retu 488 489 bool expand(tools::uint32 a_new_size) { 490 tools::diff_pointer_t len = m_pos-m_buffer 491 if(!tools::realloc<char>(m_buffer,a_new_si 492 m_out << "toolx::mpi::wrmpi::expand :" 493 << " can't realloc " << a_new_size 494 << std::endl; 495 m_size = 0; 496 m_max = 0; 497 m_pos = 0; 498 //m_wb.set_eob(m_max); 499 return false; 500 } 501 m_size = a_new_size; 502 m_max = m_buffer + m_size; 503 m_pos = m_buffer + len; 504 return true; 505 } 506 507 protected: 508 std::ostream& m_out; 509 const MPI_Comm& m_comm; 510 tools::uint32 m_size; 511 char* m_buffer; 512 char* m_max; 513 char* m_pos; 514 // 515 int m_ipos; 516 }; 517 518 }} 519 520 #ifdef TOOLX_MPI_UINT64 521 #undef TOOLX_MPI_UINT64 522 #endif 523 524 #ifdef TOOLX_MPI_INT64 525 #undef TOOLX_MPI_INT64 526 #endif 527 528 #endif