Geant4 Cross Reference |
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 29 #include "G4RootMpiNtupleFileManager.hh" 30 31 #include "G4AnalysisUtilities.hh" 32 #include "G4RootMpiNtupleManager.hh" 33 #include "G4RootMpiPNtupleManager.hh" 34 35 #include <tools/impi> 36 37 using namespace G4Analysis; 38 using std::make_shared; 39 40 //_____________________________________________________________________________ 41 G4RootMpiNtupleFileManager::G4RootMpiNtupleFileManager(const G4AnalysisManagerState& state) 42 : G4RootNtupleFileManager(state), 43 fImpi(nullptr), 44 fMpiRank(-1), 45 fMpiSize(0), 46 fMpiSlaveNtupleManager(nullptr), 47 fNtupleBooked(false) 48 {} 49 50 //_____________________________________________________________________________ 51 G4RootMpiNtupleFileManager::~G4RootMpiNtupleFileManager() {} 52 53 // 54 // private methods 55 // 56 57 //_____________________________________________________________________________ 58 void G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode(G4int nofNtupleFiles) 59 { 60 Message(kVL2, "set", "mpi ntuple merging mode"); 61 62 auto canMerge = true; 63 64 // Illegal situations 65 if (fMpiSize < 2) { 66 G4ExceptionDescription description; 67 description << "Merging ntuples is not applicable on a single rank." << G4endl 68 << "Setting was ignored."; 69 G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMergingMode()", "Analysis_W013", 70 JustWarning, description); 71 canMerge = false; 72 } 73 74 G4String mergingMode; 75 if (!canMerge) { 76 fNtupleMergeMode = G4NtupleMergeMode::kNone; 77 mergingMode = "G4NtupleMergeMode::kNone"; 78 } 79 else { 80 // Set the number of reduced ntuple files 81 // (multiple output files are not yet supported) 82 fNofNtupleFiles = nofNtupleFiles; 83 84 // Forced merging mode 85 // MPI 86 if (fMpiRank >= fMpiSize) { 87 // the extra worker 88 fNtupleMergeMode = G4NtupleMergeMode::kMain; 89 mergingMode = "G4NtupleMergeMode::kMain"; 90 } 91 else { 92 // processing worker 93 fNtupleMergeMode = G4NtupleMergeMode::kSlave; 94 mergingMode = "G4NtupleMergeMode::kSlave"; 95 } 96 } 97 98 Message(kVL1, "set", "mpi ntuple merging mode", mergingMode); 99 } 100 101 // 102 // public methods 103 // 104 105 //_____________________________________________________________________________ 106 void G4RootMpiNtupleFileManager::SetMpiNtupleMerging(tools::impi* impi, G4int mpiRank, 107 G4int mpiSize, G4int nofNtupleFiles) 108 { 109 if (fIsInitialized) { 110 G4ExceptionDescription description; 111 description << "Cannot change merging mode." << G4endl 112 << "The function must be called before OpenFile()."; 113 G4Exception("G4RootMpiNtupleFileManager::SetMpiNtupleMerging", "Analysis_W013", JustWarning, 114 description); 115 return; 116 } 117 118 // Save MPI merging parameters 119 fImpi = impi; 120 fMpiRank = mpiRank; 121 fMpiSize = mpiSize; 122 123 // Set ntuple merging mode 124 SetMpiNtupleMergingMode(nofNtupleFiles); 125 } 126 127 //_____________________________________________________________________________ 128 std::shared_ptr<G4VNtupleManager> G4RootMpiNtupleFileManager::CreateNtupleManager() 129 { 130 Message(kVL4, "create", "mpi ntuple manager"); 131 132 std::shared_ptr<G4VNtupleManager> activeNtupleManager = nullptr; 133 switch (fNtupleMergeMode) { 134 case G4NtupleMergeMode::kNone: 135 fNtupleManager = make_shared<G4RootNtupleManager>(fState, fBookingManager, 0, 0, 136 fNtupleRowWise, fNtupleRowMode); 137 fNtupleManager->SetFileManager(fFileManager); 138 activeNtupleManager = fNtupleManager; 139 break; 140 141 case G4NtupleMergeMode::kMain: { 142 fNtupleManager = make_shared<G4RootMpiNtupleManager>(fState, fBookingManager, fNtupleRowWise, 143 fNtupleRowMode, fImpi, fMpiSize); 144 fNtupleManager->SetFileManager(fFileManager); 145 activeNtupleManager = fNtupleManager; 146 break; 147 } 148 149 case G4NtupleMergeMode::kSlave: { 150 auto destinationRank = fMpiSize; 151 fMpiSlaveNtupleManager = 152 make_shared<G4RootMpiPNtupleManager>(fState, fImpi, fMpiRank, destinationRank); 153 activeNtupleManager = fMpiSlaveNtupleManager; 154 break; 155 } 156 } 157 158 G4String mergeMode; 159 switch (fNtupleMergeMode) { 160 case G4NtupleMergeMode::kNone: 161 mergeMode = ""; 162 break; 163 case G4NtupleMergeMode::kMain: 164 mergeMode = "main "; 165 break; 166 case G4NtupleMergeMode::kSlave: 167 mergeMode = "slave "; 168 break; 169 } 170 Message(kVL3, "create", mergeMode + "mpi ntuple manager"); 171 172 fIsInitialized = true; 173 174 return activeNtupleManager; 175 } 176 177 //_____________________________________________________________________________ 178 G4bool G4RootMpiNtupleFileManager::ActionAtOpenFile(const G4String& fileName) 179 { 180 // No MPI merging, call base class 181 if (fNtupleMergeMode == G4NtupleMergeMode::kNone) { 182 return G4RootNtupleFileManager::ActionAtOpenFile(fileName); 183 } 184 185 if (!fNtupleBooked) { 186 G4String objectType = "analysis file"; 187 if (fNtupleMergeMode == G4NtupleMergeMode::kMain) { 188 objectType = "main analysis file"; 189 } 190 Message(kVL4, "open", objectType, fileName); 191 192 if (fNtupleMergeMode == G4NtupleMergeMode::kMain) { 193 // Creating files is triggered from CreateNtuple 194 fNtupleManager->CreateNtuplesFromBooking(fBookingManager->GetNtupleBookingVector()); 195 } 196 197 if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) { 198 // G4cout << "Slave: Go to create ntuples from booking" << G4endl; 199 // No file is open by Slave manager 200 fMpiSlaveNtupleManager->CreateNtuplesFromBooking(fBookingManager->GetNtupleBookingVector()); 201 } 202 203 Message(kVL1, "open", objectType, fileName); 204 205 fNtupleBooked = true; 206 } 207 208 return true; 209 } 210 211 //_____________________________________________________________________________ 212 G4bool G4RootMpiNtupleFileManager::ActionAtWrite() 213 { 214 // No MPI merging, call base class 215 if (fNtupleMergeMode == G4NtupleMergeMode::kNone) { 216 return G4RootNtupleFileManager::ActionAtWrite(); 217 } 218 219 auto result = true; 220 221 G4String ntupleType; 222 if (fNtupleMergeMode == G4NtupleMergeMode::kMain) ntupleType = "main ntuples"; 223 if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) ntupleType = "slave ntuples"; 224 225 Message(kVL4, "merge", ntupleType); 226 227 if (fNtupleMergeMode == G4NtupleMergeMode::kMain) { 228 result &= fNtupleManager->Merge(); 229 } 230 231 if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) { 232 result &= fMpiSlaveNtupleManager->Merge(); 233 } 234 235 Message(kVL1, "merge", ntupleType, "", result); 236 237 return result; 238 } 239 240 //_____________________________________________________________________________ 241 G4bool G4RootMpiNtupleFileManager::ActionAtCloseFile() 242 { 243 // No MPI merging, call base class 244 if (fNtupleMergeMode == G4NtupleMergeMode::kNone) { 245 return G4RootNtupleFileManager::ActionAtCloseFile(); 246 } 247 248 if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) { 249 fMpiSlaveNtupleManager->SetNewCycle(false); 250 return true; 251 } 252 253 return CloseNtupleFiles(); 254 } 255 256 //_____________________________________________________________________________ 257 G4bool G4RootMpiNtupleFileManager::Reset() 258 { 259 // Reset ntuples 260 261 // No MPI merging, call base class 262 if (fNtupleMergeMode == G4NtupleMergeMode::kNone) { 263 return G4RootNtupleFileManager::Reset(); 264 } 265 266 auto result = true; 267 268 if (fNtupleMergeMode == G4NtupleMergeMode::kMain) { 269 result &= fNtupleManager->Reset(); 270 } 271 272 if (fNtupleMergeMode == G4NtupleMergeMode::kSlave) { 273 result &= fMpiSlaveNtupleManager->Reset(); 274 } 275 276 return result; 277 } 278