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 // The manager class for MPI applications. 28 29 // Author: Ivana Hrivnacova, 25/06/2015 (ivana@ipno.in2p3.fr) 30 31 using std::to_string; 32 33 //_____________________________________________________________________________ 34 template <typename HT> 35 inline 36 G4bool G4MPIToolsManager::Send( 37 G4int nofActiveT, const std::vector<std::pair<HT*, G4HnInformation*>>& hnVector) 38 { 39 auto result = true; 40 41 // send object to destination rank 42 // G4cout << "Begin send for " << nofActiveT << G4endl; 43 fHmpi->beg_send(nofActiveT); 44 45 // pack objects 46 for (const auto& [ht, info] : hnVector) { 47 // skip sending if activation is enabled and HT is inactivated 48 // or if histogram was deleted 49 if ( ( fState.GetIsActivation() && ( ! info->GetActivation() ) ) || 50 ( info->GetDeleted() ) ) continue; 51 // pack histogram for sending 52 // G4cout << "Packed " << i << "th T" << G4endl; 53 result &= fHmpi->pack(*ht); 54 } 55 56 //G4cout << "Go to send all " << G4endl; 57 if ( ! fHmpi->send(fHmpi->rank()) ) { 58 G4Analysis::Warn( 59 "Rank: " + to_string(fHmpi->rank()) + " : can't send histos.", 60 fkClass, "Send"); 61 return false; 62 } 63 64 return result; 65 } 66 67 //_____________________________________________________________________________ 68 template <typename HT> 69 inline 70 G4bool G4MPIToolsManager::Receive( 71 G4int nofActiveT, const std::vector<std::pair<HT*, G4HnInformation*>>& hnVector) 72 { 73 G4int commSize; 74 G4bool result = fHmpi->comm_size(commSize); 75 if ( ! result ) { 76 G4Analysis::Warn( 77 "Failed to get MPI commander size.\nMerging will not be performed.", 78 fkClass, "Receive"); 79 return false; 80 } 81 82 // get objects from source ranks 83 for (G4int srank = 0; srank < commSize; ++srank) { 84 85 // skip destination rank 86 if ( srank == fHmpi->rank() ) continue; 87 88 // get objects from this source rank 89 // G4cout << "Go to wait_histos " << srank << G4endl; 90 using class_pointer = std::pair<std::string,void*>; 91 std::vector<class_pointer> hs; 92 if ( ! fHmpi->wait_histos(srank, hs) ) { 93 G4Analysis::Warn( 94 "Wait_histos from " + to_string(srank) + " : failed.", 95 fkClass, "Receive"); 96 return false; 97 } 98 99 // check that we got the right number of objects 100 if ( G4int(hs.size()) != nofActiveT ) { 101 G4Analysis::Warn( 102 "srank: " + to_string(srank) + " : got " + to_string(hs.size()) + 103 " objects, while " + to_string(nofActiveT) +" were expected.", 104 fkClass, "Receive"); 105 return false; 106 } 107 108 // merge the objects to destination rank 109 G4int counter = 0; 110 for (const auto& [ht, info] : hnVector) { 111 // skip sending if activation is enabled and HT is inactivated 112 if ( ( fState.GetIsActivation() && ( ! info->GetActivation() ) ) ) continue; 113 // merge histograms 114 auto newHt = static_cast<HT*>(hs[counter++].second); 115 ht->add(*newHt); 116 } 117 } 118 return true; 119 } 120 121 122 //_____________________________________________________________________________ 123 template <typename HT> 124 inline 125 G4bool G4MPIToolsManager::Merge( 126 const std::vector<std::pair<HT*, G4HnInformation*>>& hnVector) 127 { 128 if ( hnVector.empty() ) return true; 129 130 // Get number of objects to be sent 131 G4int nofActiveT = 0; 132 if ( fState.GetIsActivation() ) { 133 // only activated histograms will be treated 134 for (const auto& htn : hnVector) { 135 auto activation = htn.second->GetActivation(); 136 if ( activation ) ++nofActiveT; 137 } 138 } else { 139 nofActiveT = G4int(hnVector.size()); 140 } 141 142 if ( ! nofActiveT ) return true; 143 144 G4int commRank; 145 if ( ! fHmpi->comm_rank(commRank) ) { 146 G4Analysis::Warn( 147 "Failed to get MPI commander rank.\nMerging will not be performed.", 148 fkClass, "Merge"); 149 return false; 150 } 151 152 auto result = true; 153 154 if ( commRank != fHmpi->rank() ) { 155 fState.Message(G4Analysis::kVL3, "mpi send", "Hn|Pn", 156 "on rank " + to_string(commRank) + 157 " destination rank: " + to_string(fHmpi->rank())); 158 159 result &= Send(nofActiveT, hnVector); 160 161 fState.Message(G4Analysis::kVL1, "mpi send", "Hn|Pn", 162 "on rank " + to_string(commRank) + 163 " destination rank: " + to_string(fHmpi->rank())); 164 165 } else { 166 fState.Message(G4Analysis::kVL3, "mpi wait_histos", "Hn|Pn", 167 "on rank " + to_string(commRank) + 168 " destination rank: " + to_string(fHmpi->rank())); 169 170 result &= Receive(nofActiveT, hnVector); 171 172 fState.Message(G4Analysis::kVL1, "mpi wait_histos", "Hn|Pn", 173 "on rank " + to_string(commRank) + 174 " destination rank: " + to_string(fHmpi->rank())); 175 } 176 return result; 177 } 178