Geant4-11
Public Member Functions | Static Public Member Functions | Private Attributes
G4WorkerThread Class Reference

#include <G4WorkerThread.hh>

Public Member Functions

G4int GetNumberThreads () const
 
G4int GetThreadId () const
 
void SetNumberThreads (G4int numnberThreads)
 
void SetPinAffinity (G4int aff) const
 
void SetThreadId (G4int threadId)
 

Static Public Member Functions

static void BuildGeometryAndPhysicsVector ()
 
static void DestroyGeometryAndPhysicsVector ()
 
static void UpdateGeometryAndPhysicsVectorFromMaster ()
 

Private Attributes

G4int numThreads = 0
 
G4int threadId = 0
 

Detailed Description

Definition at line 43 of file G4WorkerThread.hh.

Member Function Documentation

◆ BuildGeometryAndPhysicsVector()

void G4WorkerThread::BuildGeometryAndPhysicsVector ( )
static

◆ DestroyGeometryAndPhysicsVector()

void G4WorkerThread::DestroyGeometryAndPhysicsVector ( )
static

◆ GetNumberThreads()

G4int G4WorkerThread::GetNumberThreads ( ) const

Definition at line 65 of file G4WorkerThread.cc.

66{
67 return numThreads;
68}

References numThreads.

◆ GetThreadId()

G4int G4WorkerThread::GetThreadId ( ) const

◆ SetNumberThreads()

void G4WorkerThread::SetNumberThreads ( G4int  numnberThreads)

Definition at line 59 of file G4WorkerThread.cc.

60{
61 numThreads = nw;
62}

References numThreads.

◆ SetPinAffinity()

void G4WorkerThread::SetPinAffinity ( G4int  aff) const

Definition at line 211 of file G4WorkerThread.cc.

212{
213 if(affinity == 0)
214 return;
215
216#if !defined(WIN32)
217 G4cout << "AFFINITY SET" << G4endl;
218 // Assign this thread to cpus in a round robin way
219 G4int offset = affinity;
220 G4int cpuindex = 0;
221 if(std::abs(offset) > G4Threading::G4GetNumberOfCores())
222 {
223 G4Exception("G4WorkerThread::SetPinAffinity()", "Run0100", JustWarning,
224 "Cannot set thread affinity, affinity parameter larger than "
225 "number of cores");
226 return;
227 }
228 if(offset > 0) // Start assigning affinity to given CPU
229 {
230 --offset;
231 cpuindex = (GetThreadId() + offset) % G4Threading::G4GetNumberOfCores();
232 // Round robin
233 }
234 else // Exclude the given CPU
235 {
236 offset *= -1;
237 --offset;
239 cpuindex = myidx + (myidx >= offset);
240 }
241 G4cout << "Setting affinity to:" << cpuindex << G4endl;
242
243# if defined(G4MULTITHREADED)
244 // Avoid compilation warning in C90 standard w/o MT
245 G4NativeThread t = pthread_self();
246# else
248# endif
249 G4bool success = G4Threading::G4SetPinAffinity(cpuindex, t);
250 if(!success)
251 {
252 G4Exception("G4MTRunManagerKernel::StarThread()", "Run0101", JustWarning,
253 "Cannot set thread affinity.");
254 }
255#endif
256}
@ 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
G4int GetThreadId() const
G4bool G4SetPinAffinity(G4int idx, G4NativeThread &at)
Definition: G4Threading.cc:127
G4int G4GetNumberOfCores()
Definition: G4Threading.cc:121

References G4cout, G4endl, G4Exception(), G4Threading::G4GetNumberOfCores(), G4Threading::G4SetPinAffinity(), GetThreadId(), and JustWarning.

Referenced by G4MTRunManagerKernel::StartThread().

◆ SetThreadId()

void G4WorkerThread::SetThreadId ( G4int  threadId)

Definition at line 47 of file G4WorkerThread.cc.

48{
49 threadId = tid;
50}

References threadId.

◆ UpdateGeometryAndPhysicsVectorFromMaster()

void G4WorkerThread::UpdateGeometryAndPhysicsVectorFromMaster ( )
static

Definition at line 94 of file G4WorkerThread.cc.

