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