Geant4-11
G4MTRunManager.hh
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// G4MTRunManager
27//
28// Class description:
29//
30// This is a class for run control in Geant4 of multi-threaded runs.
31// It extends G4RunManager re-implementing multi-threaded behavior in
32// key methods (see documentation for G4RunManager).
33// Users initialise an instance of this class instead of G4RunManager
34// to start a multi-threaded simulation.
35
36// Original authors: X.Dong, A.Dotti - February 2013
37// --------------------------------------------------------------------
38#ifndef G4MTRunManager_hh
39#define G4MTRunManager_hh 1
40
41#include <list>
42#include <map>
43
44#include "G4MTBarrier.hh"
45#include "G4RNGHelper.hh"
46#include "G4RunManager.hh"
47#include "G4Threading.hh"
48#include "G4Profiler.hh"
49
55
56// TODO: Split random number storage from this class
57
59{
60 friend class G4RunManagerFactory;
61
62 public:
63
65 // The profiler aliases are only used when compiled with
66 // GEANT4_USE_TIMEMORY.
67
68 using masterWorlds_t = std::map<G4int, G4VPhysicalVolume*>;
69 // Map of defined worlds.
70
72 virtual ~G4MTRunManager();
73
74 virtual void SetNumberOfThreads(G4int n);
75 virtual G4int GetNumberOfThreads() const { return nworkers; }
76 void SetPinAffinity(G4int n = 1);
77 inline G4int GetPinAffinity() const { return pinAffinity; }
78
79 // Inherited methods to re-implement for MT case
80 virtual void Initialize();
81 virtual void InitializeEventLoop(G4int n_event, const char* macroFile = 0,
82 G4int n_select = -1);
83 virtual void InitializeThreadPool() {}
84
85 // The following do not do anything for this runmanager
86 virtual void TerminateOneEvent();
87 virtual void ProcessOneEvent(G4int i_event);
88 virtual void ConstructScoringWorlds();
89 virtual void RunTermination();
90
91 virtual G4bool SetUpAnEvent(G4Event*, long& s1, long& s2, long& s3,
92 G4bool reseedRequired = true);
93 // The following method should be invoked by G4WorkerRunManager for each
94 // event. False is returned if no more event to be processed.
95 // Note: G4Event object must be instantiated by a worker thread.
96 // In case no more events remain to be processed, that worker thread must
97 // delete that G4Event object. If a worker runs with its own random number
98 // sequence, the Boolean flag 'reseedRequired' should be set to false.
99 // This is *NOT* allowed for the first event.
100
101 virtual G4int SetUpNEvents(G4Event*, G4SeedsQueue* seedsQueue,
102 G4bool reseedRequired = true);
103 // Same as above method, but seeds are set only once over "eventModulo"
104 // events. The return value shows the number of events the caller Worker
105 // has to process (between 1 and eventModulo depending on number of events
106 // yet to be processed). G4Event object has the event ID of the first
107 // event of this bunch. If zero is returned no more events need to be
108 // processed, and worker thread must delete that G4Event.
109 // Called by Initialize() method.
110
111 std::vector<G4String> GetCommandStack();
112 // This method is invoked just before spawning the threads to
113 // collect from UI manager the list of commands that threads
114 // will execute.
115
116 virtual size_t GetNumberActiveThreads() const { return threads.size(); }
117 // Returns number of currently active threads.
118 // This number may be different from the number of threads currently
119 // in running state, e.g. the number returned by:
120 // G4Threading::GetNumberOfActiveWorkerThreads() method.
121
123
124 virtual void ThisWorkerReady();
125 // Worker threads barrier: this method should be called by each
126 // worker when ready to start thread event-loop.
127 // This method will return only when all workers are ready.
128
129 virtual void ThisWorkerEndEventLoop();
130 // Worker threads barrier: this method should be called by each
131 // worker when worker event loop is terminated.
132
135 static void addWorld(G4int counter, G4VPhysicalVolume* w);
136
138 {
139 return masterRNGEngine;
140 }
141
143 // Returns the singleton instance of the run manager common to all
144 // threads implementing the master behavior
147 // Returns the singleton instance of the run manager kernel common to all
148 //threads
149
150 virtual void SetUserInitialization(G4VUserPhysicsList* userPL);
155 virtual void SetUserAction(G4UserRunAction* userAction);
156 virtual void SetUserAction(G4VUserPrimaryGeneratorAction* userAction);
157 virtual void SetUserAction(G4UserEventAction* userAction);
158 virtual void SetUserAction(G4UserStackingAction* userAction);
159 virtual void SetUserAction(G4UserTrackingAction* userAction);
160 virtual void SetUserAction(G4UserSteppingAction* userAction);
161
162 // To be invoked solely from G4WorkerRunManager to merge the results
163 void MergeScores(const G4ScoringManager* localScoringManager);
164 void MergeRun(const G4Run* localRun);
165
166 // Handling of more than one run per thread
168 {
169 UNDEFINED,
170 NEXTITERATION, // There is another set of UI commands to be executed
171 PROCESSUI, // Process UI commands w/o a /run/beamOn
172 ENDWORKER // Terminate thread, work finished
173 };
174
176 // Called to force workers to request and process the UI commands stack
177 // This will block untill all workers have processed UI commands
179 // Called by workers to signal to master it has completed processing of
180 // UI commands
182 // Worker thread barrier: this method should be used by workers' run
183 // manager to wait, after an event loop for the next action to be
184 // performed (for example execute a new run).
185 // This returns the action to be performed.
186
187 inline void SetEventModulo(G4int i = 1) { eventModuloDef = i; }
188 inline G4int GetEventModulo() const { return eventModuloDef; }
189
190 virtual void AbortRun(G4bool softAbort = false);
191 virtual void AbortEvent();
192
194 static void SetSeedOncePerCommunication(G4int val);
196
197 protected:
198
199 virtual G4bool InitializeSeeds(G4int /*nevts*/) { return false; };
200 // Initialize the seeds list, if derived class does not implement this
201 // method, a default generation will be used (nevents*2 random seeds).
202 // Return true if initialization is done.
203 // Adds one seed to the list of seeds.
204
205 virtual void PrepareCommandsStack();
206 virtual void StoreRNGStatus(const G4String& filenamePrefix);
207 virtual void rndmSaveThisRun();
208 virtual void rndmSaveThisEvent();
209 virtual void CreateAndStartWorkers();
210 // Creates worker threads and signal to start
211
212 virtual void WaitForReadyWorkers();
213 // Master thread barrier: call this function to block master thread and
214 // wait workers to be ready to process work. This function will return
215 // only when all workers are ready to perform event loop.
216
217 virtual void WaitForEndEventLoopWorkers();
218 // Master thread barrier: call this function to block master thread and
219 // wait workers have finished current event loop. This function will
220 // return only when all workers have finished processing events for
221 // this run.
222
223 virtual void TerminateWorkers();
224 // Empty the workersList.
225
226 virtual void NewActionRequest(WorkerActionRequest newRequest);
227
228 virtual void RefillSeeds();
229
230 protected:
231
233 // Number of worker threads. To be set by SetNumberOfThreads() method.
234
236 // Force to use this number regardless of SetNumberOfThreads() method.
237
239
241 // Handling of master thread scoring worlds, access is needed by workers
244 // Singleton implementing master thread behavior
245
247
254 G4double* randDbl = nullptr;
255
258 // - If it is set to 0 (default), seeds that are centrally managed
259 // by G4MTRunManager are set for every event of every worker thread.
260 // This option guarantees event reproducibility regardless of number
261 // of threads.
262 // - If it is set to 1, seeds are set only once for the first
263 // event of each run of each worker thread. Event reproducibility is
264 // guaranteed only if the same number of worker threads are used.
265 // On the other hand, this option offers better computing performance
266 // in particular for applications with relatively small primary
267 // particle energy and large number of events.
268 // - If it is set to 2, seeds are set only for the first event of
269 // group of N events. This option is reserved for the future use when
270 // Geant4 will allow number of threads to be dynamically changed during
271 // an event loop.
272
273 // Barriers: synch points between master and workers
278
279 private:
280
281 using G4ThreadsList = std::list<G4Thread*>;
282 // List of workers (i.e. thread)
283
285 // Pin Affinity parameter
287 // List of workers run managers
288 // List of all workers run managers
289 std::vector<G4String> uiCmdsForWorkers;
290 // List of UI commands for workers.
292 // Pointer to the mastet thread random engine
293
295};
296
297#endif // G4MTRunManager_hh
std::queue< G4long > G4SeedsQueue
Definition: G4RNGHelper.hh:136
G4Thread::id G4ThreadId
Definition: G4Threading.hh:286
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
static G4int SeedOncePerCommunication()
virtual void SetUserAction(G4UserRunAction *userAction)
virtual void InitializeThreadPool()
virtual WorkerActionRequest ThisWorkerWaitForNextAction()
static void SetSeedOncePerCommunication(G4int val)
virtual void AbortEvent()
G4int numberOfEventToBeProcessed
virtual void ProcessOneEvent(G4int i_event)
virtual void TerminateOneEvent()
G4int GetPinAffinity() const
G4MTRunManagerKernel * MTkernel
virtual void rndmSaveThisEvent()
virtual void SetUserInitialization(G4VUserPhysicsList *userPL)
virtual G4bool InitializeSeeds(G4int)
virtual void WaitForReadyWorkers()
G4MTBarrier beginOfEventLoopBarrier
void SetEventModulo(G4int i=1)
virtual void CreateAndStartWorkers()
virtual void SetNumberOfThreads(G4int n)
virtual ~G4MTRunManager()
virtual void ThisWorkerProcessCommandsStackDone()
virtual G4int SetUpNEvents(G4Event *, G4SeedsQueue *seedsQueue, G4bool reseedRequired=true)
virtual G4bool SetUpAnEvent(G4Event *, long &s1, long &s2, long &s3, G4bool reseedRequired=true)
CLHEP::HepRandomEngine * masterRNGEngine
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
static void addWorld(G4int counter, G4VPhysicalVolume *w)
virtual void InitializeEventLoop(G4int n_event, const char *macroFile=0, G4int n_select=-1)
virtual void PrepareCommandsStack()
static G4ScoringManager * GetMasterScoringManager()
static G4MTRUN_DLL G4ScoringManager * masterScM
G4ThreadsList threads
virtual void Initialize()
static G4MTRUN_DLL G4MTRunManager * fMasterRM
virtual void ThisWorkerReady()
static G4MTRunManagerKernel * GetMTMasterRunManagerKernel()
std::vector< G4String > uiCmdsForWorkers
G4double * randDbl
static G4int seedOncePerCommunication
virtual void RunTermination()
static G4MTRUN_DLL masterWorlds_t masterWorlds
virtual G4int GetNumberOfThreads() const
virtual size_t GetNumberActiveThreads() const
virtual void ConstructScoringWorlds()
G4int GetEventModulo() const
static G4MTRunManager * GetMasterRunManager()
virtual void StoreRNGStatus(const G4String &filenamePrefix)
virtual void WaitForEndEventLoopWorkers()
std::list< G4Thread * > G4ThreadsList
WorkerActionRequest nextActionRequest
std::map< G4int, G4VPhysicalVolume * > masterWorlds_t
virtual void AbortRun(G4bool softAbort=false)
virtual void RefillSeeds()
virtual void rndmSaveThisRun()
static G4ThreadId masterThreadId
G4MTBarrier processUIBarrier
static G4ThreadId GetMasterThreadId()
void MergeRun(const G4Run *localRun)
G4MTBarrier endOfEventLoopBarrier
G4MTBarrier nextActionRequestBarrier
virtual void TerminateWorkers()
static masterWorlds_t & GetMasterWorlds()
static G4ThreadId GetMasterTheadId()
virtual void RequestWorkersProcessCommandsStack()
static G4RunManagerKernel * GetMasterRunManagerKernel()
void MergeScores(const G4ScoringManager *localScoringManager)
virtual void NewActionRequest(WorkerActionRequest newRequest)
void SetPinAffinity(G4int n=1)
std::vector< G4String > GetCommandStack()
virtual void ThisWorkerEndEventLoop()
Definition: G4Run.hh:49
#define G4MTRUN_DLL
Definition: rundefs.hh:55