Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/toolx/mpi/wrmpi

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  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/typedefs
 19 #if defined(_MSC_VER) || defined(__MINGW32__)
 20 //typedef __int64 int64;
 21 //typedef unsigned __int64 uint64;
 22 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG_LONG
 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_LONG
 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::wrmpi");
 48     return s_v;
 49   }
 50 public: //tools::impi
 51   virtual bool pack(char a_val) {
 52     tools::uint32 sz = tools::uint32(sizeof(char));
 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_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
 55       m_out << "toolx::mpi::wrmpi : MPI_Pack(char) failed." << std::endl;
 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(short));
 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,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
 65       m_out << "toolx::mpi::wrmpi : MPI_Pack(short) failed." << std::endl;
 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(int));
 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_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
 75       m_out << "toolx::mpi::wrmpi : MPI_Pack(int) failed." << std::endl;
 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(unsigned int));
 83     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
 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(unsigned int) failed." << std::endl;
 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(tools::uint64));
 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_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
 95       m_out << "toolx::mpi::wrmpi : MPI_Pack(uint64) failed." << std::endl;
 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(tools::int64));
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_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
105       m_out << "toolx::mpi::wrmpi : MPI_Pack(int64) failed." << std::endl;
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(float));
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,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
115       m_out << "toolx::mpi::wrmpi : MPI_Pack(float) failed." << std::endl;
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(double));
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,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
125       m_out << "toolx::mpi::wrmpi : MPI_Pack(double) failed." << std::endl;
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(unsigned char));
133     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
134     unsigned char val = a_val?1:0;
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(bool) failed." << std::endl;
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+sz)) return false;}
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()),a_s.size(),MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
148 #else
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
151       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::string) failed." << std::endl;
152       return false;
153     }
154     m_pos += sz;
155     return true;
156   }
157   virtual bool vpack(const std::vector<unsigned int>& a_v) {
158     if(!pack((num_t)a_v.size())) return false;
159     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(unsigned int));
160     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
161 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
162     if(::MPI_Pack(const_cast<unsigned int*>(tools::vec_data(a_v)),a_v.size(),
163                   MPI_UNSIGNED,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
164 #else
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
167       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<unsigned int>) failed." << std::endl;
168       return false;
169     }
170     m_pos += sz;
171     return true;
172   }
173   virtual bool vpack(const std::vector<int>& a_v) {
174     if(!pack((num_t)a_v.size())) return false;
175     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(int));
176     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
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_data(a_v)),a_v.size(),MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
179 #else
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
182       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<int>) failed." << std::endl;
183       return false;
184     }
185     m_pos += sz;
186     return true;
187   }
188   virtual bool vpack(const std::vector<double>& a_v) {
189     if(!pack((num_t)a_v.size())) return false;
190     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(double));
191     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
192 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
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
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
197       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<double>) failed." << std::endl;
198       return false;
199     }
200     m_pos += sz;
201     return true;
202   }
203   virtual bool pack(tools::uint32 a_size,const char* a_buffer) {
204     if(!pack((num_t)a_size)) return false;
205     tools::uint32 sz = (tools::uint32)(a_size*sizeof(char));
206     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
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),a_size,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
209 #else
210     if(::MPI_Pack(a_buffer,a_size,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
211 #endif
212       m_out << "toolx::mpi::wrmpi : MPI_Pack(char*) failed." << std::endl;
213       return false;
214     }
215     m_pos += sz;
216     return true;
217   }
218 
219   virtual bool pack(tools::uint32 a_size,const int* a_buffer) {
220     if(!pack((num_t)a_size)) return false;
221     tools::uint32 sz = (tools::uint32)(a_size*sizeof(int));
222     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
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_size,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
225 #else
226     if(::MPI_Pack(a_buffer,a_size,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
227 #endif
228       m_out << "toolx::mpi::wrmpi : MPI_Pack(int*) failed." << std::endl;
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_val,1,MPI_CHAR,m_comm)!=MPI_SUCCESS) {
237       m_out << "toolx::mpi::wrmpi : MPI_Unpack(char) failed." << std::endl;
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_val,1,MPI_SHORT,m_comm)!=MPI_SUCCESS) {
245       m_out << "toolx::mpi::wrmpi : MPI_Unpack(short) failed." << std::endl;
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_val,1,MPI_INT,m_comm)!=MPI_SUCCESS) {
253       m_out << "toolx::mpi::wrmpi : MPI_Unpack(int) failed." << std::endl;
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_val,1,MPI_UNSIGNED,m_comm)!=MPI_SUCCESS) {
261       m_out << "toolx::mpi::wrmpi : MPI_Unpack(unsigned int) failed." << std::endl;
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_val,1,TOOLX_MPI_UINT64,m_comm)!=MPI_SUCCESS) {
269       m_out << "toolx::mpi::wrmpi : MPI_Unpack(uint64) failed." << std::endl;
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_val,1,TOOLX_MPI_INT64,m_comm)!=MPI_SUCCESS) {
277       m_out << "toolx::mpi::wrmpi : MPI_Unpack(int64) failed." << std::endl;
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_val,1,MPI_FLOAT,m_comm)!=MPI_SUCCESS) {
285       m_out << "toolx::mpi::wrmpi : MPI_Unpack(float) failed." << std::endl;
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_val,1,MPI_DOUBLE,m_comm)!=MPI_SUCCESS) {
293       m_out << "toolx::mpi::wrmpi : MPI_Unpack(double) failed." << std::endl;
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,&val,1,MPI_UNSIGNED_CHAR,m_comm)!=MPI_SUCCESS) {
303       m_out << "toolx::mpi::wrmpi : MPI_Unpack(bool) failed." << std::endl;
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 int>& a_v) {
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,tools::vec_data(a_v),a_v.size(),MPI_UNSIGNED,m_comm)!=MPI_SUCCESS) {
315       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<unsigned int>) failed." << std::endl;
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,tools::vec_data(a_v),a_v.size(),MPI_INT,m_comm)!=MPI_SUCCESS) {
326       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<int>) failed." << std::endl;
327       a_v.clear();
328       return false;
329     }
330     return true;
331   }
332   virtual bool vunpack(std::vector<double>& a_v) {
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,tools::vec_data(a_v),a_v.size(),MPI_DOUBLE,m_comm)!=MPI_SUCCESS) {
337       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<double>) failed." << std::endl;
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,const_cast<char*>(a_s.c_str()),a_s.size(),MPI_CHAR,m_comm)!=MPI_SUCCESS) {
348       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::string) failed." << std::endl;
349       a_s.clear();
350       return false;
351     }
352     return true;
353   }
354   virtual bool unpack(tools::uint32& a_size,char*& a_buffer) {
355     num_t num;
356     if(!unpack(num)) {a_size = 0;a_buffer = 0;return false;}
357     a_buffer = new char[num];
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(char*) failed." << std::endl;
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,int*& a_buffer) {
369     num_t num;
370     if(!unpack(num)) {a_size = 0;a_buffer = 0;return false;}
371     a_buffer = new int[num];
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(int*) failed." << std::endl;
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_tag) { // used in tools/mpi/pntuple.
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 : MPI_Send() failed for rank destination " << a_dest << "." << std::endl;
396       return false;
397     }
398     return true;
399   }
400 
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;
403     char* _buffer = 0;
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 : failed for rank " << a_rank << " and source " << a_src <<"." << std::endl;
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_tag,int& a_probe_src,bool a_verbose = false) {
419     return wait_buffer(a_rank,MPI_ANY_SOURCE,a_tag,a_probe_src,a_verbose);
420   }
421 
422 public:
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)
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_comm,tools::uint32 a_size,char* a_buffer) //we take ownership of a_buffer.
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) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
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) {return expand(tools::mx<tools::uint32>(2*m_size,a_new_size));} //CERN-ROOT logic.
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_size,m_size)) {
492       m_out << "toolx::mpi::wrmpi::expand :"
493             << " can't realloc " << a_new_size << " bytes."
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