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 27 #include "G4TaskRunManagerKernel.hh" 28 29 #include "G4AutoLock.hh" 30 #include "G4DecayTable.hh" 31 #include "G4LogicalVolume.hh" 32 #include "G4Material.hh" 33 #include "G4MaterialTable.hh" 34 #include "G4PVParameterised.hh" 35 #include "G4PVReplica.hh" 36 #include "G4ParticleDefinition.hh" 37 #include "G4ParticleTable.hh" 38 #include "G4ParticleTableIterator.hh" 39 #include "G4PhysicalVolumeStore.hh" 40 #include "G4PhysicsVector.hh" 41 #include "G4PolyconeSide.hh" 42 #include "G4PolyhedraSide.hh" 43 #include "G4Region.hh" 44 #include "G4RegionStore.hh" 45 #include "G4Run.hh" 46 #include "G4StateManager.hh" 47 #include "G4TaskManager.hh" 48 #include "G4UImanager.hh" 49 #include "G4UserWorkerInitialization.hh" 50 #include "G4UserWorkerThreadInitialization.hh" 51 #include "G4VDecayChannel.hh" 52 #include "G4VModularPhysicsList.hh" 53 #include "G4VPhysicalVolume.hh" 54 #include "G4VPhysicsConstructor.hh" 55 #include "G4VUserActionInitialization.hh" 56 #include "G4VUserPhysicsList.hh" 57 #include "G4WorkerTaskRunManager.hh" 58 #include "G4WorkerThread.hh" 59 60 #include <atomic> 61 #include <memory> 62 63 //============================================ 64 65 std::vector<G4String> G4TaskRunManagerKernel:: 66 67 //============================================ 68 69 G4TaskRunManagerKernel::G4TaskRunManagerKernel 70 { 71 // This version of the constructor should ne 72 #ifndef G4MULTITHREADED 73 G4ExceptionDescription msg; 74 msg << "Geant4 code is compiled without mult 75 "(-DG4MULTITHREADED " 76 "is set to off)."; 77 msg << " This type of RunManager can only be 78 "applications."; 79 G4Exception("G4RunManagerKernel::G4RunManage 80 #endif 81 // Set flag that a MT-type kernel has been i 82 G4Threading::SetMultithreadedApplication(tru 83 } 84 85 //============================================ 86 87 void G4TaskRunManagerKernel::SetupShadowProces 88 { 89 // Behavior is the same as base class (seque 90 // ShadowProcess pointer == process poitner 91 G4RunManagerKernel::SetupShadowProcess(); 92 } 93 94 //============================================ 95 96 namespace 97 { 98 using WorkerRunManPtr_t = std::unique_ptr<G4Wo 99 using WorkerThreadPtr_t = std::unique_ptr<G4Wo 100 101 WorkerRunManPtr_t& workerRM() 102 { 103 G4ThreadLocalStatic WorkerRunManPtr_t _insta 104 return _instance; 105 } 106 107 WorkerThreadPtr_t& context() 108 { 109 G4ThreadLocalStatic WorkerThreadPtr_t _insta 110 return _instance; 111 } 112 113 } // namespace 114 115 //============================================ 116 117 G4WorkerThread* G4TaskRunManagerKernel::GetWor 118 { 119 return context().get(); 120 } 121 122 //============================================ 123 124 void G4TaskRunManagerKernel::InitializeWorker( 125 { 126 if (context() && workerRM()) return; 127 128 G4TaskRunManager* mrm = G4TaskRunManager::Ge 129 if (G4MTRunManager::GetMasterThreadId() == G 130 G4TaskManager* taskManager = mrm->GetTaskM 131 auto _fut = taskManager->async(InitializeW 132 _fut->wait(); 133 return; 134 } 135 136 //!!!!!!!!!!!!!!!!!!!!!!!!!! 137 //!!!!!! IMPORTANT !!!!!!!!! 138 //!!!!!!!!!!!!!!!!!!!!!!!!!! 139 // Here is not sequential anymore and G4User 140 // a shared user initialization class 141 // This means this method cannot use data me 142 // unless they are invariant ("read-only") a 143 // All the rest that is not invariant shoul 144 // the context (or, as for wThreadContext b 145 //!!!!!!!!!!!!!!!!!!!!!!!!!! 146 147 G4Threading::WorkerThreadJoinsPool(); 148 context() = std::make_unique<G4WorkerThread> 149 150 //============================ 151 // Step-0: Thread ID 152 //============================ 153 // Initliazie per-thread stream-output 154 // The following line is needed before we ac 155 // becasue the constructor of UI manager res 156 context()->SetNumberThreads((G4int)mrm->GetT 157 context()->SetThreadId(G4int(G4ThreadPool::g 158 G4int thisID = context()->GetThreadId(); 159 G4Threading::G4SetThreadId(thisID); 160 G4UImanager::GetUIpointer()->SetUpForAThread 161 162 //============================ 163 // Optimization: optional 164 //============================ 165 // Enforce thread affinity if requested 166 context()->SetPinAffinity(mrm->GetPinAffinit 167 168 //============================ 169 // Step-1: Random number engine 170 //============================ 171 // RNG Engine needs to be initialized by "cl 172 const CLHEP::HepRandomEngine* masterEngine = 173 mrm->GetUserWorkerThreadInitialization()->Se 174 175 //============================ 176 // Step-2: Initialize worker thread 177 //============================ 178 if (mrm->GetUserWorkerInitialization() != nu 179 mrm->GetUserWorkerInitialization()->Worker 180 181 if (mrm->GetUserActionInitialization() != nu 182 G4VSteppingVerbose* sv = mrm->GetUserActio 183 if (sv != nullptr) G4VSteppingVerbose::Set 184 } 185 // Now initialize worker part of shared obje 186 G4WorkerThread::BuildGeometryAndPhysicsVecto 187 workerRM().reset(static_cast<G4WorkerTaskRun 188 mrm->GetUserWorkerThreadInitialization()-> 189 auto& wrm = workerRM(); 190 wrm->SetWorkerThread(context().get()); 191 192 //================================ 193 // Step-3: Setup worker run manager 194 //================================ 195 // Set the detector and physics list to the 196 const G4VUserDetectorConstruction* detector 197 wrm->G4RunManager::SetUserInitialization(con 198 const G4VUserPhysicsList* physicslist = mrm- 199 wrm->SetUserInitialization(const_cast<G4VUse 200 201 //================================ 202 // Step-4: Initialize worker run manager 203 //================================ 204 if (mrm->GetUserActionInitialization() != nu 205 mrm->GetNonConstUserActionInitialization() 206 if (mrm->GetUserWorkerInitialization() != nu 207 mrm->GetUserWorkerInitialization()->Worker 208 209 workerRM()->Initialize(); 210 211 for (auto& itr : initCmdStack) 212 G4UImanager::GetUIpointer()->ApplyCommand( 213 214 wrm->ProcessUI(); 215 } 216 217 //============================================ 218 219 void G4TaskRunManagerKernel::ExecuteWorkerInit 220 { 221 // because of TBB 222 if (G4MTRunManager::GetMasterThreadId() == G 223 G4TaskManager* taskManager = G4TaskRunMana 224 auto _fut = taskManager->async(ExecuteWork 225 return _fut->get(); 226 } 227 228 // this check is for TBB as there is not a w 229 // routine on each thread 230 if (!workerRM()) InitializeWorker(); 231 232 auto& wrm = workerRM(); 233 assert(wrm.get() != nullptr); 234 wrm->DoCleanup(); 235 } 236 237 //============================================ 238 239 void G4TaskRunManagerKernel::ExecuteWorkerTask 240 { 241 // because of TBB 242 if (G4MTRunManager::GetMasterThreadId() == G 243 G4TaskManager* taskManager = G4TaskRunMana 244 auto _fut = taskManager->async(ExecuteWork 245 return _fut->get(); 246 } 247 248 // this check is for TBB as there is not a w 249 // routine on each thread 250 if (!workerRM()) InitializeWorker(); 251 252 auto& wrm = workerRM(); 253 assert(wrm.get() != nullptr); 254 wrm->DoWork(); 255 } 256 257 //============================================ 258 259 void G4TaskRunManagerKernel::TerminateWorkerRu 260 { 261 if (workerRM()) TerminateWorkerRunEventLoop( 262 } 263 264 //============================================ 265 266 void G4TaskRunManagerKernel::TerminateWorker() 267 { 268 //=============================== 269 // Step-6: Terminate worker thread 270 //=============================== 271 G4TaskRunManager* mrm = G4TaskRunManager::Ge 272 if ((mrm != nullptr) && (mrm->GetUserWorkerI 273 mrm->GetUserWorkerInitialization()->Worker 274 275 workerRM().reset(); 276 context().reset(); 277 278 G4WorkerThread::DestroyGeometryAndPhysicsVec 279 280 G4Threading::WorkerThreadLeavesPool(); 281 } 282 283 //============================================ 284 285 void G4TaskRunManagerKernel::TerminateWorkerRu 286 { 287 if (wrm == nullptr) return; 288 289 wrm->TerminateEventLoop(); 290 wrm->RunTermination(); 291 } 292 293 //============================================ 294 295 std::vector<G4String>& G4TaskRunManagerKernel: 296 { 297 return initCmdStack; 298 } 299 300 //============================================ 301 302 void G4TaskRunManagerKernel::SetUpDecayChannel 303 { 304 G4ParticleTable::G4PTblDicIterator* pItr = G 305 pItr->reset(); 306 while ((*pItr)()) { 307 G4DecayTable* dt = pItr->value()->GetDecay 308 if (dt != nullptr) { 309 G4int nCh = dt->entries(); 310 for (G4int i = 0; i < nCh; i++) { 311 dt->GetDecayChannel(i)->GetDaughter(0) 312 } 313 } 314 } 315 } 316 317 //============================================ 318 319 void G4TaskRunManagerKernel::BroadcastAbortRun 320 { 321 G4ConsumeParameters(softAbort); 322 } 323 324 //============================================ 325