Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/include/G4TaskRunManager.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 // Author: Jonathan Madsen (May 28st 2020)
 27 //
 28 // class description:
 29 //   This is a class for run control in GEANT4 for multi-threaded runs
 30 //   It extends G4RunManager re-implementing multi-threaded behavior in
 31 //   key methods. See documentation for G4RunManager
 32 //   Users initializes an instance of this class instead of G4RunManager
 33 //   to start a multi-threaded simulation.
 34 
 35 #ifndef G4TaskRunManager_hh
 36 #define G4TaskRunManager_hh 1
 37 
 38 #include "G4EnvironmentUtils.hh"
 39 #include "G4MTBarrier.hh"
 40 #include "G4MTRunManager.hh"
 41 #include "G4RNGHelper.hh"
 42 #include "G4RunManager.hh"
 43 #include "G4TBBTaskGroup.hh"
 44 #include "G4TaskGroup.hh"
 45 #include "G4TaskManager.hh"
 46 #include "G4ThreadPool.hh"
 47 #include "G4Threading.hh"
 48 #include "G4VUserTaskQueue.hh"
 49 
 50 #include "PTL/TaskRunManager.hh"
 51 #include "rundefs.hh"
 52 
 53 #include <list>
 54 #include <map>
 55 
 56 class G4TaskRunManagerKernel;
 57 class G4ScoringManager;
 58 class G4UserTaskInitialization;
 59 class G4UserTaskThreadInitialization;
 60 class G4WorkerTaskRunManager;
 61 class G4RunManagerFactory;
 62 
 63 //============================================================================//
 64 
 65 class G4TaskRunManager : public G4MTRunManager, public PTL::TaskRunManager
 66 {
 67     friend class G4RunManagerFactory;
 68 
 69   public:
 70     using InitializeSeedsCallback = std::function<G4bool(G4int, G4int&, G4int&)>;
 71     using RunTaskGroup = G4TaskGroup<void>;
 72 
 73   public:
 74     // Returns the singleton instance of the run manager common to all threads
 75     // implementing the master behavior
 76     static G4TaskRunManager* GetMasterRunManager()
 77     {
 78       auto* _rm = G4MTRunManager::GetMasterRunManager();
 79       return dynamic_cast<G4TaskRunManager*>(_rm);
 80     }
 81 
 82     // Returns the singleton instance of the run manager kernel common to all
 83     // threads
 84     static G4TaskRunManagerKernel* GetMTMasterRunManagerKernel();
 85 
 86     // Parameters:
 87     //      taskQueue     : provide a custom task queue
 88     //      useTBB        : only relevant if GEANT4_USE_TBB defined
 89     //      evtGrainsize  : the number of events per task
 90     G4TaskRunManager(G4bool useTBB = G4GetEnv<G4bool>("G4USE_TBB", false));
 91     G4TaskRunManager(G4VUserTaskQueue* taskQueue,
 92                      G4bool useTBB = G4GetEnv<G4bool>("G4USE_TBB", false), G4int evtGrainsize = 0);
 93     ~G4TaskRunManager() override;
 94 
 95     void SetGrainsize(G4int n) { eventGrainsize = n; }
 96     G4int GetGrainsize() const { return eventGrainsize; }
 97     inline G4int GetNumberOfTasks() const { return numberOfTasks; }
 98     inline G4int GetNumberOfEventsPerTask() const { return numberOfEventsPerTask; }
 99 
100     void SetNumberOfThreads(G4int n) override;
101     G4int GetNumberOfThreads() const override;
102     size_t GetNumberActiveThreads() const override
103     {
104       return PTL::TaskRunManager::GetNumberActiveThreads();
105     }
106     static G4ThreadId GetMasterThreadId();
107 
108     // Inherited methods to re-implement for MT case
109     void Initialize() override;
110     void InitializeEventLoop(G4int n_event, const char* macroFile = nullptr,
111                              G4int n_select = -1) override;
112     void InitializeThreadPool() override;
113     G4bool ThreadPoolIsInitialized() const { return poolInitialized; }
114 
115     void Initialize(uint64_t nthreads) override { PTL::TaskRunManager::Initialize(nthreads); }
116 
117     void TerminateOneEvent() override;
118     void ProcessOneEvent(G4int i_event) override;
119     void ConstructScoringWorlds() override;
120     void RunTermination() override;
121 
122     // The following method should be invoked by G4WorkerTaskRunManager for each
123     // event. False is returned if no more event to be processed. Note: G4Event
124     // object must be instantiated by a worker thread. In case no more
125     //  event remains to be processed, that worker thread must delete that G4Event
126     //  object. If a worker runs with its own random number sequence, the Boolean
127     //  flag reseedRequired should be set to false. This is *NOT* allowed for the
128     //  first event.
129     G4bool SetUpAnEvent(G4Event*, G4long& s1, G4long& s2, G4long& s3,
130                         G4bool reseedRequired = true) override;
131 
132     // Same as above method, but the seeds are set only once over "eventModulo"
133     // events. The return value shows the number of events the caller Worker has
134     // to process (between 1 and eventModulo depending on number of events yet to
135     // be processed). G4Event object has the event ID of the first event of this
136     // bunch. If zero is returned no more event needs to be processed, and worker
137     // thread must delete that G4Event.
138     G4int SetUpNEvents(G4Event*, G4SeedsQueue* seedsQueue, G4bool reseedRequired = true) override;
139 
140     // To be invoked solely from G4WorkerTaskRunManager to merge the results
141     void MergeScores(const G4ScoringManager* localScoringManager) override;
142     void MergeRun(const G4Run* localRun) override;
143 
144     // Called to force workers to request and process the UI commands stack
145     // This will block untill all workers have processed UI commands
146     void RequestWorkersProcessCommandsStack() override;
147 
148     // Called by workers to signal to master it has completed processing of
149     // UI commands
150     // virtual WorkerActionRequest ThisWorkerWaitForNextAction();
151     // Worker thread barrier
152     // This method should be used by workers' run manager to wait,
153     // after an event loop for the next action to be performed
154     // (for example execute a new run)
155     // This returns the action to be performed
156     void ThisWorkerProcessCommandsStackDone() override;
157 
158     void WaitForReadyWorkers() override {}
159     void WaitForEndEventLoopWorkers() override;
160     void ThisWorkerReady() override {}
161     void ThisWorkerEndEventLoop() override {}
162 
163     WorkerActionRequest ThisWorkerWaitForNextAction() override
164     {
165       return WorkerActionRequest::UNDEFINED;
166     }
167 
168     inline void SetInitializeSeedsCallback(InitializeSeedsCallback f) { initSeedsCallback = f; }
169 
170     void AbortRun(G4bool softAbort = false) override;
171     void AbortEvent() override;
172 
173   protected:
174     virtual void ComputeNumberOfTasks();
175 
176     // Initialize the seeds list, if derived class does not implement this method
177     // A default generation will be used (nevents*2 random seeds)
178     // Return true if initialization is done.
179     G4bool InitializeSeeds(G4int /*nevts*/) override { return false; }
180 
181     // Adds one seed to the list of seeds
182     void RefillSeeds() override;
183     void StoreRNGStatus(const G4String& filenamePrefix) override;
184 
185     // Creates worker threads and signal to start
186     void CreateAndStartWorkers() override;
187 
188     void TerminateWorkers() override;
189     void NewActionRequest(WorkerActionRequest) override {}
190     virtual void AddEventTask(G4int);
191 
192   protected:
193     // Barriers: synch points between master and workers
194     RunTaskGroup* workTaskGroup = nullptr;
195 
196     // aliases to inherited member values
197     G4bool& poolInitialized = PTL::TaskRunManager::m_is_initialized;
198     G4ThreadPool*& threadPool = PTL::TaskRunManager::m_thread_pool;
199     G4VUserTaskQueue*& taskQueue = PTL::TaskRunManager::m_task_queue;
200     G4TaskManager*& taskManager = PTL::TaskRunManager::m_task_manager;
201 
202     InitializeSeedsCallback initSeedsCallback = [](G4int, G4int&, G4int&) {
203       return false;
204     };
205 
206   protected:
207     // grainsize
208     G4bool workersStarted = false;
209     G4int eventGrainsize = 0;
210     G4int numberOfEventsPerTask = -1;
211     G4int numberOfTasks = -1;
212     CLHEP::HepRandomEngine* masterRNGEngine = nullptr;
213     // Pointer to the master thread random engine
214     G4TaskRunManagerKernel* MTkernel = nullptr;
215 };
216 
217 #endif  // G4TaskRunManager_hh
218