Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4MTRunManagerKernel implementation 27 // 28 // Author: M.Asai - July 2013 29 // ------------------------------------------- 30 #include "G4MTRunManagerKernel.hh" 31 32 #include "G4AutoLock.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" 48 #include "G4StateManager.hh" 49 #include "G4UImanager.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 63 G4ThreadLocal G4WorkerThread* G4MTRunManagerKe 64 65 // ------------------------------------------- 66 namespace 67 { 68 G4Mutex workerRMMutex = G4MUTEX_INITIALIZER; 69 } 70 71 // ------------------------------------------- 72 G4MTRunManagerKernel::G4MTRunManagerKernel() : 73 { 74 // This version of the constructor should ne 75 #ifndef G4MULTITHREADED 76 G4ExceptionDescription msg; 77 msg << "Geant4 code is compiled without mult 78 "(-DG4MULTITHREADED " 79 "is set to off)."; 80 msg << " This type of RunManager can only be 81 "applications."; 82 G4Exception("G4RunManagerKernel::G4RunManage 83 #endif 84 G4AutoLock l(&workerRMMutex); 85 if (workerRMvector == nullptr) workerRMvecto 86 l.unlock(); 87 // Set flag that a MT-type kernel has been i 88 G4Threading::SetMultithreadedApplication(tru 89 } 90 91 // ------------------------------------------- 92 G4MTRunManagerKernel::~G4MTRunManagerKernel() 93 { 94 G4AutoLock l(&workerRMMutex); 95 if (workerRMvector != nullptr) { 96 if (!workerRMvector->empty()) { 97 G4ExceptionDescription msg; 98 msg << "G4MTRunManagerKernel is to be de 99 << " G4WorkerRunManager are still al 100 G4Exception("G4RunManagerKernel::~G4RunM 101 } 102 delete workerRMvector; 103 workerRMvector = nullptr; 104 } 105 } 106 107 // ------------------------------------------- 108 void G4MTRunManagerKernel::SetupShadowProcess( 109 { 110 // Behavior is the same as base class (seque 111 // ShadowProcess pointer == process poitner 112 G4RunManagerKernel::SetupShadowProcess(); 113 } 114 115 // ------------------------------------------- 116 G4WorkerThread* G4MTRunManagerKernel::GetWorke 117 { 118 return wThreadContext; 119 } 120 121 // ------------------------------------------- 122 void G4MTRunManagerKernel::StartThread(G4Worke 123 { 124 //!!!!!!!!!!!!!!!!!!!!!!!!!! 125 //!!!!!! IMPORTANT !!!!!!!!! 126 //!!!!!!!!!!!!!!!!!!!!!!!!!! 127 // Here is not sequential anymore and G4User 128 // a shared user initialization class. 129 // This means this method cannot use data me 130 // unless they are invariant ("read-only") a 131 // All the rest that is not invariant should 132 // the context (or, as for wThreadContext be 133 //!!!!!!!!!!!!!!!!!!!!!!!!!! 134 // #ifdef G4MULTITHREADED 135 // turnontpmalloc(); 136 // #endif 137 G4Threading::WorkerThreadJoinsPool(); 138 wThreadContext = context; 139 G4MTRunManager* masterRM = G4MTRunManager::G 140 141 //============================ 142 // Step-0: Thread ID 143 //============================ 144 // Initialise per-thread stream-output 145 // The following line is needed before we ac 146 // because the constructor of UI manager res 147 G4int thisID = wThreadContext->GetThreadId() 148 G4Threading::G4SetThreadId(thisID); 149 G4UImanager::GetUIpointer()->SetUpForAThread 150 151 //============================ 152 // Optimization: optional 153 //============================ 154 // Enforce thread affinity if requested 155 wThreadContext->SetPinAffinity(masterRM->Get 156 157 //============================ 158 // Step-1: Random number engine 159 //============================ 160 // RNG Engine needs to be initialised by "cl 161 const CLHEP::HepRandomEngine* masterEngine = 162 masterRM->GetUserWorkerThreadInitialization( 163 164 //============================ 165 // Step-2: Initialise worker thread 166 //============================ 167 if (masterRM->GetUserWorkerInitialization() 168 masterRM->GetUserWorkerInitialization()->W 169 } 170 if (masterRM->GetUserActionInitialization() 171 G4VSteppingVerbose* sv = masterRM->GetUser 172 if (sv != nullptr) { 173 G4VSteppingVerbose::SetInstance(sv); 174 } 175 } 176 // Now initialise worker part of shared obje 177 G4WorkerThread::BuildGeometryAndPhysicsVecto 178 G4WorkerRunManager* wrm = masterRM->GetUserW 179 wrm->SetWorkerThread(wThreadContext); 180 G4AutoLock wrmm(&workerRMMutex); 181 workerRMvector->push_back(wrm); 182 wrmm.unlock(); 183 184 //================================ 185 // Step-3: Setup worker run manager 186 //================================ 187 // Set the detector and physics list to the 188 const G4VUserDetectorConstruction* detector 189 wrm->G4RunManager::SetUserInitialization(con 190 const G4VUserPhysicsList* physicslist = mast 191 wrm->SetUserInitialization(const_cast<G4VUse 192 193 //================================ 194 // Step-4: Initialise worker run manager 195 //================================ 196 if (masterRM->GetUserActionInitialization() 197 masterRM->GetNonConstUserActionInitializat 198 } 199 if (masterRM->GetUserWorkerInitialization() 200 masterRM->GetUserWorkerInitialization()->W 201 } 202 wrm->Initialize(); 203 204 //================================ 205 // Step5: Loop over requests from the master 206 //================================ 207 // This function should enter a loop process 208 // requests from master. It should block unt 209 // to terminate 210 wrm->DoWork(); 211 212 //=============================== 213 // Step-6: Terminate worker thread 214 //=============================== 215 if (masterRM->GetUserWorkerInitialization() 216 masterRM->GetUserWorkerInitialization()->W 217 } 218 219 wrmm.lock(); 220 for (auto itrWrm = workerRMvector->cbegin(); 221 if ((*itrWrm) == wrm) { 222 workerRMvector->erase(itrWrm); 223 break; 224 } 225 } 226 wrmm.unlock(); 227 delete wrm; 228 229 //=============================== 230 // Step-7: Cleanup split classes 231 //=============================== 232 G4WorkerThread::DestroyGeometryAndPhysicsVec 233 wThreadContext = nullptr; 234 235 G4Threading::WorkerThreadLeavesPool(); 236 } 237 238 // ------------------------------------------- 239 void G4MTRunManagerKernel::SetUpDecayChannels( 240 { 241 auto pItr = G4ParticleTable::GetParticleTabl 242 pItr->reset(); 243 while ((*pItr)()) { 244 G4DecayTable* dt = pItr->value()->GetDecay 245 if (dt != nullptr) { 246 G4int nCh = dt->entries(); 247 for (G4int i = 0; i < nCh; ++i) { 248 dt->GetDecayChannel(i)->GetDaughter(0) 249 } 250 } 251 } 252 } 253 254 // ------------------------------------------- 255 void G4MTRunManagerKernel::BroadcastAbortRun(G 256 { 257 G4AutoLock wrmm(&workerRMMutex); 258 259 for (const auto& itr : *workerRMvector) { 260 itr->AbortRun(softAbort); 261 } 262 } 263