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