Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MTRunManagerKernel.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// G4MTRunManagerKernel implementation
27//
28// Author: M.Asai - July 2013
29// --------------------------------------------------------------------
31#include "G4AutoLock.hh"
32#include "G4RegionStore.hh"
33#include "G4StateManager.hh"
34
35#include "G4LogicalVolume.hh"
36#include "G4Material.hh"
37#include "G4MaterialTable.hh"
38#include "G4PVParameterised.hh"
39#include "G4PVReplica.hh"
41#include "G4PhysicsVector.hh"
42#include "G4PolyconeSide.hh"
43#include "G4PolyhedraSide.hh"
44#include "G4Region.hh"
45#include "G4UImanager.hh"
48#include "G4VDecayChannel.hh"
50#include "G4VPhysicalVolume.hh"
53#include "G4VUserPhysicsList.hh"
54#include "G4WorkerRunManager.hh"
55#include "G4WorkerThread.hh"
56
57#include "G4DecayTable.hh"
59#include "G4ParticleTable.hh"
61#include "G4VDecayChannel.hh"
62
63std::vector<G4WorkerRunManager*>* G4MTRunManagerKernel::workerRMvector = nullptr;
64
65G4ThreadLocal G4WorkerThread* G4MTRunManagerKernel::wThreadContext = nullptr;
66
67// --------------------------------------------------------------------
68namespace
69{
70 G4Mutex workerRMMutex = G4MUTEX_INITIALIZER;
71}
72
73// --------------------------------------------------------------------
75 : G4RunManagerKernel(masterRMK)
76{
77 // This version of the constructor should never be called in sequential mode!
78#ifndef G4MULTITHREADED
80 msg << "Geant4 code is compiled without multi-threading support "
81 "(-DG4MULTITHREADED "
82 "is set to off).";
83 msg << " This type of RunManager can only be used in mult-threaded "
84 "applications.";
85 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0109",
86 FatalException, msg);
87#endif
88 G4AutoLock l(&workerRMMutex);
89 if(workerRMvector == nullptr)
90 workerRMvector = new std::vector<G4WorkerRunManager*>;
91 l.unlock();
92 // Set flag that a MT-type kernel has been instantiated
94}
95
96// --------------------------------------------------------------------
98{
99 G4AutoLock l(&workerRMMutex);
100 if(workerRMvector != nullptr)
101 {
102 if(workerRMvector->size() > 0)
103 {
105 msg << "G4MTRunManagerKernel is to be deleted while "
106 << workerRMvector->size() << " G4WorkerRunManager are still alive.";
107 G4Exception("G4RunManagerKernel::~G4RunManagerKernel()", "Run10035",
108 FatalException, msg);
109 }
110 delete workerRMvector;
111 workerRMvector = nullptr;
112 }
113}
114
115// --------------------------------------------------------------------
117{
118 // Behavior is the same as base class (sequential mode)
119 // ShadowProcess pointer == process poitner
121}
122
123// --------------------------------------------------------------------
125{
126 return wThreadContext;
127}
128
129// --------------------------------------------------------------------
131{
132 //!!!!!!!!!!!!!!!!!!!!!!!!!!
133 //!!!!!! IMPORTANT !!!!!!!!!
134 //!!!!!!!!!!!!!!!!!!!!!!!!!!
135 // Here is not sequential anymore and G4UserWorkerThreadInitialization is
136 // a shared user initialization class.
137 // This means this method cannot use data members of G4RunManagerKernel
138 // unless they are invariant ("read-only") and can be safely shared.
139 // All the rest that is not invariant should be incapsulated into
140 // the context (or, as for wThreadContext be G4ThreadLocal)
141 //!!!!!!!!!!!!!!!!!!!!!!!!!!
142 //#ifdef G4MULTITHREADED
143 // turnontpmalloc();
144 //#endif
146 wThreadContext = context;
148
149 //============================
150 // Step-0: Thread ID
151 //============================
152 // Initialise per-thread stream-output
153 // The following line is needed before we actually do IO initialisation
154 // because the constructor of UI manager resets the IO destination.
155 G4int thisID = wThreadContext->GetThreadId();
158
159 //============================
160 // Optimization: optional
161 //============================
162 // Enforce thread affinity if requested
163 wThreadContext->SetPinAffinity(masterRM->GetPinAffinity());
164
165 //============================
166 // Step-1: Random number engine
167 //============================
168 // RNG Engine needs to be initialised by "cloning" the master one.
169 const CLHEP::HepRandomEngine* masterEngine =
170 masterRM->getMasterRandomEngine();
171 masterRM->GetUserWorkerThreadInitialization()->SetupRNGEngine(masterEngine);
172
173 //============================
174 // Step-2: Initialise worker thread
175 //============================
176 if(masterRM->GetUserWorkerInitialization())
177 {
179 }
180 if(masterRM->GetUserActionInitialization())
181 {
184 if(sv != nullptr)
185 {
187 }
188 }
189 // Now initialise worker part of shared objects (geometry/physics)
190 wThreadContext->BuildGeometryAndPhysicsVector();
191 G4WorkerRunManager* wrm =
193 wrm->SetWorkerThread(wThreadContext);
194 G4AutoLock wrmm(&workerRMMutex);
195 workerRMvector->push_back(wrm);
196 wrmm.unlock();
197
198 //================================
199 // Step-3: Setup worker run manager
200 //================================
201 // Set the detector and physics list to the worker thread. Share with master
202 const G4VUserDetectorConstruction* detector =
203 masterRM->GetUserDetectorConstruction();
204 wrm->G4RunManager::SetUserInitialization(
205 const_cast<G4VUserDetectorConstruction*>(detector));
206 const G4VUserPhysicsList* physicslist = masterRM->GetUserPhysicsList();
207 wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist));
208
209 //================================
210 // Step-4: Initialise worker run manager
211 //================================
212 if(masterRM->GetUserActionInitialization())
213 {
215 }
216 if(masterRM->GetUserWorkerInitialization())
217 {
219 }
220 wrm->Initialize();
221
222 //================================
223 // Step5: Loop over requests from the master thread
224 //================================
225 // This function should enter a loop processing new runs and actions
226 // requests from master. It should block until thread is ready
227 // to terminate
228 wrm->DoWork();
229
230 //===============================
231 // Step-6: Terminate worker thread
232 //===============================
233 if(masterRM->GetUserWorkerInitialization())
234 {
236 }
237
238 wrmm.lock();
239 for(auto itrWrm = workerRMvector->cbegin();
240 itrWrm != workerRMvector->cend(); ++itrWrm)
241 {
242 if((*itrWrm) == wrm)
243 {
244 workerRMvector->erase(itrWrm);
245 break;
246 }
247 }
248 wrmm.unlock();
249 delete wrm;
250
251 //===============================
252 // Step-7: Cleanup split classes
253 //===============================
254 wThreadContext->DestroyGeometryAndPhysicsVector();
255 wThreadContext = nullptr;
256
258}
259
260// --------------------------------------------------------------------
262{
264 pItr->reset();
265 while((*pItr)())
266 {
267 G4DecayTable* dt = pItr->value()->GetDecayTable();
268 if(dt != nullptr)
269 {
270 G4int nCh = dt->entries();
271 for(G4int i = 0; i < nCh; ++i)
272 {
273 dt->GetDecayChannel(i)->GetDaughter(0);
274 }
275 }
276 }
277}
278
279// --------------------------------------------------------------------
281{
282 G4AutoLock wrmm(&workerRMMutex);
283
284 for(auto itr = workerRMvector->cbegin(); itr != workerRMvector->cend(); ++itr)
285 {
286 (*itr)->AbortRun(softAbort);
287 }
288}
@ 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
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4VDecayChannel * GetDecayChannel(G4int index) const
G4int entries() const
void BroadcastAbortRun(G4bool softAbort)
static G4WorkerThread * GetWorkerThread()
static void StartThread(G4WorkerThread *context)
G4int GetPinAffinity() const
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
static G4MTRunManager * GetMasterRunManager()
void reset(G4bool ifSkipIon=true)
G4PTblDicIterator * GetIterator() const
static G4ParticleTable * GetParticleTable()
virtual void SetupShadowProcess() const
const G4UserWorkerInitialization * GetUserWorkerInitialization() const
virtual void Initialize()
const G4VUserDetectorConstruction * GetUserDetectorConstruction() const
const G4VUserActionInitialization * GetUserActionInitialization() const
G4VUserActionInitialization * GetNonConstUserActionInitialization() const
const G4VUserPhysicsList * GetUserPhysicsList() const
const G4UserWorkerThreadInitialization * GetUserWorkerThreadInitialization() const
void SetUpForAThread(G4int tId)
Definition: G4UImanager.cc:884
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
void SetWorkerThread(G4WorkerThread *wc)
virtual void SetUserInitialization(G4VUserPhysicsList *userInit)
G4int GetThreadId() const
static void BuildGeometryAndPhysicsVector()
static void DestroyGeometryAndPhysicsVector()
void SetPinAffinity(G4int aff) const
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
#define G4ThreadLocal
Definition: tls.hh:77