Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4MTRunManagerKernel implementation << 27 // << 28 // Author: M.Asai - July 2013 << 29 // ------------------------------------------- << 30 #include "G4MTRunManagerKernel.hh" << 31 26 32 #include "G4AutoLock.hh" << 27 #include "G4MTRunManagerKernel.hh" 33 #include "G4DecayTable.hh" << 34 #include "G4LogicalVolume.hh" << 35 #include "G4Material.hh" << 36 #include "G4MaterialTable.hh" << 37 #include "G4PVParameterised.hh" << 38 #include "G4PVReplica.hh" << 39 #include "G4ParticleDefinition.hh" << 40 #include "G4ParticleTable.hh" << 41 #include "G4ParticleTableIterator.hh" << 42 #include "G4PhysicalVolumeStore.hh" << 43 #include "G4PhysicsVector.hh" << 44 #include "G4PolyconeSide.hh" << 45 #include "G4PolyhedraSide.hh" << 46 #include "G4Region.hh" << 47 #include "G4RegionStore.hh" 28 #include "G4RegionStore.hh" 48 #include "G4StateManager.hh" 29 #include "G4StateManager.hh" 49 #include "G4UImanager.hh" << 30 #include "G4AutoLock.hh" 50 #include "G4UserWorkerInitialization.hh" << 51 #include "G4UserWorkerThreadInitialization.hh" << 52 #include "G4VDecayChannel.hh" << 53 #include "G4VModularPhysicsList.hh" << 54 #include "G4VPhysicalVolume.hh" << 55 #include "G4VPhysicsConstructor.hh" << 56 #include "G4VUserActionInitialization.hh" << 57 #include "G4VUserPhysicsList.hh" << 58 #include "G4WorkerRunManager.hh" << 59 #include "G4WorkerThread.hh" << 60 << 61 std::vector<G4WorkerRunManager*>* G4MTRunManag << 62 31 63 G4ThreadLocal G4WorkerThread* G4MTRunManagerKe << 32 std::vector<G4WorkerRunManager*>* G4MTRunManagerKernel::workerRMvector = 0; 64 33 65 // ------------------------------------------- << 34 namespace { 66 namespace << 35 G4Mutex workerRMMutex = G4MUTEX_INITIALIZER; 67 { << 68 G4Mutex workerRMMutex = G4MUTEX_INITIALIZER; << 69 } 36 } 70 37 71 // ------------------------------------------- << 72 G4MTRunManagerKernel::G4MTRunManagerKernel() : 38 G4MTRunManagerKernel::G4MTRunManagerKernel() : G4RunManagerKernel(masterRMK) 73 { 39 { 74 // This version of the constructor should ne << 40 //This version of the constructor should never be called in sequential mode! 75 #ifndef G4MULTITHREADED 41 #ifndef G4MULTITHREADED 76 G4ExceptionDescription msg; << 42 G4ExceptionDescription msg; 77 msg << "Geant4 code is compiled without mult << 43 msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off)."; 78 "(-DG4MULTITHREADED " << 44 msg<<" This type of RunManager can only be used in mult-threaded applications."; 79 "is set to off)."; << 45 G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0109",FatalException,msg); 80 msg << " This type of RunManager can only be << 81 "applications."; << 82 G4Exception("G4RunManagerKernel::G4RunManage << 83 #endif 46 #endif 84 G4AutoLock l(&workerRMMutex); << 47 G4AutoLock l(&workerRMMutex); 85 if (workerRMvector == nullptr) workerRMvecto << 48 if(!workerRMvector) workerRMvector = new std::vector<G4WorkerRunManager*>; 86 l.unlock(); << 49 l.unlock(); 87 // Set flag that a MT-type kernel has been i << 50 //Set flag that a MT-type kernel has been instantiated 88 G4Threading::SetMultithreadedApplication(tru << 51 G4Threading::SetMultithreadedApplication(true); 89 } 52 } 90 53 91 // ------------------------------------------- << 92 G4MTRunManagerKernel::~G4MTRunManagerKernel() 54 G4MTRunManagerKernel::~G4MTRunManagerKernel() 93 { 55 { 94 G4AutoLock l(&workerRMMutex); 56 G4AutoLock l(&workerRMMutex); 95 if (workerRMvector != nullptr) { << 57 if(workerRMvector) 96 if (!workerRMvector->empty()) { << 58 { 97 G4ExceptionDescription msg; << 59 if(workerRMvector->size()>0) 98 msg << "G4MTRunManagerKernel is to be de << 60 { 99 << " G4WorkerRunManager are still al << 61 G4ExceptionDescription msg; 100 G4Exception("G4RunManagerKernel::~G4RunM << 62 msg<<"G4MTRunManagerKernel is to be deleted while " 101 } << 63 <<workerRMvector->size()<<" G4WorkerRunManager are still alive."; 102 delete workerRMvector; << 64 G4Exception("G4RunManagerKernel::~G4RunManagerKernel()", 103 workerRMvector = nullptr; << 65 "Run10035",FatalException,msg); 104 } << 66 } >> 67 delete workerRMvector; >> 68 workerRMvector = 0; >> 69 } 105 } 70 } 106 71 107 // ------------------------------------------- << 108 void G4MTRunManagerKernel::SetupShadowProcess( 72 void G4MTRunManagerKernel::SetupShadowProcess() const 109 { 73 { 110 // Behavior is the same as base class (seque << 74 //Behavior is the same as base class (sequential mode) 111 // ShadowProcess pointer == process poitner << 75 //ShadowProcess pointer == process poitner 112 G4RunManagerKernel::SetupShadowProcess(); << 76 G4RunManagerKernel::SetupShadowProcess(); 113 } 77 } 114 78 115 // ------------------------------------------- << 79 #include "G4WorkerRunManager.hh" 116 G4WorkerThread* G4MTRunManagerKernel::GetWorke << 80 #include "G4UserWorkerInitialization.hh" 117 { << 81 #include "G4UserWorkerThreadInitialization.hh" 118 return wThreadContext; << 82 #include "G4VUserActionInitialization.hh" 119 } << 83 #include "G4WorkerThread.hh" >> 84 #include "G4UImanager.hh" >> 85 #include "G4LogicalVolume.hh" >> 86 #include "G4VPhysicalVolume.hh" >> 87 #include "G4PVReplica.hh" >> 88 #include "G4Region.hh" >> 89 #include "G4Material.hh" >> 90 #include "G4PhysicsVector.hh" >> 91 #include "G4VDecayChannel.hh" >> 92 #include "G4PhysicalVolumeStore.hh" >> 93 #include "G4MaterialTable.hh" >> 94 #include "G4PolyconeSide.hh" >> 95 #include "G4PolyhedraSide.hh" >> 96 #include "G4PVParameterised.hh" >> 97 #include "G4VUserPhysicsList.hh" >> 98 #include "G4VPhysicsConstructor.hh" >> 99 #include "G4VModularPhysicsList.hh" >> 100 >> 101 G4ThreadLocal G4WorkerThread* G4MTRunManagerKernel::wThreadContext = 0; >> 102 G4WorkerThread* G4MTRunManagerKernel::GetWorkerThread() >> 103 { return wThreadContext; } 120 104 121 // ------------------------------------------- << 105 void* G4MTRunManagerKernel::StartThread(void* context) 122 void G4MTRunManagerKernel::StartThread(G4Worke << 123 { 106 { 124 //!!!!!!!!!!!!!!!!!!!!!!!!!! 107 //!!!!!!!!!!!!!!!!!!!!!!!!!! 125 //!!!!!! IMPORTANT !!!!!!!!! 108 //!!!!!! IMPORTANT !!!!!!!!! 126 //!!!!!!!!!!!!!!!!!!!!!!!!!! 109 //!!!!!!!!!!!!!!!!!!!!!!!!!! 127 // Here is not sequential anymore and G4User 110 // Here is not sequential anymore and G4UserWorkerThreadInitialization is 128 // a shared user initialization class. << 111 // a shared user initialization class 129 // This means this method cannot use data me << 112 // This means this method cannot use data memebers of G4RunManagerKernel 130 // unless they are invariant ("read-only") a 113 // unless they are invariant ("read-only") and can be safely shared. 131 // All the rest that is not invariant should << 114 // All the rest that is not invariant should be incapsualted into 132 // the context (or, as for wThreadContext be << 115 // the context (or, as for wThreadContext be G4ThreadLocal) 133 //!!!!!!!!!!!!!!!!!!!!!!!!!! 116 //!!!!!!!!!!!!!!!!!!!!!!!!!! 134 // #ifdef G4MULTITHREADED << 117 //#ifdef G4MULTITHREADED 135 // turnontpmalloc(); << 118 // turnontpmalloc(); 136 // #endif << 119 //#endif 137 G4Threading::WorkerThreadJoinsPool(); 120 G4Threading::WorkerThreadJoinsPool(); 138 wThreadContext = context; << 121 wThreadContext = static_cast<G4WorkerThread*>(context); 139 G4MTRunManager* masterRM = G4MTRunManager::G 122 G4MTRunManager* masterRM = G4MTRunManager::GetMasterRunManager(); 140 123 >> 124 141 //============================ 125 //============================ 142 // Step-0: Thread ID << 126 //Step-0: Thread ID 143 //============================ 127 //============================ 144 // Initialise per-thread stream-output << 128 //Initliazie per-thread stream-output 145 // The following line is needed before we ac << 129 //The following line is needed before we actually do IO initialization 146 // because the constructor of UI manager res << 130 //becasue the constructor of UI manager resets the IO destination. 147 G4int thisID = wThreadContext->GetThreadId() 131 G4int thisID = wThreadContext->GetThreadId(); 148 G4Threading::G4SetThreadId(thisID); 132 G4Threading::G4SetThreadId(thisID); 149 G4UImanager::GetUIpointer()->SetUpForAThread 133 G4UImanager::GetUIpointer()->SetUpForAThread(thisID); 150 134 151 //============================ 135 //============================ 152 // Optimization: optional << 136 //Optimization: optional 153 //============================ 137 //============================ 154 // Enforce thread affinity if requested << 138 //Enforce thread affinity if requested 155 wThreadContext->SetPinAffinity(masterRM->Get 139 wThreadContext->SetPinAffinity(masterRM->GetPinAffinity()); 156 140 157 //============================ 141 //============================ 158 // Step-1: Random number engine << 142 //Step-1: Random number engine 159 //============================ 143 //============================ 160 // RNG Engine needs to be initialised by "cl << 144 //RNG Engine needs to be initialized by "cloning" the master one. 161 const CLHEP::HepRandomEngine* masterEngine = 145 const CLHEP::HepRandomEngine* masterEngine = masterRM->getMasterRandomEngine(); 162 masterRM->GetUserWorkerThreadInitialization( 146 masterRM->GetUserWorkerThreadInitialization()->SetupRNGEngine(masterEngine); 163 147 164 //============================ 148 //============================ 165 // Step-2: Initialise worker thread << 149 //Step-2: Initialize worker thread 166 //============================ 150 //============================ 167 if (masterRM->GetUserWorkerInitialization() << 151 if(masterRM->GetUserWorkerInitialization()) 168 masterRM->GetUserWorkerInitialization()->W << 152 { masterRM->GetUserWorkerInitialization()->WorkerInitialize(); } 169 } << 153 if(masterRM->GetUserActionInitialization()) 170 if (masterRM->GetUserActionInitialization() << 154 { 171 G4VSteppingVerbose* sv = masterRM->GetUser << 155 G4VSteppingVerbose* sv = masterRM->GetUserActionInitialization()->InitializeSteppingVerbose(); 172 if (sv != nullptr) { << 156 if ( sv ) { G4VSteppingVerbose::SetInstance(sv); } 173 G4VSteppingVerbose::SetInstance(sv); << 157 } 174 } << 158 //Now initialize worker part of shared objects (geometry/physics) 175 } << 159 wThreadContext->BuildGeometryAndPhysicsVector(); 176 // Now initialise worker part of shared obje << 160 G4WorkerRunManager* wrm 177 G4WorkerThread::BuildGeometryAndPhysicsVecto << 161 = masterRM->GetUserWorkerThreadInitialization()->CreateWorkerRunManager(); 178 G4WorkerRunManager* wrm = masterRM->GetUserW << 179 wrm->SetWorkerThread(wThreadContext); 162 wrm->SetWorkerThread(wThreadContext); 180 G4AutoLock wrmm(&workerRMMutex); 163 G4AutoLock wrmm(&workerRMMutex); 181 workerRMvector->push_back(wrm); 164 workerRMvector->push_back(wrm); 182 wrmm.unlock(); 165 wrmm.unlock(); 183 166 184 //================================ 167 //================================ 185 // Step-3: Setup worker run manager << 168 //Step-3: Setup worker run manager 186 //================================ 169 //================================ 187 // Set the detector and physics list to the 170 // Set the detector and physics list to the worker thread. Share with master 188 const G4VUserDetectorConstruction* detector 171 const G4VUserDetectorConstruction* detector = masterRM->GetUserDetectorConstruction(); 189 wrm->G4RunManager::SetUserInitialization(con 172 wrm->G4RunManager::SetUserInitialization(const_cast<G4VUserDetectorConstruction*>(detector)); 190 const G4VUserPhysicsList* physicslist = mast 173 const G4VUserPhysicsList* physicslist = masterRM->GetUserPhysicsList(); 191 wrm->SetUserInitialization(const_cast<G4VUse 174 wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist)); 192 175 193 //================================ 176 //================================ 194 // Step-4: Initialise worker run manager << 177 //Step-4: Initialize worker run manager 195 //================================ 178 //================================ 196 if (masterRM->GetUserActionInitialization() << 179 if(masterRM->GetUserActionInitialization()) 197 masterRM->GetNonConstUserActionInitializat << 180 { masterRM->GetNonConstUserActionInitialization()->Build(); } 198 } << 181 if(masterRM->GetUserWorkerInitialization()) 199 if (masterRM->GetUserWorkerInitialization() << 182 { masterRM->GetUserWorkerInitialization()->WorkerStart(); } 200 masterRM->GetUserWorkerInitialization()->W << 201 } << 202 wrm->Initialize(); 183 wrm->Initialize(); 203 184 204 //================================ 185 //================================ 205 // Step5: Loop over requests from the master << 186 //Step5: Loop over requests from the master thread 206 //================================ 187 //================================ 207 // This function should enter a loop process << 188 //This function should enter a loop processing new runs and actions 208 // requests from master. It should block unt << 189 //requests from master. It should block until thread is ready 209 // to terminate << 190 //to terminate 210 wrm->DoWork(); 191 wrm->DoWork(); 211 192 212 //=============================== 193 //=============================== 213 // Step-6: Terminate worker thread << 194 //Step-6: Terminate worker thread 214 //=============================== 195 //=============================== 215 if (masterRM->GetUserWorkerInitialization() << 196 if(masterRM->GetUserWorkerInitialization()) 216 masterRM->GetUserWorkerInitialization()->W << 197 { masterRM->GetUserWorkerInitialization()->WorkerStop(); } 217 } << 218 198 219 wrmm.lock(); 199 wrmm.lock(); 220 for (auto itrWrm = workerRMvector->cbegin(); << 200 std::vector<G4WorkerRunManager*>::iterator itrWrm = workerRMvector->begin(); 221 if ((*itrWrm) == wrm) { << 201 for(;itrWrm!=workerRMvector->end();itrWrm++) >> 202 { >> 203 if((*itrWrm)==wrm) >> 204 { 222 workerRMvector->erase(itrWrm); 205 workerRMvector->erase(itrWrm); 223 break; 206 break; 224 } 207 } 225 } 208 } 226 wrmm.unlock(); 209 wrmm.unlock(); 227 delete wrm; 210 delete wrm; 228 211 229 //=============================== 212 //=============================== 230 // Step-7: Cleanup split classes << 213 //Step-7: Cleanup split classes 231 //=============================== 214 //=============================== 232 G4WorkerThread::DestroyGeometryAndPhysicsVec << 215 wThreadContext->DestroyGeometryAndPhysicsVector(); 233 wThreadContext = nullptr; << 216 wThreadContext = 0; 234 217 235 G4Threading::WorkerThreadLeavesPool(); 218 G4Threading::WorkerThreadLeavesPool(); >> 219 return static_cast<void*>(0); 236 } 220 } 237 221 238 // ------------------------------------------- << 222 #include "G4ParticleDefinition.hh" >> 223 #include "G4ParticleTable.hh" >> 224 #include "G4ParticleTableIterator.hh" >> 225 #include "G4DecayTable.hh" >> 226 #include "G4VDecayChannel.hh" >> 227 239 void G4MTRunManagerKernel::SetUpDecayChannels( 228 void G4MTRunManagerKernel::SetUpDecayChannels() 240 { 229 { 241 auto pItr = G4ParticleTable::GetParticleTabl << 230 G4ParticleTable::G4PTblDicIterator* pItr >> 231 = G4ParticleTable::GetParticleTable()->GetIterator(); 242 pItr->reset(); 232 pItr->reset(); 243 while ((*pItr)()) { << 233 while((*pItr)()) >> 234 { 244 G4DecayTable* dt = pItr->value()->GetDecay 235 G4DecayTable* dt = pItr->value()->GetDecayTable(); 245 if (dt != nullptr) { << 236 if(dt) >> 237 { 246 G4int nCh = dt->entries(); 238 G4int nCh = dt->entries(); 247 for (G4int i = 0; i < nCh; ++i) { << 239 for(G4int i=0;i<nCh;i++) 248 dt->GetDecayChannel(i)->GetDaughter(0) << 240 { dt->GetDecayChannel(i)->GetDaughter(0); } 249 } << 250 } 241 } 251 } 242 } 252 } 243 } 253 244 254 // ------------------------------------------- << 255 void G4MTRunManagerKernel::BroadcastAbortRun(G 245 void G4MTRunManagerKernel::BroadcastAbortRun(G4bool softAbort) 256 { 246 { 257 G4AutoLock wrmm(&workerRMMutex); 247 G4AutoLock wrmm(&workerRMMutex); 258 << 248 std::vector<G4WorkerRunManager*>::iterator itr = workerRMvector->begin(); 259 for (const auto& itr : *workerRMvector) { << 249 for(;itr!=workerRMvector->end();itr++) 260 itr->AbortRun(softAbort); << 250 { (*itr)->AbortRun(softAbort); } 261 } << 262 } 251 } >> 252 263 253