Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/include/G4MTRunManager.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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