Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4WorkerThread.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#include "G4WorkerThread.hh"
27#include "G4MTRunManager.hh"
28#include "G4WorkerRunManager.hh"
29
33#include "G4SolidsWorkspace.hh"
34
35#include "G4LogicalVolume.hh"
38#include "G4Region.hh"
39#include "G4RegionStore.hh"
40
41void G4WorkerThread::SetThreadId(G4int tid) { threadId = tid; }
42
43G4int G4WorkerThread::GetThreadId() const { return threadId; }
44
45void G4WorkerThread::SetNumberThreads(G4int nw) { numThreads = nw; }
46
47G4int G4WorkerThread::GetNumberThreads() const { return numThreads; }
48
50{
51 // Initialise all split classes
52 // with copy of data from master thread
53
58}
59
61{
62 // Clear all split classes
63
68}
69
71{
72 // =================================================
73 // Step-0: keep sensitive detector and field manager
74 // =================================================
75 // First remember SD and Filed Associated with worker
76 // in order to re-use it
77 // (note that all the stuff after this will reset SD and Field)
78 typedef std::map<G4LogicalVolume*,
79 std::pair<G4VSensitiveDetector*, G4FieldManager*>>
80 LV2SDFM;
81 LV2SDFM lvmap;
82
83 typedef std::map<G4Region*,
84 std::pair<G4FastSimulationManager*, G4UserSteppingAction*>>
85 R2FSM;
86 R2FSM rgnmap;
87
89 for(size_t ip = 0; ip < mLogVolStore->size(); ip++)
90 {
91 G4LogicalVolume* lv = (*mLogVolStore)[ip];
92
93 // The following needs an explanation.
94 // Consider the case in which the user adds one LogVolume between
95 // the runs. The problem is that the thread-local part (split class)
96 // of the G4LogicalVolume object is not initialized for workers
97 // because the initialization is done once when the thread starts
98 // (see G4MTRunManagerKernel::StartThread Step-2 that calls
99 // G4WorkerThread::BuildGeometryAndPhysicsVector in this class).
100 // The problem is that pointers of SD and FM for these newly added LV
101 // may be invalid pointers (because never initialized, we have seen
102 // this behavior in our testing). If now we remember them and re-use
103 // them in Step-4 below we set invalid pointers to LV for this thread.
104 // Thus we need a way to know if for a given LV we need to remember
105 // or not the SD and FM pointers.
106 // To solve this problem: We assume that the ConstructSDandField() is
107 // called also by Master thread, thus for newly added LV the shadow
108 // pointers of SD and Fields are correct.
109 // (LIMITATION: this assumption may be too stringent, a user to save
110 // memory could instantiate SD only for workers, but we require this
111 // not to happen!).
112 // Thus if a SD and FieldMgr are needed for this particular LV, and
113 // shadow are !=0 it means that user wants an SD and FM to be
114 // associated with LV, we get the values and we remember them.
115 //
116 G4VSensitiveDetector* sd = 0;
117 G4FieldManager* fmgr = 0;
118 if(lv->GetMasterSensitiveDetector() != 0)
119 {
120 sd = lv->GetSensitiveDetector();
121 }
122 if(lv->GetMasterFieldManager() != 0)
123 {
124 fmgr = lv->GetFieldManager();
125 }
126 if(sd || fmgr)
127 {
128 lvmap[lv] = std::make_pair(sd, fmgr);
129 }
130 }
132 for(size_t ir = 0; ir < mRegStore->size(); ir++)
133 {
134 G4Region* reg = (*mRegStore)[ir];
137 if(reg || usa)
138 {
139 rgnmap[reg] = std::make_pair(fsm, usa);
140 }
141 }
142
143 //===========================
144 // Step-1: Clean the workspace
145 //===========================
146 G4GeometryWorkspace* geomWorkspace =
148 geomWorkspace->DestroyWorkspace();
149 G4SolidsWorkspace* solidWorkspace =
151 solidWorkspace->DestroyWorkspace();
152
153 //===========================
154 // Step-2: Re-create and initialize workspace
155 //===========================
156 geomWorkspace->InitialiseWorkspace();
157 solidWorkspace->InitialiseWorkspace();
158
159 //===================================================
160 // Step-4: Restore sensitive detector and field manaer
161 //===================================================
162 for(LV2SDFM::const_iterator it = lvmap.begin(); it != lvmap.end(); ++it)
163 {
164 G4LogicalVolume* lv = it->first;
165 G4VSensitiveDetector* sd = (it->second).first;
166 G4FieldManager* fmgr = (it->second).second;
167 if(fmgr) // What should be the second parameter?
168 { // We use always false for MT mode
169 lv->SetFieldManager(fmgr, false);
170 }
171 if(sd)
172 {
173 lv->SetSensitiveDetector(sd);
174 }
175 }
176 for(R2FSM::const_iterator it3 = rgnmap.begin(); it3 != rgnmap.end(); it3++)
177 {
178 G4Region* reg = it3->first;
179 G4FastSimulationManager* fsm = (it3->second).first;
180 if(fsm)
181 reg->SetFastSimulationManager(fsm);
182 G4UserSteppingAction* usa = (it3->second).second;
183 if(usa)
185 }
186}
187
189{
190 if(affinity == 0)
191 return;
192
193#if !defined(WIN32)
194 G4cout << "AFFINITY SET" << G4endl;
195 // Assign this thread to cpus in a round robin way
196 G4int offset = affinity;
197 G4int cpuindex = 0;
198 if(std::abs(offset) > G4Threading::G4GetNumberOfCores())
199 {
200 G4Exception("G4WorkerThread::SetPinAffinity()", "Run0100", JustWarning,
201 "Cannot set thread affinity, affinity parameter larger than "
202 "number of cores");
203 return;
204 }
205 if(offset > 0) // Start assigning affinity to given CPU
206 {
207 --offset;
208 cpuindex = (GetThreadId() + offset) % G4Threading::G4GetNumberOfCores();
209 // Round robin
210 }
211 else // Exclude the given CPU
212 {
213 offset *= -1;
214 --offset;
216 cpuindex = myidx + (myidx >= offset);
217 }
218 G4cout << "Setting affinity to:" << cpuindex << G4endl;
219
220# if defined(G4MULTITHREADED)
221 // Avoid compilation warning in C90 standard w/o MT
222 G4NativeThread t = pthread_self();
223# else
225# endif
226 G4bool success = G4Threading::G4SetPinAffinity(cpuindex, t);
227 if(!success)
228 {
229 G4Exception("G4MTRunManagerKernel::StarThread()", "Run0101", JustWarning,
230 "Cannot set thread affinity.");
231 }
232#endif
233}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4DummyThread::native_handle_type G4NativeThread
Definition: G4Threading.hh:248
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static pool_type * GetPool()
static G4LogicalVolumeStore * GetInstance()
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
G4VSensitiveDetector * GetMasterSensitiveDetector() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4FieldManager * GetMasterFieldManager() const
G4FieldManager * GetFieldManager() const
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
static pool_type * GetPool()
static pool_type * GetPool()
static G4RegionStore * GetInstance()
G4FastSimulationManager * GetFastSimulationManager() const
Definition: G4Region.cc:130
void SetFastSimulationManager(G4FastSimulationManager *fsm)
Definition: G4Region.cc:121
void SetRegionalSteppingAction(G4UserSteppingAction *rusa)
Definition: G4Region.cc:139
G4UserSteppingAction * GetRegionalSteppingAction() const
Definition: G4Region.cc:148
static pool_type * GetPool()
void CleanUpAndDestroyAllWorkspaces()
G4int GetThreadId() const
static void BuildGeometryAndPhysicsVector()
static void UpdateGeometryAndPhysicsVectorFromMaster()
static void DestroyGeometryAndPhysicsVector()
void SetNumberThreads(G4int numnberThreads)
void SetPinAffinity(G4int aff) const
void SetThreadId(G4int threadId)
G4int GetNumberThreads() const
G4bool G4SetPinAffinity(G4int idx, G4NativeThread &at)
Definition: G4Threading.cc:127
G4int G4GetNumberOfCores()
Definition: G4Threading.cc:121