ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4MTRunManagerKernel.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4MTRunManagerKernel.cc
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 
27 #include "G4MTRunManagerKernel.hh"
28 #include "G4RegionStore.hh"
29 #include "G4StateManager.hh"
30 #include "G4AutoLock.hh"
31 
32 std::vector<G4WorkerRunManager*>* G4MTRunManagerKernel::workerRMvector = 0;
33 
34 namespace {
35  G4Mutex workerRMMutex = G4MUTEX_INITIALIZER;
36 }
37 
39 {
40  //This version of the constructor should never be called in sequential mode!
41 #ifndef G4MULTITHREADED
43  msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
44  msg<<" This type of RunManager can only be used in mult-threaded applications.";
45  G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0109",FatalException,msg);
46 #endif
47  G4AutoLock l(&workerRMMutex);
48  if(!workerRMvector) workerRMvector = new std::vector<G4WorkerRunManager*>;
49  l.unlock();
50  //Set flag that a MT-type kernel has been instantiated
52 }
53 
55 {
56  G4AutoLock l(&workerRMMutex);
57  if(workerRMvector)
58  {
59  if(workerRMvector->size()>0)
60  {
62  msg<<"G4MTRunManagerKernel is to be deleted while "
63  <<workerRMvector->size()<<" G4WorkerRunManager are still alive.";
64  G4Exception("G4RunManagerKernel::~G4RunManagerKernel()",
65  "Run10035",FatalException,msg);
66  }
67  delete workerRMvector;
68  workerRMvector = 0;
69  }
70 }
71 
73 {
74  //Behavior is the same as base class (sequential mode)
75  //ShadowProcess pointer == process poitner
77 }
78 
79 #include "G4WorkerRunManager.hh"
83 #include "G4WorkerThread.hh"
84 #include "G4UImanager.hh"
85 #include "G4LogicalVolume.hh"
86 #include "G4VPhysicalVolume.hh"
87 #include "G4PVReplica.hh"
88 #include "G4Region.hh"
89 #include "G4Material.hh"
90 #include "G4PhysicsVector.hh"
91 #include "G4VDecayChannel.hh"
92 #include "G4PhysicalVolumeStore.hh"
93 #include "G4MaterialTable.hh"
94 #include "G4PolyconeSide.hh"
95 #include "G4PolyhedraSide.hh"
96 #include "G4PVParameterised.hh"
97 #include "G4VUserPhysicsList.hh"
98 #include "G4VPhysicsConstructor.hh"
99 #include "G4VModularPhysicsList.hh"
100 
103 { return wThreadContext; }
104 
106 {
110  // Here is not sequential anymore and G4UserWorkerThreadInitialization is
111  // a shared user initialization class
112  // This means this method cannot use data memebers of G4RunManagerKernel
113  // unless they are invariant ("read-only") and can be safely shared.
114  // All the rest that is not invariant should be incapsualted into
115  // the context (or, as for wThreadContext be G4ThreadLocal)
117 //#ifdef G4MULTITHREADED
118 // turnontpmalloc();
119 //#endif
123 
124 
125  //============================
126  //Step-0: Thread ID
127  //============================
128  //Initliazie per-thread stream-output
129  //The following line is needed before we actually do IO initialization
130  //becasue the constructor of UI manager resets the IO destination.
131  G4int thisID = wThreadContext->GetThreadId();
134 
135  //============================
136  //Optimization: optional
137  //============================
138  //Enforce thread affinity if requested
140 
141  //============================
142  //Step-1: Random number engine
143  //============================
144  //RNG Engine needs to be initialized by "cloning" the master one.
145  const CLHEP::HepRandomEngine* masterEngine = masterRM->getMasterRandomEngine();
146  masterRM->GetUserWorkerThreadInitialization()->SetupRNGEngine(masterEngine);
147 
148  //============================
149  //Step-2: Initialize worker thread
150  //============================
151  if(masterRM->GetUserWorkerInitialization())
153  if(masterRM->GetUserActionInitialization())
154  {
156  if ( sv ) { G4VSteppingVerbose::SetInstance(sv); }
157  }
158  //Now initialize worker part of shared objects (geometry/physics)
160  G4WorkerRunManager* wrm
163  G4AutoLock wrmm(&workerRMMutex);
164  workerRMvector->push_back(wrm);
165  wrmm.unlock();
166 
167  //================================
168  //Step-3: Setup worker run manager
169  //================================
170  // Set the detector and physics list to the worker thread. Share with master
171  const G4VUserDetectorConstruction* detector = masterRM->GetUserDetectorConstruction();
172  wrm->G4RunManager::SetUserInitialization(const_cast<G4VUserDetectorConstruction*>(detector));
173  const G4VUserPhysicsList* physicslist = masterRM->GetUserPhysicsList();
174  wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist));
175 
176  //================================
177  //Step-4: Initialize worker run manager
178  //================================
179  if(masterRM->GetUserActionInitialization())
180  { masterRM->GetNonConstUserActionInitialization()->Build(); }
181  if(masterRM->GetUserWorkerInitialization())
182  { masterRM->GetUserWorkerInitialization()->WorkerStart(); }
183  wrm->Initialize();
184 
185  //================================
186  //Step5: Loop over requests from the master thread
187  //================================
188  //This function should enter a loop processing new runs and actions
189  //requests from master. It should block until thread is ready
190  //to terminate
191  wrm->DoWork();
192 
193  //===============================
194  //Step-6: Terminate worker thread
195  //===============================
196  if(masterRM->GetUserWorkerInitialization())
197  { masterRM->GetUserWorkerInitialization()->WorkerStop(); }
198 
199  wrmm.lock();
200  std::vector<G4WorkerRunManager*>::iterator itrWrm = workerRMvector->begin();
201  for(;itrWrm!=workerRMvector->end();itrWrm++)
202  {
203  if((*itrWrm)==wrm)
204  {
205  workerRMvector->erase(itrWrm);
206  break;
207  }
208  }
209  wrmm.unlock();
210  delete wrm;
211 
212  //===============================
213  //Step-7: Cleanup split classes
214  //===============================
216  wThreadContext = 0;
217 
219 }
220 
221 #include "G4ParticleDefinition.hh"
222 #include "G4ParticleTable.hh"
224 #include "G4DecayTable.hh"
225 #include "G4VDecayChannel.hh"
226 
228 {
231  pItr->reset();
232  while((*pItr)())
233  {
234  G4DecayTable* dt = pItr->value()->GetDecayTable();
235  if(dt)
236  {
237  G4int nCh = dt->entries();
238  for(G4int i=0;i<nCh;i++)
239  { dt->GetDecayChannel(i)->GetDaughter(0); }
240  }
241  }
242 }
243 
245 {
246  G4AutoLock wrmm(&workerRMMutex);
247  std::vector<G4WorkerRunManager*>::iterator itr = workerRMvector->begin();
248  for(;itr!=workerRMvector->end();itr++)
249  { (*itr)->AbortRun(softAbort); }
250 }
251