ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4MPIToolsManager.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4MPIToolsManager.hh
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 
27 // The manager class for MPI applications.
28 
29 // Author: Ivana Hrivnacova, 25/06/2015 (ivana@ipno.in2p3.fr)
30 
31 #ifndef G4MPIToolsManager_h
32 #define G4MPIToolsManager_h 1
33 
35 #include "G4HnInformation.hh"
36 #include "G4ios.hh"
37 
38 #include <tools/impi_world>
39 #include <tools/histo/hmpi>
40 
41 #include <vector>
42 
44 {
45  public:
47  tools::histo::hmpi* hmpi)
48  : fState(state), fHmpi(hmpi) {}
49  virtual ~G4MPIToolsManager() {}
50 
51  public:
52  // methods
53  template <typename T>
54  G4bool Merge(const std::vector<T*>& htVector,
55  const std::vector<G4HnInformation*>& hnVector);
56  private:
57  // methods
58  template <typename T>
59  G4bool Send(G4int nofActiveT,
60  const std::vector<T*>& htVector,
61  const std::vector<G4HnInformation*>& hnVector);
62 
63  template <typename T>
64  G4bool Receive(G4int nofActiveT,
65  const std::vector<T*>& htVector,
66  const std::vector<G4HnInformation*>& hnVector);
67 
68  // data members
70  tools::histo::hmpi* fHmpi;
71 };
72 
73 // inline functions
74 
75 //_____________________________________________________________________________
76 template <typename T>
78  const std::vector<T*>& htVector,
79  const std::vector<G4HnInformation*>& hnVector)
80 {
81  G4bool finalResult = true;
82 
83  // send object to destination rank
84  // G4cout << "Begin send for " << nofActiveT << G4endl;
85  fHmpi->beg_send(nofActiveT);
86 
87  // pack objects
88  for ( G4int i=0; i<G4int(htVector.size()); ++i ) {
89  // skip sending if activation is enabled and HT is inactivated
90  auto info = hnVector[i];
91  if ( ( fState.GetIsActivation() && ( ! info->GetActivation() ) ) ) continue;
92  // pack histogram for sending
93  // G4cout << "Packed " << i << "th T" << G4endl;
94  auto ht = htVector[i];
95  auto result = fHmpi->pack(*ht);
96  finalResult = result && finalResult;
97  }
98 
99  //G4cout << "Go to send all " << G4endl;
100  if ( ! fHmpi->send(fHmpi->rank()) ) {
101  G4ExceptionDescription description;
102  description << " Rank: " << fHmpi->rank() << " : can't send histos.";
103  G4Exception("G4H1ToolsManager::Receieve",
104  "Analysis_W031", JustWarning, description);
105  return false;
106  }
107 
108  return finalResult;
109 }
110 
111 //_____________________________________________________________________________
112 template <typename T>
114  const std::vector<T*>& htVector,
115  const std::vector<G4HnInformation*>& hnVector)
116 {
117  G4int commSize;
118  G4bool result = fHmpi->comm_size(commSize);
119  if ( ! result ) {
120  G4ExceptionDescription description;
121  description
122  << " Failed to get MPI commander size." << G4endl
123  << " Merging will not be performed.";
124  G4Exception("G4H1ToolsManager::Merge",
125  "Analysis_W031", JustWarning, description);
126  return false;
127  }
128 
129  // get objects from source ranks
130  for (G4int srank = 0; srank < commSize; ++srank) {
131 
132  // skip destination rank
133  if ( srank == fHmpi->rank() ) continue;
134 
135  // get objects from this source rank
136  //G4cout << "Go to wait_histos " << rank << G4endl;
137  using class_pointer = std::pair<std::string,void*>;
138  std::vector<class_pointer> hs;
139  if ( ! fHmpi->wait_histos(srank, hs) ) {
140  G4ExceptionDescription description;
141  description << " wait_histos from " << srank << " : failed.";
142  G4Exception("G4H1ToolsManager::Receieve",
143  "Analysis_W031", JustWarning, description);
144  return false;
145  }
146 
147  // check that we got the right number of objects
148  if ( G4int(hs.size()) != nofActiveT ) {
149  G4ExceptionDescription description;
150  description << " srank: " << srank << " : got " << hs.size() << " objects, "
151  << "while " << nofActiveT << " were exepected." << G4endl;
152  G4Exception("G4H1ToolsManager::Receieve",
153  "Analysis_W031", JustWarning, description);
154  return false;
155  }
156 
157  // merge the objects to destination rank
158  G4int counter = 0;
159  for ( G4int i=0; i<G4int(htVector.size()); ++i ) {
160  // skip sending if activation is enabled and HT is inactivated
161  auto info = hnVector[i];
162  if ( ( fState.GetIsActivation() && ( ! info->GetActivation() ) ) ) continue;
163  // merge histograms
164  auto ht = htVector[i];
165  auto newHt = static_cast<T*>(hs[counter++].second);
166  ht->add(*newHt);
167  }
168  }
169  return true;
170 }
171 
172 
173 //_____________________________________________________________________________
174 template <typename T>
175 inline G4bool G4MPIToolsManager::Merge(const std::vector<T*>& htVector,
176  const std::vector<G4HnInformation*>& hnVector)
177 {
178  if ( ! htVector.size() ) return true;
179 
180  // Get number of objects to be sent
181  G4int nofActiveT = 0;
182  if ( fState.GetIsActivation() ) {
183  // only activated histograms will be treated
184  for ( G4int i=0; i<G4int(htVector.size()); ++i ) {
185  auto activation = hnVector[i]->GetActivation();
186  if ( activation ) ++nofActiveT;
187  }
188  } else {
189  nofActiveT = G4int(htVector.size());
190  }
191 
192  if ( ! nofActiveT ) return true;
193 
194  G4int commRank;
195  if ( ! fHmpi->comm_rank(commRank) ) {
196  G4ExceptionDescription description;
197  description
198  << " Failed to get MPI commander rank." << G4endl
199  << " Merging will not be performed.";
200  G4Exception("G4H1ToolsManager::Merge",
201  "Analysis_W031", JustWarning, description);
202  return false;
203  }
204 
205  G4bool finalResult = true;
206 
207  if ( commRank != fHmpi->rank() ) {
208 
209 #ifdef G4VERBOSE
210  if ( fState.GetVerboseL3() ) {
211  G4ExceptionDescription description;
212  description << "on rank " << commRank
213  << " destination rank: " << fHmpi->rank();
214  fState.GetVerboseL4()->Message("mpi send", "Hn|Pn", description);
215  }
216 #endif
217 
218  auto result = Send(nofActiveT, htVector, hnVector);
219 
220  finalResult = result && finalResult;
221 
222 #ifdef G4VERBOSE
223  if ( fState.GetVerboseL1() ) {
224  G4ExceptionDescription description;
225  description << "on rank " << commRank
226  << " destination rank: " << fHmpi->rank();
227  fState.GetVerboseL1()->Message("send", "Hn|Pn", description);
228  }
229 #endif
230 
231  } else {
232 
233 #ifdef G4VERBOSE
234  if ( fState.GetVerboseL3() ) {
235  G4ExceptionDescription description;
236  description << "on rank " << commRank
237  << " destination rank: " << fHmpi->rank();
238  fState.GetVerboseL4()->Message("mpi wait_histos", "Hn|Pn", description);
239  }
240 #endif
241 
242  auto result = Receive(nofActiveT, htVector, hnVector);
243 
244  finalResult = result && finalResult;
245 
246 #ifdef G4VERBOSE
247  if ( fState.GetVerboseL1() ) {
248  G4ExceptionDescription description;
249  description << "on rank " << commRank
250  << " destination rank: " << fHmpi->rank();
251  fState.GetVerboseL1()->Message("mpi wait_histos", "Hn|Pn", description);
252  }
253 #endif
254  }
255  return finalResult;
256 }
257 
258 #endif