Geant4  10.03
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 //
27 // class description:
28 // This is a class for run control in GEANT4 for multi-threaded runs
29 // It extends G4RunManager re-implementing multi-threaded behavior in
30 // key methods. See documentation for G4RunManager
31 // Users initializes an instance of this class instead of G4RunManager
32 // to start a multi-threaded simulation.
33 
34 #ifndef G4MTRunManager_h
35 #define G4MTRunManager_h 1
36 
37 #include "G4RunManager.hh"
38 #include "G4Threading.hh"
39 #include "G4RNGHelper.hh"
40 #include "G4MTBarrier.hh"
41 #include <list>
42 #include <map>
43 
45 class G4ScoringManager;
48 
49 //TODO: Split random number storage from this class
50 
51 class G4MTRunManager : public G4RunManager {
52 public:
54  virtual ~G4MTRunManager();
55  //New method
56  void SetNumberOfThreads( G4int n );
57  G4int GetNumberOfThreads() const { return nworkers; }
58  void SetPinAffinity(G4int n=1);
59  G4int GetPinAffinity() const { return pinAffinity; }
60 public:
61 
62  //Inherited methods to re-implement for MT case
63  virtual void Initialize();
64  virtual void InitializeEventLoop(G4int n_event, const char* macroFile=0, G4int n_select=-1);
65 
66  //The following do not do anything for this runmanager
67  virtual void TerminateOneEvent();
68  virtual void ProcessOneEvent(G4int i_event);
70  virtual void ConstructScoringWorlds();
71  virtual void RunTermination();
72 
73  //The following method should be invoked by G4WorkerRunManager for each event.
74  //False is returned if no more event to be processed.
75  // Note: G4Event object must be instantiated by a worker thread. In case no more
76  // event remains to be processed, that worker thread must delete that G4Event
77  // object. If a worker runs with its own random number sequence, the boolean flag
78  // reseedRequired should be set to false. This is *NOT* allowed for the first event.
79  virtual G4bool SetUpAnEvent(G4Event*, long& s1, long& s2, long& s3, G4bool reseedRequired=true);
80  // Same as above method, but the seeds are set only once over "eventModulo" events.
81  // The return value shows the number of events the caller Worker has to process
82  // (between 1 and eventModulo depending on number of events yet to be processed).
83  // G4Event object has the event ID of the first event of this bunch.
84  // If zero is returned no more event needs to be processed, and worker thread
85  // must delete that G4Event.
86  virtual G4int SetUpNEvents(G4Event*, G4SeedsQueue* seedsQueue, G4bool reseedRequired=true);
87 
88  //Method called by Initialize() method
89 protected:
90  //Initialize the seeds list, if derived class does not implement this method
91  //A default generation will be used (nevents*2 random seeds)
92  //Return true if initialization is done.
93  virtual G4bool InitializeSeeds( G4int /*nevts*/) { return false; };
94  //Adds one seed to the list of seeds
95  virtual void PrepareCommandsStack();
96  virtual void StoreRNGStatus(const G4String& filenamePrefix );
97  virtual void CreateAndStartWorkers();
98  //Creates worker threads and signal to start
99 public:
100  std::vector<G4String> GetCommandStack();
101  //This method is invoked just before spawning the threads to
102  //collect from UI managere the list of commands that threads
103  //will execute.
104  size_t GetNumberActiveThreads() const { return threads.size(); }
105  //Returns number of currently active threads.
106  //This number may be different from the number of threads currently
107  //in running state (e.g. the number returned by:
108  //G4Threading::GetNumberOfActiveWorkerThreads() method).
109 private:
110  // Number of worker threads. To be set by SetNumberOfThreads() method.
112  // Force to use this number regardless of SetNumberOfThreads() method.
114  // Pin Affinity parameter
116 
117  //List of workers (i.e. thread)
118  typedef std::list<G4Thread*> G4ThreadsList;
119  G4ThreadsList threads;
120  //List of workers run managers
121  //List of all workers run managers
122  std::vector<G4String> uiCmdsForWorkers;
123  //List of UI commands for workers.
124  CLHEP::HepRandomEngine* masterRNGEngine;
125  //Pointer to the mastet thread random engine
126 protected:
127  virtual void WaitForReadyWorkers();
128  //Master thread barrier:
129  //Call this function to block master thread and
130  //wait workers to be ready to process work.
131  //This function will return only when all
132  //workers are ready to perform event loop.
133  virtual void WaitForEndEventLoopWorkers();
134  //Master thread barrier:
135  //Call this function to block master thread and
136  //wait workers have finished current event loop.
137  //This function will return only when all
138  //workers have finished processing events for this run.
139 protected:
141  virtual void TerminateWorkers();
142  //Empty the workersList
143 
144 public:
145  virtual void ThisWorkerReady();
146  //Worker threads barrier:
147  //This method should be called by each
148  //worker when ready to start thread event-loop
149  //This method will return only when all workers
150  //are ready.
151  //static void ThisWorkerFinishWork();
152  //Worker threads barrier:
153  //This static method should be called by each
154  //worker when finish to process events
155  virtual void ThisWorkerEndEventLoop();
156  //Worker threads barrier:
157  //This method should be called by each
158  //worker when worker event loop is terminated.
159  typedef std::map<G4int,G4VPhysicalVolume*> masterWorlds_t;
161  static masterWorlds_t& GetMasterWorlds() { return masterWorlds; }
162  static void addWorld( G4int counter, G4VPhysicalVolume* w) { masterWorlds.insert( std::make_pair(counter,w) ); }
163  const CLHEP::HepRandomEngine* getMasterRandomEngine() const { return masterRNGEngine; }
164 private:
165  //Handling of master thread scoring worlds, access to it is needed by workers
167  static masterWorlds_t masterWorlds;
168  //Singleton implementing master thread behavior
171 public: // with description
173  // Returns the singleton instance of the run manager common to all threads implementing
174  // the master behavior
177  // Returns the singleton instance of the run manager kernel common to all threads
178 
179  virtual void SetUserInitialization(G4VUserPhysicsList* userPL);
181  virtual void SetUserInitialization(G4UserWorkerInitialization* userInit);
183  virtual void SetUserInitialization(G4VUserActionInitialization* userInit);
184  virtual void SetUserAction(G4UserRunAction* userAction);
185  virtual void SetUserAction(G4VUserPrimaryGeneratorAction* userAction);
186  virtual void SetUserAction(G4UserEventAction* userAction);
187  virtual void SetUserAction(G4UserStackingAction* userAction);
188  virtual void SetUserAction(G4UserTrackingAction* userAction);
189  virtual void SetUserAction(G4UserSteppingAction* userAction);
190 
191 public:
192  // To be invoked solely from G4WorkerRunManager to merge the results
193  void MergeScores(const G4ScoringManager* localScoringManager);
194  void MergeRun(const G4Run* localRun);
195 
196 public:
197  //Handling of more than one run per thread
198  enum class WorkerActionRequest {
199  UNDEFINED ,
200  NEXTITERATION , // There is another set of UI commands to be executed
201  PROCESSUI, // Process UI commands w/o a /run/beamOn
202  ENDWORKER // Terminate thread, work finished
203  };
204  virtual void RequestWorkersProcessCommandsStack();
205  //Called to force workers to request and process the UI commands stack
206  //This will block untill all workers have processed UI commands
207  virtual void ThisWorkerProcessCommandsStackDone();
208  //Called by workers to signal to master it has completed processing of
209  //UI commands
211  //Worker thread barrier
212  //This method should be used by workers' run manager to wait,
213  //after an event loop for the next action to be performed
214  // (for example execute a new run)
215  //This returns the action to be performed
216 protected:
218  virtual void NewActionRequest( WorkerActionRequest newRequest );
219 
220 protected:
227  double* randDbl;
228 
229  void RefillSeeds();
230 
231 public:
232  inline void SetEventModulo(G4int i=1) { eventModuloDef = i; }
233  inline G4int GetEventModulo() const { return eventModuloDef; }
234 
235 public:
236  virtual void AbortRun(G4bool softAbort=false);
237  virtual void AbortEvent();
238 
239 protected:
241  // - If it is set to 0 (default), seeds that are centrally managed
242  // by G4MTRunManager are set for every event of every worker thread.
243  // This option guarantees event reproducability regardless of number
244  // of threads.
245  // - If it is set to 1, seeds are set only once for the first
246  // event of each run of each worker thread. Event reproducability is
247  // guaranteed only if the same number of worker threads are used.
248  // On the other hand, this option offers better computing performance
249  // in particular for applications with relatively small primary
250  // particle energy and large number of events.
251  // - If it is set to 2, seeds are set only for the first event of
252  // group of N events. This option is reserved for the future use when
253  // Geant4 allows number of threads to be dynatically changed during an
254  // event loop.
255 public:
257  static void SetSeedOncePerCommunication(G4int val) { seedOncePerCommunication = val; }
258 protected:
259  //Barriers: synch points between master and workers
264 };
265 
266 #endif //G4MTRunManager_h
virtual void InitializeEventLoop(G4int n_event, const char *macroFile=0, G4int n_select=-1)
virtual G4int SetUpNEvents(G4Event *, G4SeedsQueue *seedsQueue, G4bool reseedRequired=true)
std::vector< G4String > GetCommandStack()
virtual void PrepareCommandsStack()
std::queue< G4long > G4SeedsQueue
Definition: G4RNGHelper.hh:132
std::map< G4int, G4VPhysicalVolume * > masterWorlds_t
static G4int seedOncePerCommunication
std::vector< G4String > uiCmdsForWorkers
static void addWorld(G4int counter, G4VPhysicalVolume *w)
WorkerActionRequest nextActionRequest
virtual void ThisWorkerEndEventLoop()
void SetNumberOfThreads(G4int n)
virtual G4bool InitializeSeeds(G4int)
void SetEventModulo(G4int i=1)
static masterWorlds_t & GetMasterWorlds()
virtual void ConstructScoringWorlds()
virtual void RunTermination()
int G4int
Definition: G4Types.hh:78
virtual void SetUserAction(G4UserRunAction *userAction)
G4MTBarrier beginOfEventLoopBarrier
virtual void WaitForEndEventLoopWorkers()
G4MTRunManagerKernel * MTkernel
virtual void TerminateOneEvent()
virtual void TerminateWorkers()
static G4RunManagerKernel * GetMasterRunManagerKernel()
G4ThreadsList threads
void MergeRun(const G4Run *localRun)
static masterWorlds_t masterWorlds
static G4ScoringManager * masterScM
G4MTBarrier processUIBarrier
virtual void ProcessOneEvent(G4int i_event)
bool G4bool
Definition: G4Types.hh:79
virtual void WaitForReadyWorkers()
static G4MTRunManager * GetMasterRunManager()
void SetPinAffinity(G4int n=1)
virtual WorkerActionRequest ThisWorkerWaitForNextAction()
virtual void ThisWorkerProcessCommandsStackDone()
Definition: G4Run.hh:46
virtual void SetUserInitialization(G4VUserPhysicsList *userPL)
G4int GetPinAffinity() const
G4int GetNumberOfThreads() const
virtual void AbortRun(G4bool softAbort=false)
virtual void RequestWorkersProcessCommandsStack()
virtual void NewActionRequest(WorkerActionRequest newRequest)
const G4int n
std::list< G4Thread * > G4ThreadsList
virtual void Initialize()
static G4ScoringManager * GetMasterScoringManager()
G4MTBarrier endOfEventLoopBarrier
virtual void ThisWorkerReady()
virtual void AbortEvent()
virtual G4bool SetUpAnEvent(G4Event *, long &s1, long &s2, long &s3, G4bool reseedRequired=true)
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
G4int GetEventModulo() const
virtual ~G4MTRunManager()
static G4int SeedOncePerCommunication()
G4int numberOfEventToBeProcessed
static G4MTRunManagerKernel * GetMTMasterRunManagerKernel()
G4MTBarrier nextActionRequestBarrier
size_t GetNumberActiveThreads() const
static void SetSeedOncePerCommunication(G4int val)
void MergeScores(const G4ScoringManager *localScoringManager)
CLHEP::HepRandomEngine * masterRNGEngine
virtual void StoreRNGStatus(const G4String &filenamePrefix)
virtual void CreateAndStartWorkers()
static G4MTRunManager * fMasterRM