Geant4 Cross Reference

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

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_hmpi
  5 #define toolx_mpi_hmpi
  6 
  7 // code to send, receive histos through MPI.
  8 
  9 #include <tools/histo/hmpi>
 10 #include <tools/histo/hd2mpi>
 11 
 12 #include <tools/histo/h1d>
 13 #include <tools/histo/h2d>
 14 #include <tools/histo/h3d>
 15 #include <tools/histo/p1d>
 16 #include <tools/histo/p2d>
 17 
 18 #include "wrmpi"
 19 
 20 namespace toolx {
 21 namespace mpi {
 22 
 23 class hmpi : public virtual tools::histo::hmpi {
 24   typedef tools::histo::hmpi parent;
 25 protected:
 26   typedef unsigned int num_t;
 27   static const std::string& s_class() {
 28     static const std::string s_v("toolx::mpi::hmpi");
 29     return s_v;
 30   }
 31 public:
 32   virtual bool pack(const tools::histo::h1d& a_h) {
 33     if(!m_wrmpi.spack(a_h.s_cls())) return false;
 34     if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
 35     return true;
 36   }
 37   virtual bool pack(const tools::histo::h2d& a_h) {
 38     if(!m_wrmpi.spack(a_h.s_cls())) return false;
 39     if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
 40     return true;
 41   }
 42   virtual bool pack(const tools::histo::h3d& a_h) {
 43     if(!m_wrmpi.spack(a_h.s_cls())) return false;
 44     if(!histo_data_duiuid_pack(m_wrmpi,a_h.dac())) return false;
 45     return true;
 46   }
 47   virtual bool pack(const tools::histo::p1d& a_h) {
 48     if(!m_wrmpi.spack(a_h.s_cls())) return false;
 49     if(!profile_data_duiuidd_pack(m_wrmpi,a_h.get_histo_data())) return false;
 50     return true;
 51   }
 52   virtual bool pack(const tools::histo::p2d& a_h) {
 53     if(!m_wrmpi.spack(a_h.s_cls())) return false;
 54     if(!profile_data_duiuidd_pack(m_wrmpi,a_h.get_histo_data())) return false;
 55     return true;
 56   }
 57 public:
 58   virtual bool beg_send(unsigned int a_nhist) {
 59     m_wrmpi.pack_reset();
 60     return m_wrmpi.pack(a_nhist);
 61   }
 62   virtual bool send(int a_dest) {
 63     if(::MPI_Send(m_wrmpi.buffer(),m_wrmpi.ipos(),MPI_CHAR,a_dest,m_tag,m_comm)!=MPI_SUCCESS) {
 64       m_out << "toolx::mpi::hmpi::send : rank " << m_rank << " : MPI_Send failed." << std::endl;
 65       return false;
 66     }
 67     m_wrmpi.pack_reset();
 68     return true;
 69   }
 70 public:
 71   virtual bool wait_histos(int a_src,std::vector< std::pair<std::string,void*> >& a_hists) {
 72     a_hists.clear();
 73 
 74     typedef std::pair<std::string,void*> class_pointer;
 75 
 76     MPI_Status status;
 77     if(::MPI_Probe(a_src,m_tag,m_comm,&status)!=MPI_SUCCESS) {
 78       m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Probe : failed." << std::endl;
 79       return false;
 80     }
 81 
 82     int buffer_size = 0;
 83     if(::MPI_Get_count(&status,MPI_CHAR,&buffer_size)!=MPI_SUCCESS) {
 84       m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Get_count : failed." << std::endl;
 85       return false;
 86     }
 87 
 88     if(!buffer_size) {
 89       m_out << "exlb::mpi::wait_histos : MPI_Get_count returns zero data." << std::endl;
 90       return false;
 91     }
 92 
 93     if(m_verbose) m_out << "rank " << m_rank << " : get_count " << buffer_size << std::endl;
 94 
 95     char* buffer = new char[buffer_size];
 96     if(!buffer) {
 97       m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : can't alloc buffer of size " << buffer_size << std::endl;
 98       return false;
 99     }
100 
101     if(::MPI_Recv(buffer,buffer_size,MPI_CHAR,a_src,m_tag,m_comm,&status)!=MPI_SUCCESS) {
102       m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : MPI_Recv : failed." << std::endl;
103       delete [] buffer;
104       return false;
105     }
106 
107     if(m_verbose) m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : unpack data ..." << std::endl;
108 
109     wrmpi _mpi(m_out,m_comm,buffer_size,buffer); //give ownership of buffer to _mpi.
110 
111     num_t nhist;
112     if(!_mpi.unpack(nhist)) return false;
113 
114     if(m_verbose)
115       m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank << " : number of histos to unpack " << nhist << std::endl;
116 
117    {for(num_t ihist=0;ihist<nhist;ihist++) {
118 
119       std::string scls;
120       if(!_mpi.sunpack(scls)) return false;
121 
122       if(scls==tools::histo::h1d::s_class()) {
123         tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
124         if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
125         tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
126         h->copy_from_data(hdata);
127         if(m_verbose) {
128           m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
129                 << " : got a " << scls
130                 << ", title " << h->title()
131                 << ", mean_x " << h->mean() << ", rms " << h->rms()
132                 << std::endl;
133         }
134         a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
135 
136       } else if(scls==tools::histo::h2d::s_class()) {
137         tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
138         if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
139         tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
140         h->copy_from_data(hdata);
141         if(m_verbose) {
142           m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
143                 << " : got a " << scls
144                 << ", title " << h->title()
145                 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
146                 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
147                 << std::endl;
148         }
149         a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
150 
151       } else if(scls==tools::histo::h3d::s_class()) {
152         tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata;
153         if(!histo_data_duiuid_unpack(_mpi,hdata)) return false;
154         tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
155         h->copy_from_data(hdata);
156         if(m_verbose) {
157           m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
158                 << " : got a " << scls
159                 << ", title " << h->title()
160                 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
161                 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
162                 << ", mean_z " << h->mean_z() << ", rms_z " << h->rms_z()
163                 << std::endl;
164         }
165         a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
166 
167       } else if(scls==tools::histo::p1d::s_class()) {
168         tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata;
169         if(!profile_data_duiuidd_unpack(_mpi,pdata)) return false;
170         tools::histo::p1d* h = new tools::histo::p1d("",10,0,1);
171         h->copy_from_data(pdata);
172         if(m_verbose) {
173           m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
174                 << " : got a " << scls
175                 << ", title " << h->title()
176                 << ", mean_x " << h->mean() << ", rms " << h->rms()
177                 << std::endl;
178         }
179         a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
180 
181       } else if(scls==tools::histo::p2d::s_class()) {
182         tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata;
183         if(!profile_data_duiuidd_unpack(_mpi,pdata)) return false;
184         tools::histo::p2d* h = new tools::histo::p2d("",10,0,1,10,0,1);
185         h->copy_from_data(pdata);
186         if(m_verbose) {
187           m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
188                 << " : got a " << scls
189                 << ", title " << h->title()
190                 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
191                 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
192                 << std::endl;
193         }
194         a_hists.push_back(class_pointer(h->s_cls(),h)); //give ownership of h.
195 
196       } else {
197         m_out << "toolx::mpi::hmpi::wait_histos : rank " << m_rank
198               << " : got not treated class " << scls
199               << std::endl;
200       }
201 
202     }} //ihist
203 
204     return true;
205   }
206 
207 public:
208   virtual int rank() const { return m_rank;}
209   virtual bool comm_rank(int& a_rank) const {
210     if(::MPI_Comm_rank(m_comm,&a_rank)!=MPI_SUCCESS) {a_rank=-1;return false;}
211     return true;
212   }
213   virtual bool comm_size(int& a_size) const {
214     if(::MPI_Comm_size(m_comm,&a_size)!=MPI_SUCCESS) {a_size=0;return false;}
215     return true;
216   }
217 public:
218   hmpi(std::ostream& a_out,int a_rank,int a_tag,const MPI_Comm& a_comm,bool a_verbose = false)
219   :m_out(a_out)
220   ,m_rank(a_rank)
221   ,m_tag(a_tag)
222   ,m_comm(a_comm)
223   ,m_verbose(a_verbose)
224   ,m_wrmpi(a_out,a_comm)
225   {
226 #ifdef TOOLS_MEM
227     tools::mem::increment(s_class().c_str());
228 #endif
229   }
230   virtual ~hmpi(){
231 #ifdef TOOLS_MEM
232     tools::mem::decrement(s_class().c_str());
233 #endif
234   }
235 protected:
236   hmpi(const hmpi& a_from)
237   :parent(a_from)
238   ,m_out(a_from.m_out)
239   ,m_rank(a_from.m_rank)
240   ,m_tag(a_from.m_tag)
241   ,m_comm(a_from.m_comm)
242   ,m_verbose(a_from.m_verbose)
243   ,m_wrmpi(a_from.m_out,a_from.m_comm)
244   {
245 #ifdef TOOLS_MEM
246     tools::mem::increment(s_class().c_str());
247 #endif
248   }
249   hmpi& operator=(const hmpi& a_from){
250     m_rank = a_from.m_rank;
251     m_tag = a_from.m_tag;
252     m_verbose = a_from.m_verbose;
253     return *this;
254   }
255 protected:
256   std::ostream& m_out;
257   int m_rank;
258   int m_tag;
259   const MPI_Comm& m_comm;
260   bool m_verbose;
261   wrmpi m_wrmpi;
262 };
263 
264 }}
265 
266 #endif