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

Applications | User Support | Publications | Collaboration