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
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