Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/toolx/mpi/wrmpi is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef toolx_mpi_wrmpi
0005 #define toolx_mpi_wrmpi
0006 
0007 #include "wait_buffer"
0008 
0009 #include <tools/impi>
0010 #include <tools/vdata>
0011 #include <tools/realloc>
0012 #include <tools/mnmx>
0013 
0014 #ifdef TOOLS_MEM
0015 #include <tools/mem>
0016 #endif
0017 
0018 // the below must be in sync with tools/typedefs
0019 #if defined(_MSC_VER) || defined(__MINGW32__)
0020 //typedef __int64 int64;
0021 //typedef unsigned __int64 uint64;
0022 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG_LONG
0023 #define TOOLX_MPI_INT64  MPI_LONG_LONG
0024 #elif defined(_LP64)
0025 // 64 Bit Platforms
0026 //typedef long int64;
0027 //typedef unsigned long uint64;
0028 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG
0029 #define TOOLX_MPI_INT64  MPI_LONG
0030 #else
0031 // 32-Bit Platforms
0032 //typedef long long int64;
0033 //typedef unsigned long long uint64;
0034 #define TOOLX_MPI_UINT64 MPI_UNSIGNED_LONG_LONG
0035 #define TOOLX_MPI_INT64  MPI_LONG_LONG
0036 #endif
0037 
0038 namespace toolx {
0039 namespace mpi {
0040 
0041 class wrmpi : public virtual tools::impi {
0042   typedef tools::impi parent;
0043 public:
0044   typedef unsigned int num_t;
0045 protected:
0046   static const std::string& s_class() {
0047     static const std::string s_v("toolx::mpi::wrmpi");
0048     return s_v;
0049   }
0050 public: //tools::impi
0051   virtual bool pack(char a_val) {
0052     tools::uint32 sz = tools::uint32(sizeof(char));
0053     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0054     if(::MPI_Pack(&a_val,1,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0055       m_out << "toolx::mpi::wrmpi : MPI_Pack(char) failed." << std::endl;
0056       return false;
0057     }
0058     m_pos += sz;
0059     return true;
0060   }
0061   virtual bool pack(short a_val) {
0062     tools::uint32 sz = tools::uint32(sizeof(short));
0063     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0064     if(::MPI_Pack(&a_val,1,MPI_SHORT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0065       m_out << "toolx::mpi::wrmpi : MPI_Pack(short) failed." << std::endl;
0066       return false;
0067     }
0068     m_pos += sz;
0069     return true;
0070   }
0071   virtual bool pack(int a_val) {
0072     tools::uint32 sz = tools::uint32(sizeof(int));
0073     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0074     if(::MPI_Pack(&a_val,1,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0075       m_out << "toolx::mpi::wrmpi : MPI_Pack(int) failed." << std::endl;
0076       return false;
0077     }
0078     m_pos += sz;
0079     return true;
0080   }
0081   virtual bool pack(unsigned int a_val) {
0082     tools::uint32 sz = tools::uint32(sizeof(unsigned int));
0083     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0084     if(::MPI_Pack(&a_val,1,MPI_UNSIGNED,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0085       m_out << "toolx::mpi::wrmpi : MPI_Pack(unsigned int) failed." << std::endl;
0086       return false;
0087     }
0088     m_pos += sz;
0089     return true;
0090   }
0091   virtual bool pack(tools::uint64 a_val) {
0092     tools::uint32 sz = tools::uint32(sizeof(tools::uint64));
0093     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0094     if(::MPI_Pack(&a_val,1,TOOLX_MPI_UINT64,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0095       m_out << "toolx::mpi::wrmpi : MPI_Pack(uint64) failed." << std::endl;
0096       return false;
0097     }
0098     m_pos += sz;
0099     return true;
0100   }
0101   virtual bool pack(tools::int64 a_val) {
0102     tools::uint32 sz = tools::uint32(sizeof(tools::int64));
0103     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0104     if(::MPI_Pack(&a_val,1,TOOLX_MPI_INT64,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0105       m_out << "toolx::mpi::wrmpi : MPI_Pack(int64) failed." << std::endl;
0106       return false;
0107     }
0108     m_pos += sz;
0109     return true;
0110   }
0111   virtual bool pack(float a_val) {
0112     tools::uint32 sz = tools::uint32(sizeof(float));
0113     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0114     if(::MPI_Pack(&a_val,1,MPI_FLOAT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0115       m_out << "toolx::mpi::wrmpi : MPI_Pack(float) failed." << std::endl;
0116       return false;
0117     }
0118     m_pos += sz;
0119     return true;
0120   }
0121   virtual bool pack(double a_val) {
0122     tools::uint32 sz = tools::uint32(sizeof(double));
0123     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0124     if(::MPI_Pack(&a_val,1,MPI_DOUBLE,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0125       m_out << "toolx::mpi::wrmpi : MPI_Pack(double) failed." << std::endl;
0126       return false;
0127     }
0128     m_pos += sz;
0129     return true;
0130   }
0131   virtual bool bpack(bool a_val) {
0132     tools::uint32 sz = tools::uint32(sizeof(unsigned char));
0133     if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
0134     unsigned char val = a_val?1:0;
0135     if(::MPI_Pack(&val,1,MPI_UNSIGNED_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0136       m_out << "toolx::mpi::wrmpi : MPI_Pack(bool) failed." << std::endl;
0137       return false;
0138     }
0139     m_pos += sz;
0140     return true;
0141   }
0142   virtual bool spack(const std::string& a_s) {
0143     if(!pack((num_t)a_s.size())) return false;
0144     tools::uint32 sz = (tools::uint32)a_s.size();
0145     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0146 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0147     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) {
0148 #else
0149     if(::MPI_Pack(a_s.c_str(),a_s.size(),MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0150 #endif
0151       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::string) failed." << std::endl;
0152       return false;
0153     }
0154     m_pos += sz;
0155     return true;
0156   }
0157   virtual bool vpack(const std::vector<unsigned int>& a_v) {
0158     if(!pack((num_t)a_v.size())) return false;
0159     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(unsigned int));
0160     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0161 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0162     if(::MPI_Pack(const_cast<unsigned int*>(tools::vec_data(a_v)),a_v.size(),
0163                   MPI_UNSIGNED,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0164 #else
0165     if(::MPI_Pack(tools::vec_data(a_v),a_v.size(),MPI_UNSIGNED,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0166 #endif
0167       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<unsigned int>) failed." << std::endl;
0168       return false;
0169     }
0170     m_pos += sz;
0171     return true;
0172   }
0173   virtual bool vpack(const std::vector<int>& a_v) {
0174     if(!pack((num_t)a_v.size())) return false;
0175     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(int));
0176     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0177 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0178     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) {
0179 #else
0180     if(::MPI_Pack(tools::vec_data(a_v),a_v.size(),MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0181 #endif
0182       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<int>) failed." << std::endl;
0183       return false;
0184     }
0185     m_pos += sz;
0186     return true;
0187   }
0188   virtual bool vpack(const std::vector<double>& a_v) {
0189     if(!pack((num_t)a_v.size())) return false;
0190     tools::uint32 sz = (tools::uint32)(a_v.size()*sizeof(double));
0191     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0192 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0193     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) {
0194 #else
0195     if(::MPI_Pack(tools::vec_data(a_v),a_v.size(),MPI_DOUBLE,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0196 #endif
0197       m_out << "toolx::mpi::wrmpi : MPI_Pack(std::vector<double>) failed." << std::endl;
0198       return false;
0199     }
0200     m_pos += sz;
0201     return true;
0202   }
0203   virtual bool pack(tools::uint32 a_size,const char* a_buffer) {
0204     if(!pack((num_t)a_size)) return false;
0205     tools::uint32 sz = (tools::uint32)(a_size*sizeof(char));
0206     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0207 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0208     if(::MPI_Pack(const_cast<char*>(a_buffer),a_size,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0209 #else
0210     if(::MPI_Pack(a_buffer,a_size,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0211 #endif
0212       m_out << "toolx::mpi::wrmpi : MPI_Pack(char*) failed." << std::endl;
0213       return false;
0214     }
0215     m_pos += sz;
0216     return true;
0217   }
0218 
0219   virtual bool pack(tools::uint32 a_size,const int* a_buffer) {
0220     if(!pack((num_t)a_size)) return false;
0221     tools::uint32 sz = (tools::uint32)(a_size*sizeof(int));
0222     if((m_pos+sz)>m_max) {if(!expand2(m_size+sz)) return false;}
0223 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0224     if(::MPI_Pack(const_cast<int*>(a_buffer),a_size,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0225 #else
0226     if(::MPI_Pack(a_buffer,a_size,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
0227 #endif
0228       m_out << "toolx::mpi::wrmpi : MPI_Pack(int*) failed." << std::endl;
0229       return false;
0230     }
0231     m_pos += sz;
0232     return true;
0233   }
0234 public: //tools::impi
0235   virtual bool unpack(char& a_val) {
0236     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_CHAR,m_comm)!=MPI_SUCCESS) {
0237       m_out << "toolx::mpi::wrmpi : MPI_Unpack(char) failed." << std::endl;
0238       a_val = 0;
0239       return false;
0240     }
0241     return true;
0242   }
0243   virtual bool unpack(short& a_val) {
0244     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_SHORT,m_comm)!=MPI_SUCCESS) {
0245       m_out << "toolx::mpi::wrmpi : MPI_Unpack(short) failed." << std::endl;
0246       a_val = 0;
0247       return false;
0248     }
0249     return true;
0250   }
0251   virtual bool unpack(int& a_val) {
0252     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_INT,m_comm)!=MPI_SUCCESS) {
0253       m_out << "toolx::mpi::wrmpi : MPI_Unpack(int) failed." << std::endl;
0254       a_val = 0;
0255       return false;
0256     }
0257     return true;
0258   }
0259   virtual bool unpack(unsigned int& a_val) {
0260     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_UNSIGNED,m_comm)!=MPI_SUCCESS) {
0261       m_out << "toolx::mpi::wrmpi : MPI_Unpack(unsigned int) failed." << std::endl;
0262       a_val = 0;
0263       return false;
0264     }
0265     return true;
0266   }
0267   virtual bool unpack(tools::uint64& a_val) {
0268     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,TOOLX_MPI_UINT64,m_comm)!=MPI_SUCCESS) {
0269       m_out << "toolx::mpi::wrmpi : MPI_Unpack(uint64) failed." << std::endl;
0270       a_val = 0;
0271       return false;
0272     }
0273     return true;
0274   }
0275   virtual bool unpack(tools::int64& a_val) {
0276     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,TOOLX_MPI_INT64,m_comm)!=MPI_SUCCESS) {
0277       m_out << "toolx::mpi::wrmpi : MPI_Unpack(int64) failed." << std::endl;
0278       a_val = 0;
0279       return false;
0280     }
0281     return true;
0282   }
0283   virtual bool unpack(float& a_val) {
0284     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_FLOAT,m_comm)!=MPI_SUCCESS) {
0285       m_out << "toolx::mpi::wrmpi : MPI_Unpack(float) failed." << std::endl;
0286       a_val = 0;
0287       return false;
0288     }
0289     return true;
0290   }
0291   virtual bool unpack(double& a_val) {
0292     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_DOUBLE,m_comm)!=MPI_SUCCESS) {
0293       m_out << "toolx::mpi::wrmpi : MPI_Unpack(double) failed." << std::endl;
0294       a_val = 0;
0295       return false;
0296     }
0297     return true;
0298   }
0299   virtual bool bunpack(bool& a_val) {
0300     typedef unsigned char bool_t;
0301     bool_t val;
0302     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&val,1,MPI_UNSIGNED_CHAR,m_comm)!=MPI_SUCCESS) {
0303       m_out << "toolx::mpi::wrmpi : MPI_Unpack(bool) failed." << std::endl;
0304       a_val = false;
0305       return false;
0306     }
0307     a_val = val==1?true:false;
0308     return true;
0309   }
0310   virtual bool vunpack(std::vector<unsigned int>& a_v) {
0311     num_t num;
0312     if(!unpack(num)) {a_v.clear();return false;}
0313     a_v.resize(num);
0314     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,tools::vec_data(a_v),a_v.size(),MPI_UNSIGNED,m_comm)!=MPI_SUCCESS) {
0315       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<unsigned int>) failed." << std::endl;
0316       a_v.clear();
0317       return false;
0318     }
0319     return true;
0320   }
0321   virtual bool vunpack(std::vector<int>& a_v) {
0322     num_t num;
0323     if(!unpack(num)) {a_v.clear();return false;}
0324     a_v.resize(num);
0325     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,tools::vec_data(a_v),a_v.size(),MPI_INT,m_comm)!=MPI_SUCCESS) {
0326       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<int>) failed." << std::endl;
0327       a_v.clear();
0328       return false;
0329     }
0330     return true;
0331   }
0332   virtual bool vunpack(std::vector<double>& a_v) {
0333     num_t num;
0334     if(!unpack(num)) {a_v.clear();return false;}
0335     a_v.resize(num);
0336     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,tools::vec_data(a_v),a_v.size(),MPI_DOUBLE,m_comm)!=MPI_SUCCESS) {
0337       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::vector<double>) failed." << std::endl;
0338       a_v.clear();
0339       return false;
0340     }
0341     return true;
0342   }
0343   virtual bool sunpack(std::string& a_s) {
0344     num_t num;
0345     if(!unpack(num)) {a_s.clear();return false;}
0346     a_s.resize(num);
0347     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) {
0348       m_out << "toolx::mpi::wrmpi : MPI_Unpack(std::string) failed." << std::endl;
0349       a_s.clear();
0350       return false;
0351     }
0352     return true;
0353   }
0354   virtual bool unpack(tools::uint32& a_size,char*& a_buffer) {
0355     num_t num;
0356     if(!unpack(num)) {a_size = 0;a_buffer = 0;return false;}
0357     a_buffer = new char[num];
0358     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,a_buffer,num,MPI_CHAR,m_comm)!=MPI_SUCCESS) {
0359       m_out << "toolx::mpi::wrmpi : MPI_Unpack(char*) failed." << std::endl;
0360       delete [] a_buffer;
0361       a_size = 0;
0362       a_buffer = 0;
0363       return false;
0364     }
0365     a_size = num;
0366     return true;
0367   }
0368   virtual bool unpack(tools::uint32& a_size,int*& a_buffer) {
0369     num_t num;
0370     if(!unpack(num)) {a_size = 0;a_buffer = 0;return false;}
0371     a_buffer = new int[num];
0372     if(::MPI_Unpack(m_buffer,m_size,&m_ipos,a_buffer,num,MPI_INT,m_comm)!=MPI_SUCCESS) {
0373       m_out << "toolx::mpi::wrmpi : MPI_Unpack(int*) failed." << std::endl;
0374       delete [] a_buffer;
0375       a_size = 0;
0376       a_buffer = 0;
0377       return false;
0378     }
0379     a_size = num;
0380     return true;
0381   }
0382 
0383   virtual void pack_reset() {
0384     delete [] m_buffer;
0385     m_size = 128;
0386     m_buffer = new char[m_size];
0387     //if(!m_buffer) {}
0388     m_max = m_buffer+m_size;
0389     m_pos = m_buffer;
0390     m_ipos = 0; //IMPORTANT
0391   }
0392 
0393   virtual bool send_buffer(int a_dest,int a_tag) { // used in tools/mpi/pntuple.
0394     if(::MPI_Send(m_buffer,m_ipos,MPI_CHAR,a_dest,a_tag,m_comm)!=MPI_SUCCESS) {
0395       m_out << "toolx::mpi::wrmpi::send_buffer : MPI_Send() failed for rank destination " << a_dest << "." << std::endl;
0396       return false;
0397     }
0398     return true;
0399   }
0400 
0401   virtual bool wait_buffer(int a_rank,int a_src,int a_tag,int& a_probe_src,bool a_verbose = false) {
0402     int buffer_size = 0;
0403     char* _buffer = 0;
0404     if (!mpi::wait_buffer(m_out,a_rank,a_src,a_tag,m_comm,buffer_size,_buffer,a_probe_src,a_verbose)) {
0405       m_out << "toolx::mpi::wrmpi::wait_buffer : failed for rank " << a_rank << " and source " << a_src <<"." << std::endl;
0406       return false;
0407     }
0408     // we take ownership of buffer :
0409     delete [] m_buffer;
0410     m_size = buffer_size;
0411     m_buffer = _buffer;
0412     m_max = m_buffer+m_size;
0413     m_pos = m_buffer;
0414     m_ipos = 0; //IMPORTANT
0415     return true;
0416   }
0417 
0418   virtual bool wait_buffer(int a_rank,int a_tag,int& a_probe_src,bool a_verbose = false) {
0419     return wait_buffer(a_rank,MPI_ANY_SOURCE,a_tag,a_probe_src,a_verbose);
0420   }
0421 
0422 public:
0423   wrmpi(std::ostream& a_out,const MPI_Comm& a_comm,tools::uint32 a_size = 128) // we expect a_size!=0
0424   :m_out(a_out)
0425   ,m_comm(a_comm)
0426   ,m_size(0)
0427   ,m_buffer(0)
0428   ,m_max(0)
0429   ,m_pos(0)
0430   ,m_ipos(0)
0431   {
0432 #ifdef TOOLS_MEM
0433     tools::mem::increment(s_class().c_str());
0434 #endif
0435     m_size = a_size;
0436     m_buffer = new char[m_size];
0437     //if(!m_buffer) {}
0438     m_max = m_buffer+m_size;
0439     m_pos = m_buffer;
0440   }
0441    wrmpi(std::ostream& a_out,const MPI_Comm& a_comm,tools::uint32 a_size,char* a_buffer) //we take ownership of a_buffer.
0442   :m_out(a_out)
0443   ,m_comm(a_comm)
0444   ,m_size(a_size)
0445   ,m_buffer(a_buffer)
0446   ,m_max(0)
0447   ,m_pos(0)
0448   ,m_ipos(0)
0449   {
0450 #ifdef TOOLS_MEM
0451     tools::mem::increment(s_class().c_str());
0452 #endif
0453     m_max = m_buffer+m_size;
0454     m_pos = m_buffer;
0455   }
0456   virtual ~wrmpi(){
0457     delete [] m_buffer;
0458 #ifdef TOOLS_MEM
0459     tools::mem::decrement(s_class().c_str());
0460 #endif
0461   }
0462 protected:
0463   wrmpi(const wrmpi& a_from)
0464   :parent(a_from)
0465   ,m_out(a_from.m_out)
0466   ,m_comm(a_from.m_comm)
0467   ,m_size(0)
0468   ,m_buffer(0)
0469   ,m_max(0)
0470   ,m_pos(0)
0471   ,m_ipos(0)
0472   {
0473 #ifdef TOOLS_MEM
0474     tools::mem::increment(s_class().c_str());
0475 #endif
0476   }
0477   wrmpi& operator=(const wrmpi&){return *this;}
0478 public:
0479   int ipos() const {return m_ipos;}
0480 #if defined(TOOLX_USE_MPI_PACK_NOT_CONST) || defined(TOOLS_USE_MPI_PACK_NOT_CONST)
0481   char* buffer() {return m_buffer;}
0482 #else
0483   const char* buffer() const {return m_buffer;}
0484 #endif
0485 
0486 protected:
0487   bool expand2(tools::uint32 a_new_size) {return expand(tools::mx<tools::uint32>(2*m_size,a_new_size));} //CERN-ROOT logic.
0488 
0489   bool expand(tools::uint32 a_new_size) {
0490     tools::diff_pointer_t len = m_pos-m_buffer;
0491     if(!tools::realloc<char>(m_buffer,a_new_size,m_size)) {
0492       m_out << "toolx::mpi::wrmpi::expand :"
0493             << " can't realloc " << a_new_size << " bytes."
0494             << std::endl;
0495       m_size = 0;
0496       m_max = 0;
0497       m_pos = 0;
0498       //m_wb.set_eob(m_max);
0499       return false;
0500     }
0501     m_size = a_new_size;
0502     m_max = m_buffer + m_size;
0503     m_pos = m_buffer + len;
0504     return true;
0505   }
0506 
0507 protected:
0508   std::ostream& m_out;
0509   const MPI_Comm& m_comm;
0510   tools::uint32 m_size;
0511   char* m_buffer;
0512   char* m_max;
0513   char* m_pos;
0514   //
0515   int m_ipos;
0516 };
0517 
0518 }}
0519 
0520 #ifdef TOOLX_MPI_UINT64
0521 #undef TOOLX_MPI_UINT64
0522 #endif
0523 
0524 #ifdef TOOLX_MPI_INT64
0525 #undef TOOLX_MPI_INT64
0526 #endif
0527 
0528 #endif