ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RootMpiNtupleManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4RootMpiNtupleManager.cc
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 // Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
28 
31 #include "G4RootFileManager.hh"
33 #include "G4AnalysisUtilities.hh"
34 
35 #include "tools/wroot/file"
36 #include "tools/wroot/mpi_ntuple_row_wise"
37 #include "tools/wroot/mpi_ntuple_column_wise"
38 
39 using namespace G4Analysis;
40 
41 const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
42  // (should be passed from the application)
43 
44 //_____________________________________________________________________________
46  const G4AnalysisManagerState& state,
47  G4bool rowWise, G4bool rowMode,
48  tools::impi* impi, G4int mpiSize)
49  : G4RootNtupleManager(state, 0, rowWise, rowMode),
50  fImpi(impi),
51  fSlaveRanks(),
52  fMainRank(0)
53 {
54  for ( G4int rank = 0; rank < mpiSize; rank++ ) {
55  fSlaveRanks.push_back(rank);
56  }
57  fMainRank = mpiSize;
58 }
59 
60 //_____________________________________________________________________________
62 {}
63 
64 //
65 // private methods
66 //
67 
68 
69 //_____________________________________________________________________________
71 {
72 // Pack and send the main ntuple data to the slave ranks
73 
74  // G4cout << "Going to send main ntuple data " << G4endl;
75 
76  // Get basket sizes
77  std::vector<tools::wroot::branch*> mainBranches;
78  ntuple->get_branches(mainBranches);
79  std::vector<tools::uint32> basketSizes;
80  tools_vforcit(tools::wroot::branch*, mainBranches, it) {
81  basketSizes.push_back((*it)->basket_size());
82  }
83 
84  auto ntupleFile = fFileManager->GetNtupleFile(id);
85  tools::uint32 basketSize = fFileManager->GetBasketSize();
86  unsigned int basketEntries = fFileManager->GetBasketEntries();
87 
88  for ( auto slaveRank : fSlaveRanks ) {
89  G4cout << "Going to send main ntuple data to slave rank " << slaveRank << G4endl;
90 
91  fImpi->pack_reset();
92  if ( ! fImpi->pack(id)) {
93  G4cerr << "pack(id) failed." << G4endl;
94  return false;
95  }
96 
97  if ( ! fImpi->bpack(fRowWise) ) {
98  G4cerr << "bpack(fRowWise) failed."<< G4endl;
99  return false;
100  }
101 
102  if ( ! fImpi->bpack(ntupleFile->byte_swap())) {
103  G4cerr << "bpack(byte_swap) failed." << G4endl;
104  return false;
105  }
106 
107  if ( ! fImpi->pack(ntupleFile->compression()) ) {
108  G4cerr << "pack(compression) failed." << G4endl;
109  return false;
110  }
111 
112  if ( ! fImpi->pack(ntupleFile->dir().seek_directory())) {
113  // Should be used fNtupleDirectory ??
114  G4cerr << "pack(seek) failed." << G4endl;
115  return false;
116  }
117 
118  if ( fRowWise ) {
119  if ( ! fImpi->pack(basketSize) ) {
120  G4cerr << "pack(basketSize) failed." << G4endl;
121  return false;
122  }
123  } else {
124  if ( ! fImpi->bpack(fRowMode) ) {
125  G4cerr << "bpack(fRowMode) failed." << G4endl;
126  return false;
127  }
128  if ( ! fImpi->vpack(basketSizes) ) {
129  G4cerr << "vpack(basketSizes) failed." << G4endl;
130  return false;
131  }
132  if ( ! fImpi->pack(basketEntries) ) {
133  G4cerr << "pack(basketEntries) failed." << G4endl;
134  return false;
135  }
136  }
137 
138  if ( ! fImpi->send_buffer(slaveRank, kTAG_NTUPLE )) {
139  G4cerr << "send_buffer() failed." << G4endl;
140  return false;
141  }
142  fImpi->pack_reset();
143 
144  G4cout << "Sent ntuple description to slave on rank " << slaveRank << G4endl;
145  }
146 
147  // G4cout << "Done: send main ntuple data " << G4endl;
148  return true;
149 }
150 
151 //_____________________________________________________________________________
153 {
154  // G4cout << "G4RootMpiNtupleManager::InitializeRanks" << G4endl;
155 
156  auto finalResult = true;
157 
158  auto counter = 0;
159  for ( auto ntupleDescription : fNtupleDescriptionVector ) {
160 
161  // Do not create ntuple if it is inactivated
162  if ( fState.GetIsActivation() && ( ! ntupleDescription->fActivation ) ) continue;
163 
164  auto result = Send(counter++, ntupleDescription->fNtuple);
165  finalResult = finalResult && result;
166  }
167 
168  return finalResult;
169 }
170 
171 //_____________________________________________________________________________
173 {
174 // Receive the pntuple data from the slave ranks
175 // For the time being only one ntuple
176 
177  // G4cout << "G4RootMpiNtupleManager::WaitBuffer" << G4endl;
178 
179  unsigned long numberOfEndFill = 0;
180 
181  G4bool verbose = ( fState.GetVerboseL2() );
182 
183  while ( true ) {
184  fImpi->pack_reset();
185 
186  // loop until receiving end_fill from all ranks
187  // G4cout << "G4RootMpiNtupleManager::WaitBuffer entering loop" << G4endl;
188  int probe_src;
189  if ( ! fImpi->wait_buffer(fMainRank, kTAG_NTUPLE, probe_src, verbose)) {
190  G4cerr << "!!! wait_buffer() failed." << std::endl;
191  return EXIT_FAILURE;
192  }
193 
194  tools::uint32 protocol;
195  if ( ! fImpi->unpack(protocol)) {
196  G4cerr << "unpack(protocol) failed."<< G4endl;
197  return false;
198  }
199 
200  if ( protocol == tools::wroot::mpi_protocol_basket() ) {
201 
202  // G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_basket" << G4endl;
203 
204  // get ntuple Id
205  tools::uint32 ntupleId;
206  if ( ! fImpi->unpack(ntupleId) ) {
207  G4cerr << "unpack(ntuple_id) failed."<< std::endl;
208  return false;
209  }
210 
211  if ( ntupleId >= fNtupleVector.size() ) {
212  std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
213  return false;
214  }
215 
216  // Main ntuple
217  auto mainNtuple = fNtupleVector[ntupleId];
218 
219  // add basket to main ntuple
220  if ( ! mainNtuple->mpi_add_basket(*fImpi)) {
221  std::cerr << "mainNtuple->mpi_add_basket() failed." << std::endl;
222  return EXIT_FAILURE;
223  }
224  }
225  else if ( protocol == tools::wroot::mpi_protocol_baskets() ) {
226  //column_wise and row_mode only.
227 
228  // G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_baskets" << G4endl;
229 
230  // get ntuple Id
231  tools::uint32 ntupleId;
232  if ( ! fImpi->unpack(ntupleId) ) {
233  G4cerr << "unpack(ntuple_id) failed."<< std::endl;
234  return false;
235  }
236 
237  if ( ntupleId >= fNtupleVector.size() ) {
238  std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
239  return false;
240  }
241 
242  // Main ntuple
243  auto mainNtuple = fNtupleVector[ntupleId];
244 
245  // add basket to main ntuple
246  if ( ! mainNtuple->mpi_add_baskets(*fImpi)) {
247  std::cerr << "mainNtuple->mpi_add_baskets() failed." << std::endl;
248  return EXIT_FAILURE;
249  }
250  }
251  else if ( protocol==tools::wroot::mpi_protocol_end_fill() ) {
252 
253  // G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_end_fill" << G4endl;
254 
255  // get ntuple Id
256  tools::uint32 ntupleId;
257  if ( ! fImpi->unpack(ntupleId) ) {
258  G4cerr << "unpack(ntuple_id) failed."<< std::endl;
259  return false;
260  }
261 
262  if ( ntupleId >= fNtupleVector.size() ) {
263  std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
264  return false;
265  }
266 
267  // Main ntuple
268  auto mainNtuple = fNtupleVector[ntupleId];
269 
270  // end_fill in main ntuple
271  if ( ! mainNtuple->mpi_end_fill(*fImpi) ) {
272  G4cerr << "main_ntuple->mpi_end_fill() failed." << std::endl;
273  return false;
274  }
275 
276  numberOfEndFill++;
277 
278  if ( numberOfEndFill == fSlaveRanks.size() ) break;
279  }
280  else {
281  G4cerr << "unknown protocol " << protocol << G4endl;
282  return false;
283  }
284  }
285 
286  return true;
287 }
288 
289 
290 //
291 // public methods
292 //
293 
294 //_____________________________________________________________________________
296 {
297  // Base class actions
298  // G4cout << "Going to call CreateNtuplesFromBooking from base class" << G4endl;
300 
301  // Initialize ranks
302  if ( ! InitializeRanks() ) {
303  G4cerr << "InitializeRanks failed." << G4endl;
304  }
305 
306  // Go to wait buffer mode
307  if ( ! WaitBuffer() ) {
308  G4cerr << "WaitBuffer failed." << G4endl;
309  }
310 }
311 
312 //_____________________________________________________________________________
314 {
315  G4cout << "G4RootMpiNtupleManager::Merge()" << G4endl;
316 
317  auto finalResult = true;
318 
319  for ( auto ntupleDescription : fNtupleDescriptionVector ) {
320 
321  // Do not create ntuple if it is inactivated
322  if ( fState.GetIsActivation() && ( ! ntupleDescription->fActivation ) ) continue;
323 
324  // G4cout << "Go to call merge_number_of_entries" << G4endl;
325  ntupleDescription->fNtuple->merge_number_of_entries();
326  }
327 
328  return finalResult;
329 }