Geant4 11.2.2
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
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"
40#include "G4ParticleTable.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"
52#include "G4VDecayChannel.hh"
54#include "G4VPhysicalVolume.hh"
57#include "G4VUserPhysicsList.hh"
58#include "G4WorkerRunManager.hh"
59#include "G4WorkerThread.hh"
60
61std::vector<G4WorkerRunManager*>* G4MTRunManagerKernel::workerRMvector = nullptr;
62
63G4ThreadLocal G4WorkerThread* G4MTRunManagerKernel::wThreadContext = nullptr;
64
65// --------------------------------------------------------------------
66namespace
67{
68G4Mutex workerRMMutex = G4MUTEX_INITIALIZER;
69}
70
71// --------------------------------------------------------------------
73{
74 // This version of the constructor should never be called in sequential mode!
75#ifndef G4MULTITHREADED
77 msg << "Geant4 code is compiled without multi-threading support "
78 "(-DG4MULTITHREADED "
79 "is set to off).";
80 msg << " This type of RunManager can only be used in mult-threaded "
81 "applications.";
82 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0109", FatalException, msg);
83#endif
84 G4AutoLock l(&workerRMMutex);
85 if (workerRMvector == nullptr) workerRMvector = new std::vector<G4WorkerRunManager*>;
86 l.unlock();
87 // Set flag that a MT-type kernel has been instantiated
89}
90
91// --------------------------------------------------------------------
93{
94 G4AutoLock l(&workerRMMutex);
95 if (workerRMvector != nullptr) {
96 if (!workerRMvector->empty()) {
98 msg << "G4MTRunManagerKernel is to be deleted while " << workerRMvector->size()
99 << " G4WorkerRunManager are still alive.";
100 G4Exception("G4RunManagerKernel::~G4RunManagerKernel()", "Run10035", FatalException, msg);
101 }
102 delete workerRMvector;
103 workerRMvector = nullptr;
104 }
105}
106
107// --------------------------------------------------------------------
109{
110 // Behavior is the same as base class (sequential mode)
111 // ShadowProcess pointer == process poitner
113}
114
115// --------------------------------------------------------------------
117{
118 return wThreadContext;
119}
120
121// --------------------------------------------------------------------
123{
124 //!!!!!!!!!!!!!!!!!!!!!!!!!!
125 //!!!!!! IMPORTANT !!!!!!!!!
126 //!!!!!!!!!!!!!!!!!!!!!!!!!!
127 // Here is not sequential anymore and G4UserWorkerThreadInitialization is
128 // a shared user initialization class.
129 // This means this method cannot use data members of G4RunManagerKernel
130 // unless they are invariant ("read-only") and can be safely shared.
131 // All the rest that is not invariant should be incapsulated into
132 // the context (or, as for wThreadContext be G4ThreadLocal)
133 //!!!!!!!!!!!!!!!!!!!!!!!!!!
134 // #ifdef G4MULTITHREADED
135 // turnontpmalloc();
136 // #endif
138 wThreadContext = context;
140
141 //============================
142 // Step-0: Thread ID
143 //============================
144 // Initialise per-thread stream-output
145 // The following line is needed before we actually do IO initialisation
146 // because the constructor of UI manager resets the IO destination.
147 G4int thisID = wThreadContext->GetThreadId();
150
151 //============================
152 // Optimization: optional
153 //============================
154 // Enforce thread affinity if requested
155 wThreadContext->SetPinAffinity(masterRM->GetPinAffinity());
156
157 //============================
158 // Step-1: Random number engine
159 //============================
160 // RNG Engine needs to be initialised by "cloning" the master one.
161 const CLHEP::HepRandomEngine* masterEngine = masterRM->getMasterRandomEngine();
162 masterRM->GetUserWorkerThreadInitialization()->SetupRNGEngine(masterEngine);
163
164 //============================
165 // Step-2: Initialise worker thread
166 //============================
167 if (masterRM->GetUserWorkerInitialization() != nullptr) {
169 }
170 if (masterRM->GetUserActionInitialization() != nullptr) {
172 if (sv != nullptr) {
174 }
175 }
176 // Now initialise worker part of shared objects (geometry/physics)
177 wThreadContext->BuildGeometryAndPhysicsVector();
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 worker thread. Share with master
188 const G4VUserDetectorConstruction* detector = masterRM->GetUserDetectorConstruction();
189 wrm->G4RunManager::SetUserInitialization(const_cast<G4VUserDetectorConstruction*>(detector));
190 const G4VUserPhysicsList* physicslist = masterRM->GetUserPhysicsList();
191 wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist));
192
193 //================================
194 // Step-4: Initialise worker run manager
195 //================================
196 if (masterRM->GetUserActionInitialization() != nullptr) {
198 }
199 if (masterRM->GetUserWorkerInitialization() != nullptr) {
201 }
202 wrm->Initialize();
203
204 //================================
205 // Step5: Loop over requests from the master thread
206 //================================
207 // This function should enter a loop processing new runs and actions
208 // requests from master. It should block until thread is ready
209 // to terminate
210 wrm->DoWork();
211
212 //===============================
213 // Step-6: Terminate worker thread
214 //===============================
215 if (masterRM->GetUserWorkerInitialization() != nullptr) {
217 }
218
219 wrmm.lock();
220 for (auto itrWrm = workerRMvector->cbegin(); itrWrm != workerRMvector->cend(); ++itrWrm) {
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 wThreadContext->DestroyGeometryAndPhysicsVector();
233 wThreadContext = nullptr;
234
236}
237
238// --------------------------------------------------------------------
240{
242 pItr->reset();
243 while ((*pItr)()) {
244 G4DecayTable* dt = pItr->value()->GetDecayTable();
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// --------------------------------------------------------------------
256{
257 G4AutoLock wrmm(&workerRMMutex);
258
259 for (const auto& itr : *workerRMvector) {
260 itr->AbortRun(softAbort);
261 }
262}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4VDecayChannel * GetDecayChannel(G4int index) const
G4int entries() const
void BroadcastAbortRun(G4bool softAbort)
void SetupShadowProcess() const override
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)
static G4UImanager * GetUIpointer()
virtual void SetupRNGEngine(const CLHEP::HepRandomEngine *aRNGEngine) const
virtual G4WorkerRunManager * CreateWorkerRunManager() const
G4ParticleDefinition * GetDaughter(G4int anIndex)
static void SetInstance(G4VSteppingVerbose *Instance)
virtual G4VSteppingVerbose * InitializeSteppingVerbose() const
virtual void Build() const =0
void SetWorkerThread(G4WorkerThread *wc)
void SetUserInitialization(G4VUserPhysicsList *userInit) override
G4int GetThreadId() const
static void BuildGeometryAndPhysicsVector()
static void DestroyGeometryAndPhysicsVector()
void SetPinAffinity(G4int aff) const
G4int WorkerThreadJoinsPool()
G4int WorkerThreadLeavesPool()
void SetMultithreadedApplication(G4bool value)
void G4SetThreadId(G4int aNewValue)
#define G4ThreadLocal
Definition tls.hh:77