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