Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4TaskRunManagerKernel.cc
Go to the documentation of this file.
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
28#include "G4AutoLock.hh"
29#include "G4RegionStore.hh"
30#include "G4StateManager.hh"
31
32#include "G4DecayTable.hh"
33#include "G4LogicalVolume.hh"
34#include "G4Material.hh"
35#include "G4MaterialTable.hh"
36#include "G4PVParameterised.hh"
37#include "G4PVReplica.hh"
39#include "G4ParticleTable.hh"
42#include "G4PhysicsVector.hh"
43#include "G4PolyconeSide.hh"
44#include "G4PolyhedraSide.hh"
45#include "G4Region.hh"
46#include "G4Run.hh"
47#include "G4TaskManager.hh"
48#include "G4TiMemory.hh"
49#include "G4UImanager.hh"
52#include "G4VDecayChannel.hh"
54#include "G4VPhysicalVolume.hh"
57#include "G4VUserPhysicsList.hh"
59#include "G4WorkerThread.hh"
60
61#include <atomic>
62#include <memory>
63
64//============================================================================//
65
66std::vector<G4String> G4TaskRunManagerKernel::initCmdStack = {};
67
68//============================================================================//
69
71 : G4RunManagerKernel(masterRMK)
72{
73 // This version of the constructor should never be called in sequential mode!
74#ifndef G4MULTITHREADED
76 msg << "Geant4 code is compiled without multi-threading support "
77 "(-DG4MULTITHREADED "
78 "is set to off).";
79 msg << " This type of RunManager can only be used in mult-threaded "
80 "applications.";
81 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0109",
82 FatalException, msg);
83#endif
84 // Set flag that a MT-type kernel has been instantiated
86}
87
88//============================================================================//
89
91
92//============================================================================//
93
95{
96 // Behavior is the same as base class (sequential mode)
97 // ShadowProcess pointer == process poitner
99}
100
101//============================================================================//
102
103namespace
104{
105 using WorkerRunManPtr_t = std::unique_ptr<G4WorkerTaskRunManager>;
106 using WorkerThreadPtr_t = std::unique_ptr<G4WorkerThread>;
107
108 WorkerRunManPtr_t& workerRM()
109 {
110 G4ThreadLocalStatic WorkerRunManPtr_t _instance{ nullptr };
111 return _instance;
112 }
113
114 WorkerThreadPtr_t& context()
115 {
116 G4ThreadLocalStatic WorkerThreadPtr_t _instance{ nullptr };
117 return _instance;
118 }
119
120} // namespace
121
122//============================================================================//
123
125{
126 return context().get();
127}
128
129//============================================================================//
130
132{
133 if(context() && workerRM())
134 return;
135
137 if(G4MTRunManager::GetMasterThreadId() == G4ThisThread::get_id())
138 {
139 G4TaskManager* taskManager = mrm->GetTaskManager();
140 auto _fut = taskManager->async(InitializeWorker);
141 _fut->wait();
142 return;
143 }
144
145 //!!!!!!!!!!!!!!!!!!!!!!!!!!
146 //!!!!!! IMPORTANT !!!!!!!!!
147 //!!!!!!!!!!!!!!!!!!!!!!!!!!
148 // Here is not sequential anymore and G4UserWorkerThreadInitialization is
149 // a shared user initialization class
150 // This means this method cannot use data memebers of G4RunManagerKernel
151 // unless they are invariant ("read-only") and can be safely shared.
152 // All the rest that is not invariant should be incapsualted into
153 // the context (or, as for wThreadContext be G4ThreadLocal)
154 //!!!!!!!!!!!!!!!!!!!!!!!!!!
155
157 context().reset(new G4WorkerThread);
158
159 //============================
160 // Step-0: Thread ID
161 //============================
162 // Initliazie per-thread stream-output
163 // The following line is needed before we actually do IO initialization
164 // becasue the constructor of UI manager resets the IO destination.
165 context()->SetNumberThreads((G4int)mrm->GetThreadPool()->size());
166 context()->SetThreadId(G4int(G4ThreadPool::get_this_thread_id() - 1));
167 G4int thisID = context()->GetThreadId();
170
171 //============================
172 // Optimization: optional
173 //============================
174 // Enforce thread affinity if requested
175 context()->SetPinAffinity(mrm->GetPinAffinity());
176
177 //============================
178 // Step-1: Random number engine
179 //============================
180 // RNG Engine needs to be initialized by "cloning" the master one.
181 const CLHEP::HepRandomEngine* masterEngine = mrm->getMasterRandomEngine();
183
184 //============================
185 // Step-2: Initialize worker thread
186 //============================
189
191 {
194 if(sv)
196 }
197 // Now initialize worker part of shared objects (geometry/physics)
198 context()->BuildGeometryAndPhysicsVector();
199 workerRM().reset(static_cast<G4WorkerTaskRunManager*>(
201 auto& wrm = workerRM();
202 wrm->SetWorkerThread(context().get());
203
204 //================================
205 // Step-3: Setup worker run manager
206 //================================
207 // Set the detector and physics list to the worker thread. Share with master
208 const G4VUserDetectorConstruction* detector =
210 wrm->G4RunManager::SetUserInitialization(
211 const_cast<G4VUserDetectorConstruction*>(detector));
212 const G4VUserPhysicsList* physicslist = mrm->GetUserPhysicsList();
213 wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist));
214
215 //================================
216 // Step-4: Initialize worker run manager
217 //================================
222
223 workerRM()->Initialize();
224
225 for(auto& itr : initCmdStack)
227
228 wrm->ProcessUI();
229}
230
231//============================================================================//
232
234{
235 // because of TBB
236 if(G4MTRunManager::GetMasterThreadId() == G4ThisThread::get_id())
237 {
238 G4TaskManager* taskManager =
240 auto _fut = taskManager->async(ExecuteWorkerInit);
241 return _fut->get();
242 }
243
244 // this check is for TBB as there is not a way to run an initialization
245 // routine on each thread
246 if(!workerRM())
248
249 auto& wrm = workerRM();
250 assert(wrm.get() != nullptr);
251 wrm->DoCleanup();
252}
253
254//============================================================================//
255
257{
258 // because of TBB
259 if(G4MTRunManager::GetMasterThreadId() == G4ThisThread::get_id())
260 {
261 G4TaskManager* taskManager =
263 auto _fut = taskManager->async(ExecuteWorkerTask);
264 return _fut->get();
265 }
266
267 // this check is for TBB as there is not a way to run an initialization
268 // routine on each thread
269 if(!workerRM())
271
272 auto& wrm = workerRM();
273 assert(wrm.get() != nullptr);
274 wrm->DoWork();
275}
276
277//============================================================================//
278
280{
281 if(workerRM())
282 TerminateWorkerRunEventLoop(workerRM().get());
283}
284
285//============================================================================//
286
288{
289 if(workerRM())
290 TerminateWorker(workerRM().get());
291 workerRM().reset();
292 context().reset();
293}
294
295//============================================================================//
296
299{
300 if(!wrm)
301 return;
302
303 wrm->TerminateEventLoop();
304 wrm->RunTermination();
305}
306
307//============================================================================//
308
310{
311 if(!wrm)
312 return;
313
314 //===============================
315 // Step-6: Terminate worker thread
316 //===============================
318 if(mrm && mrm->GetUserWorkerInitialization())
320
321 G4WorkerThread* _context = wrm->GetWorkerThread();
323
325}
326
327//============================================================================//
328
330{
331 return initCmdStack;
332}
333
334//============================================================================//
335
337{
340 pItr->reset();
341 while((*pItr)())
342 {
343 G4DecayTable* dt = pItr->value()->GetDecayTable();
344 if(dt)
345 {
346 G4int nCh = dt->entries();
347 for(G4int i = 0; i < nCh; i++)
348 {
349 dt->GetDecayChannel(i)->GetDaughter(0);
350 }
351 }
352 }
353}
354
355//============================================================================//
356
358{
359 G4ConsumeParameters(softAbort);
360}
361
362//============================================================================//
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4VDecayChannel * GetDecayChannel(G4int index) const
G4int entries() const
G4int GetPinAffinity() const
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
static G4ThreadId GetMasterThreadId()
void reset(G4bool ifSkipIon=true)
G4PTblDicIterator * GetIterator() const
static G4ParticleTable * GetParticleTable()
virtual void SetupShadowProcess() const
const G4UserWorkerInitialization * GetUserWorkerInitialization() const
const G4VUserDetectorConstruction * GetUserDetectorConstruction() const
const G4VUserActionInitialization * GetUserActionInitialization() const
G4VUserActionInitialization * GetNonConstUserActionInitialization() const
const G4VUserPhysicsList * GetUserPhysicsList() const
const G4UserWorkerThreadInitialization * GetUserWorkerThreadInitialization() const
void BroadcastAbortRun(G4bool softAbort)
static G4RUN_DLL std::vector< G4String > initCmdStack
static G4WorkerThread * GetWorkerThread()
static std::vector< G4String > & InitCommandStack()
static G4TaskRunManager * GetMasterRunManager()
void SetUpForAThread(G4int tId)
Definition: G4UImanager.cc:884
G4int ApplyCommand(const char *aCommand)
Definition: G4UImanager.cc:495
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:77
virtual void SetupRNGEngine(const CLHEP::HepRandomEngine *aRNGEngine) const
virtual G4WorkerRunManager * CreateWorkerRunManager() const
G4ParticleDefinition * GetDaughter(G4int anIndex)
static void SetInstance(G4VSteppingVerbose *Instance)
virtual void Build() const =0
virtual G4VSteppingVerbose * InitializeSteppingVerbose() const
virtual void RunTermination() override
virtual void TerminateEventLoop() override
G4WorkerThread * GetWorkerThread() const
static void DestroyGeometryAndPhysicsVector()
std::shared_ptr< PackagedTask< RetT, Args... > > async(FuncT &&func, Args &&... args)
Definition: TaskManager.hh:107
TaskManager * GetTaskManager() const
ThreadPool * GetThreadPool() const
static uintmax_t get_this_thread_id()
Definition: ThreadPool.cc:215
size_type size() const
Definition: ThreadPool.hh:252
G4int WorkerThreadJoinsPool()
Definition: G4Threading.cc:132
G4int WorkerThreadLeavesPool()
Definition: G4Threading.cc:131
void SetMultithreadedApplication(G4bool value)
Definition: G4Threading.cc:129
void G4SetThreadId(G4int aNewValue)
Definition: G4Threading.cc:125
void G4ConsumeParameters(_Args &&...)
Definition: templates.hh:177
#define G4ThreadLocalStatic
Definition: tls.hh:76