95{
96 // =================================================
97 // Step-0: keep sensitive detector and field manager
98 // =================================================
99 // First remember SD and Filed Associated with worker
100 // in order to re-use it
101 // (note that all the stuff after this will reset SD and Field)
102 using LV2SDFM = std::map<G4LogicalVolume*,
103 std::pair<G4VSensitiveDetector*, G4FieldManager*>>;
104 LV2SDFM lvmap;
105
106 using R2FSM = std::map<G4Region*,
107 std::pair<G4FastSimulationManager*, G4UserSteppingAction*>>;
108 R2FSM rgnmap;
109
111 for(std::size_t ip = 0; ip < mLogVolStore->size(); ++ip)
112 {
113 G4LogicalVolume* lv = (*mLogVolStore)[ip];
114
115 // The following needs an explanation.
116 // Consider the case in which the user adds one LogVolume between
117 // the runs. The problem is that the thread-local part (split class)
118 // of the G4LogicalVolume object is not initialized for workers
119 // because the initialization is done once when the thread starts
120 // (see G4MTRunManagerKernel::StartThread Step-2 that calls
121 // G4WorkerThread::BuildGeometryAndPhysicsVector in this class).
122 // The problem is that pointers of SD and FM for these newly added LV
123 // may be invalid pointers (because never initialized, we have seen
124 // this behavior in our testing). If now we remember them and re-use
125 // them in Step-4 below we set invalid pointers to LV for this thread.
126 // Thus we need a way to know if for a given LV we need to remember
127 // or not the SD and FM pointers.
128 // To solve this problem: We assume that the ConstructSDandField() is
129 // called also by Master thread, thus for newly added LV the shadow
130 // pointers of SD and Fields are correct.
131 // (LIMITATION: this assumption may be too stringent, a user to save
132 // memory could instantiate SD only for workers, but we require this
133 // not to happen!).
134 // Thus if a SD and FieldMgr are needed for this particular LV, and
135 // shadow are !=0 it means that user wants an SD and FM to be
136 // associated with LV, we get the values and we remember them.
137 //
138 G4VSensitiveDetector* sd = nullptr;
139 G4FieldManager* fmgr = nullptr;
140 if(lv->GetMasterSensitiveDetector() != nullptr)
141 {
142 sd = lv->GetSensitiveDetector();
143 }
144 if(lv->GetMasterFieldManager() != nullptr)
145 {
146 fmgr = lv->GetFieldManager();
147 }
148 if(sd != nullptr || fmgr != nullptr)
149 {
150 lvmap[lv] = std::make_pair(sd, fmgr);
151 }
152 }
154 for(std::size_t ir = 0; ir < mRegStore->size(); ++ir)
155 {
156 G4Region* reg = (*mRegStore)[ir];
157 G4FastSimulationManager* fsm = reg->GetFastSimulationManager();
158 G4UserSteppingAction* usa = reg->GetRegionalSteppingAction();
159 if(reg != nullptr || usa != nullptr)
160 {
161 rgnmap[reg] = std::make_pair(fsm, usa);
162 }
163 }
164
165 //===========================
166 // Step-1: Clean the workspace
167 //===========================
168 G4GeometryWorkspace* geomWorkspace =
170 geomWorkspace->DestroyWorkspace();
171 G4SolidsWorkspace* solidWorkspace =
173 solidWorkspace->DestroyWorkspace();
174
175 //===========================
176 // Step-2: Re-create and initialize workspace
177 //===========================
178 geomWorkspace->InitialiseWorkspace();
179 solidWorkspace->InitialiseWorkspace();
180
181 //===================================================
182 // Step-4: Restore sensitive detector and field manaer
183 //===================================================
184 for(auto it = lvmap.cbegin(); it != lvmap.cend(); ++it)
185 {
186 G4LogicalVolume* lv = it->first;
187 G4VSensitiveDetector* sd = (it->second).first;
188 G4FieldManager* fmgr = (it->second).second;
189 if(fmgr != nullptr) // What should be the second parameter?
190 { // We use always false for MT mode
191 lv->SetFieldManager(fmgr, false);
192 }
193 if(sd)
194 {
195 lv->SetSensitiveDetector(sd);
196 }
197 }
198 for(auto it3 = rgnmap.cbegin(); it3 != rgnmap.cend(); ++it3)
199 {
200 G4Region* reg = it3->first;
201 G4FastSimulationManager* fsm = (it3->second).first;
202 if(fsm != nullptr)
203 reg->SetFastSimulationManager(fsm);
204 G4UserSteppingAction* usa = (it3->second).second;
205 if(usa != nullptr)
206 reg->SetRegionalSteppingAction(usa);
207 }
208}
static const G4double reg
static constexpr double second
Definition: G4SIunits.hh:137
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 G4RegionStore * GetInstance()

References G4SolidsWorkspace::DestroyWorkspace(), G4GeometryWorkspace::DestroyWorkspace(), G4LogicalVolume::GetFieldManager(), G4LogicalVolumeStore::GetInstance(), G4RegionStore::GetInstance(), G4LogicalVolume::GetMasterFieldManager(), G4LogicalVolume::GetMasterSensitiveDetector(), G4SolidsWorkspace::GetPool(), G4GeometryWorkspace::GetPool(), G4LogicalVolume::GetSensitiveDetector(), G4TWorkspacePool< T >::GetWorkspace(), G4SolidsWorkspace::InitialiseWorkspace(), G4GeometryWorkspace::InitialiseWorkspace(), anonymous_namespace{G4QuasiElRatios.cc}::map, reg, second, G4LogicalVolume::SetFieldManager(), and G4LogicalVolume::SetSensitiveDetector().

Referenced by G4WorkerRunManager::DoWork(), and G4WorkerTaskRunManager::DoWork().

Field Documentation

◆ numThreads

G4int G4WorkerThread::numThreads = 0
private

Definition at line 64 of file G4WorkerThread.hh.

Referenced by GetNumberThreads(), and SetNumberThreads().

◆ threadId

G4int G4WorkerThread::threadId = 0
private

Definition at line 63 of file G4WorkerThread.hh.

Referenced by GetThreadId(), and SetThreadId().


The documentation for this class was generated from the following files: