Warning, /include/Geant4/toolx/mpi/hmpi 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_hmpi
0005 #define toolx_mpi_hmpi
0006
0007 // code to send, receive histos through MPI.
0008
0009 #include <tools/histo/hmpi>
0010 #include <tools/histo/hd2mpi>
0011
0012 #include <tools/histo/h1d>
0013 #include <tools/histo/h2d>
0014 #include <tools/histo/h3d>
0015 #include <tools/histo/p1d>
0016 #include <tools/histo/p2d>
0017
0018 #include "wrmpi"
0019
0020 namespace toolx {
0021 namespace mpi {
0022
0023 class hmpi : public virtual tools::histo::hmpi {
0024 typedef tools::histo::hmpi parent;
0025 protected:
0026 typedef unsigned int num_t;
0027 static const std::string& s_class() {
0028 static const std::string s_v("toolx::mpi::hmpi");
0029 return s_v;
0030 }
0031 public:
0032 virtual bool pack(const tools::histo::h1d& a_h) {
0033 if(!m_wrmpi.spack(a_h.s_cls())) return false;
0034 if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
0035 return true;
0036 }
0037 virtual bool pack(const tools::histo::h2d& a_h) {
0038 if(!m_wrmpi.spack(a_h.s_cls())) return false;
0039 if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
0040 return true;
0041 }
0042 virtual bool pack(const tools::histo::h3d& a_h) {
0043 if(!m_wrmpi.spack(a_h.s_cls())) return false;
0044 if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
0045 return true;
0046 }
0047 virtual bool pack(const tools::histo::p1d& a_h) {
0048 if(!m_wrmpi.spack(a_h.s_cls())) return false;
0049 if(!profile_data_duiuidd_pack(m_wrmpi,a_h.get_histo_data())) return false;
0050 return true;
0051 }
0052 virtual bool pack(const tools::histo::p2d& a_h) {
0053 if(!m_wrmpi.spack(a_h.s_cls())) return false;
0054 if(!profile_data_duiuidd_pack(m_wrmpi,a_h.get_histo_data())) return false;
0055 return true;
0056 }
0057 public:
0058 virtual bool beg_send(unsigned int a_nhist) {
0059 m_wrmpi.pack_reset();
0060 return m_wrmpi.pack(a_nhist);
0061 }
0062 virtual bool send(int a_dest) {
0063 if(::MPI_Send(m_wrmpi.buffer(),m_wrmpi.ipos(),MPI_CHAR,a_dest,m_tag,m_comm)!=MPI_SUCCESS) {
0064 m_out << "toolx::mpi::hmpi::send : rank " << m_rank << " : MPI_Send failed." << std::endl;
0065 return false;
0066 }
0067 m_wrmpi.pack_reset();
0068 return true;
0069 }
0070 public:
0071 virtual bool wait_histos(int a_src,std::vector< std::pair<std::string,void*> >& a_hists) {
0072 a_hists.clear();
0073
0074 typedef std::pair<std::string,void*> class_pointer;
0075
0076 MPI_Status status;
0077 if(::MPI_Probe(a_src,m_tag,m_comm,&status)!=MPI_SUCCESS) {
0078 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Probe : failed." << std::endl;
0079 return false;
0080 }
0081
0082 int buffer_size = 0;
0083 if(::MPI_Get_count(&status,MPI_CHAR,&buffer_size)!=MPI_SUCCESS) {
0084 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Get_count : failed." << std::endl;
0085 return false;
0086 }
0087
0088 if(!buffer_size) {
0089 m_out << "exlb::mpi::wait_histos : MPI_Get_count returns zero data." << std::endl;
0090 return false;
0091 }
0092
0093 if(m_verbose) m_out << "rank " << m_rank << " : get_count " << buffer_size << std::endl;
0094
0095 char* buffer = new char[buffer_size];
0096 if(!buffer) {
0097 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : can't alloc buffer of size " << buffer_size << std::endl;
0098 return false;
0099 }
0100
0101 if(::MPI_Recv(buffer,buffer_size,MPI_CHAR,a_src,m_tag,m_comm,&status)!=MPI_SUCCESS) {
0102 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Recv : failed." << std::endl;
0103 delete [] buffer;
0104 return false;
0105 }
0106
0107 if(m_verbose) m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : unpack data ..." << std::endl;
0108
0109 wrmpi _mpi(m_out,m_comm,buffer_size,buffer); //give ownership of buffer to _mpi.
0110
0111 num_t nhist;
0112 if(!_mpi.unpack(nhist)) return false;
0113
0114 if(m_verbose)
0115 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : number of histos to unpack " << nhist << std::endl;
0116
0117 {for(num_t ihist=0;ihist<nhist;ihist++) {
0118
0119 std::string scls;
0120 if(!_mpi.sunpack(scls)) return false;
0121
0122 if(scls==tools::histo::h1d::s_class()) {
0123 tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
0124 if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
0125 tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
0126 h->copy_from_data(hdata);
0127 if(m_verbose) {
0128 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0129 << " : got a " << scls
0130 << ", title " << h->title()
0131 << ", mean_x " << h->mean() << ", rms " << h->rms()
0132 << std::endl;
0133 }
0134 a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
0135
0136 } else if(scls==tools::histo::h2d::s_class()) {
0137 tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
0138 if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
0139 tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
0140 h->copy_from_data(hdata);
0141 if(m_verbose) {
0142 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0143 << " : got a " << scls
0144 << ", title " << h->title()
0145 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0146 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0147 << std::endl;
0148 }
0149 a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
0150
0151 } else if(scls==tools::histo::h3d::s_class()) {
0152 tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
0153 if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
0154 tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
0155 h->copy_from_data(hdata);
0156 if(m_verbose) {
0157 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0158 << " : got a " << scls
0159 << ", title " << h->title()
0160 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0161 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0162 << ", mean_z " << h->mean_z() << ", rms_z " << h->rms_z()
0163 << std::endl;
0164 }
0165 a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
0166
0167 } else if(scls==tools::histo::p1d::s_class()) {
0168 tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata;
0169 if(!profile_data_duiuidd_unpack(_mpi,pdata)) return false;
0170 tools::histo::p1d* h = new tools::histo::p1d("",10,0,1);
0171 h->copy_from_data(pdata);
0172 if(m_verbose) {
0173 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0174 << " : got a " << scls
0175 << ", title " << h->title()
0176 << ", mean_x " << h->mean() << ", rms " << h->rms()
0177 << std::endl;
0178 }
0179 a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
0180
0181 } else if(scls==tools::histo::p2d::s_class()) {
0182 tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata;
0183 if(!profile_data_duiuidd_unpack(_mpi,pdata)) return false;
0184 tools::histo::p2d* h = new tools::histo::p2d("",10,0,1,10,0,1);
0185 h->copy_from_data(pdata);
0186 if(m_verbose) {
0187 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0188 << " : got a " << scls
0189 << ", title " << h->title()
0190 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0191 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0192 << std::endl;
0193 }
0194 a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
0195
0196 } else {
0197 m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
0198 << " : got not treated class " << scls
0199 << std::endl;
0200 }
0201
0202 }} //ihist
0203
0204 return true;
0205 }
0206
0207 public:
0208 virtual int rank() const { return m_rank;}
0209 virtual bool comm_rank(int& a_rank) const {
0210 if(::MPI_Comm_rank(m_comm,&a_rank)!=MPI_SUCCESS) {a_rank=-1;return false;}
0211 return true;
0212 }
0213 virtual bool comm_size(int& a_size) const {
0214 if(::MPI_Comm_size(m_comm,&a_size)!=MPI_SUCCESS) {a_size=0;return false;}
0215 return true;
0216 }
0217 public:
0218 hmpi(std::ostream& a_out,int a_rank,int a_tag,const MPI_Comm& a_comm,bool a_verbose = false)
0219 :m_out(a_out)
0220 ,m_rank(a_rank)
0221 ,m_tag(a_tag)
0222 ,m_comm(a_comm)
0223 ,m_verbose(a_verbose)
0224 ,m_wrmpi(a_out,a_comm)
0225 {
0226 #ifdef TOOLS_MEM
0227 tools::mem::increment(s_class().c_str());
0228 #endif
0229 }
0230 virtual ~hmpi(){
0231 #ifdef TOOLS_MEM
0232 tools::mem::decrement(s_class().c_str());
0233 #endif
0234 }
0235 protected:
0236 hmpi(const hmpi& a_from)
0237 :parent(a_from)
0238 ,m_out(a_from.m_out)
0239 ,m_rank(a_from.m_rank)
0240 ,m_tag(a_from.m_tag)
0241 ,m_comm(a_from.m_comm)
0242 ,m_verbose(a_from.m_verbose)
0243 ,m_wrmpi(a_from.m_out,a_from.m_comm)
0244 {
0245 #ifdef TOOLS_MEM
0246 tools::mem::increment(s_class().c_str());
0247 #endif
0248 }
0249 hmpi& operator=(const hmpi& a_from){
0250 m_rank = a_from.m_rank;
0251 m_tag = a_from.m_tag;
0252 m_verbose = a_from.m_verbose;
0253 return *this;
0254 }
0255 protected:
0256 std::ostream& m_out;
0257 int m_rank;
0258 int m_tag;
0259 const MPI_Comm& m_comm;
0260 bool m_verbose;
0261 wrmpi m_wrmpi;
0262 };
0263
0264 }}
0265
0266 #endif