Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4WorkerTaskRunManager.cc
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
29#include "G4MTRunManager.hh"
31#include "G4RNGHelper.hh"
32#include "G4Run.hh"
33#include "G4SDManager.hh"
34#include "G4ScoringManager.hh"
35#include "G4TiMemory.hh"
36#include "G4Timer.hh"
38#include "G4UImanager.hh"
39#include "G4UserRunAction.hh"
43#include "G4VScoringMesh.hh"
46#include "G4VUserPhysicsList.hh"
48#include "G4VVisManager.hh"
50#include "G4WorkerThread.hh"
51#include "G4AutoLock.hh"
53#include "G4TaskRunManager.hh"
54
55#include <fstream>
56#include <sstream>
57
58// namespace
59// {
60// G4Mutex ConstructScoringWorldsMutex;
61// }
62
63//============================================================================//
64
66{
68}
69
70//============================================================================//
71
74{
75 return static_cast<G4WorkerTaskRunManagerKernel*>(
77}
78
79//============================================================================//
80
83{}
84
85//============================================================================//
86
88{
89#ifdef G4MULTITHREADED
90 if(!visIsSetUp)
91 {
93 if(pVVis)
94 {
95 pVVis->SetUpForAThread();
96 visIsSetUp = true;
97 }
98 }
99#endif
100 runIsSeeded = false;
101
103 return;
104
105 // Signal this thread can start event loop.
106 // Note this will return only when all threads reach this point
108 if(fakeRun)
109 return;
110
111 const G4UserWorkerInitialization* uwi =
113
115 if(currentRun)
116 delete currentRun;
117
118 currentRun = nullptr;
119
122
123 // Call a user hook: this is guaranteed all threads are "synchronized"
124 if(uwi)
125 uwi->WorkerRunStart();
126
127 if(userRunAction)
129 if(!currentRun)
130 currentRun = new G4Run();
131
136
139 if(fSDM != nullptr)
140 {
142 }
143
145 {
146 auto hce = (fSDM != nullptr) ? fSDM->PrepareNewEvent() : nullptr;
148 delete hce;
149 }
150
151 std::ostringstream oss;
152 G4Random::saveFullState(oss);
155
156 for(G4int i_prev = 0; i_prev < n_perviousEventsToBeStored; ++i_prev)
157 previousEvents->push_back(nullptr);
158
159 if(printModulo > 0 || verboseLevel > 0)
160 {
161 G4cout << "### Run " << currentRun->GetRunID()
162 << " starts on worker thread " << G4Threading::G4GetThreadId() << "."
163 << G4endl;
164 }
165
166 if(userRunAction)
168
169#if defined(GEANT4_USE_TIMEMORY)
170 workerRunProfiler.reset(new ProfilerConfig(currentRun));
171#endif
172
174 {
176 }
177
179 {
180 G4String fileN = "currentRun";
182 {
183 std::ostringstream os;
184 os << "run" << currentRun->GetRunID();
185 fileN = os.str();
186 }
187 StoreRNGStatus(fileN);
188 }
189
190 runAborted = false;
192}
193
194//============================================================================//
195
196void G4WorkerTaskRunManager::DoEventLoop(G4int n_event, const char* macroFile,
197 G4int n_select)
198{
200 {
201 G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
202 "G4VUserPrimaryGeneratorAction is not defined!");
203 }
204
205 // This is the same as in the sequential case, just the for-loop indexes are
206 // different
207 InitializeEventLoop(n_event, macroFile, n_select);
208
209 // Reset random number seeds queue
210 while(seedsQueue.size() > 0)
211 seedsQueue.pop();
212 // for each run, worker should receive at least one set of random number
213 // seeds.
214 // runIsSeeded = false;
215
216 // Event loop
217 eventLoopOnGoing = true;
218 G4int i_event = -1;
219 nevModulo = -1;
220 currEvID = -1;
221
222 for(G4int evt = 0; evt < n_event; ++evt)
223 {
224 ProcessOneEvent(i_event);
226 {
228 if(runAborted)
229 eventLoopOnGoing = false;
230 }
232 break;
233 }
234
235 // TerminateEventLoop();
236}
237
238//============================================================================//
239
241{
242 currentEvent = GenerateEvent(i_event);
244 {
249 {
250 G4cout << "Applying command \"" << msgText << "\" @ " << __FUNCTION__
251 << ":" << __LINE__ << G4endl;
253 }
254 }
255}
256
257//============================================================================//
258
260{
261 G4Event* anEvent = new G4Event(i_event);
262 long s1 = 0;
263 long s2 = 0;
264 long s3 = 0;
265 G4bool eventHasToBeSeeded = true;
267 eventHasToBeSeeded = false;
268
269 if(i_event < 0)
270 {
272 if(nevM == 1)
273 {
275 anEvent, s1, s2, s3, eventHasToBeSeeded);
276 runIsSeeded = true;
277 }
278 else
279 {
280 if(nevModulo <= 0)
281 {
283 anEvent, &seedsQueue, eventHasToBeSeeded);
284 if(nevToDo == 0)
285 eventLoopOnGoing = false;
286 else
287 {
288 currEvID = anEvent->GetEventID();
289 nevModulo = nevToDo - 1;
290 }
291 }
292 else
293 {
295 eventHasToBeSeeded = false;
296 anEvent->SetEventID(++currEvID);
297 nevModulo--;
298 }
299 if(eventLoopOnGoing && eventHasToBeSeeded)
300 {
301 s1 = seedsQueue.front();
302 seedsQueue.pop();
303 s2 = seedsQueue.front();
304 seedsQueue.pop();
305 }
306 }
307
309 {
310 delete anEvent;
311 return nullptr;
312 }
313 }
314 else if(eventHasToBeSeeded)
315 {
316 // Need to reseed random number generator
318 s1 = helper->GetSeed(i_event * 2);
319 s2 = helper->GetSeed(i_event * 2 + 1);
320 }
321
322 if(eventHasToBeSeeded)
323 {
324 long seeds[3] = { s1, s2, 0 };
325 G4Random::setTheSeeds(seeds, -1);
326 runIsSeeded = true;
327 ////G4cout<<"Event "<<currEvID<<" is seeded with { "<<s1<<", "<<s2<<"
328 ///}"<<G4endl;
329 }
330
331 // Read from file seed.
332 // Andrea Dotti 4 November 2015
333 // This is required for strong-reproducibility, in MT mode we have that each
334 // thread produces, for each event a status file, we want to do that.
335 // Search a random file with the format run{%d}evt{%d}.rndm
336
337 // This is the filename base constructed from run and event
338 const auto filename = [&] {
339 std::ostringstream os;
340 os << "run" << currentRun->GetRunID() << "evt" << anEvent->GetEventID();
341 return os.str();
342 };
343
344 G4bool RNGstatusReadFromFile = false;
346 {
347 // Build full path of RNG status file for this event
348 std::ostringstream os;
349 os << filename() << ".rndm";
350 const G4String& randomStatusFile = os.str();
351 std::ifstream ifile(randomStatusFile.c_str());
352 if(ifile)
353 {
354 // File valid and readable
355 RNGstatusReadFromFile = true;
356 G4Random::restoreEngineStatus(randomStatusFile.c_str());
357 }
358 }
359
362 {
363 std::ostringstream oss;
364 G4Random::saveFullState(oss);
367 }
368
369 if(storeRandomNumberStatus && !RNGstatusReadFromFile)
370 {
371 // If reading from file, avoid to rewrite the same
372 G4String fileN = "currentEvent";
374 fileN = filename();
375 StoreRNGStatus(fileN);
376 }
377
378 if(printModulo > 0 && anEvent->GetEventID() % printModulo == 0)
379 {
380 G4cout << "--> Event " << anEvent->GetEventID() << " starts";
381 if(eventHasToBeSeeded)
382 G4cout << " with initial seeds (" << s1 << "," << s2 << ")";
383 G4cout << "." << G4endl;
384 }
386 return anEvent;
387}
388
389//============================================================================//
390
392{
393 if(!fakeRun && currentRun)
394 {
395#if defined(GEANT4_USE_TIMEMORY)
396 workerRunProfiler.reset();
397#endif
399
400 // Call a user hook: note this is before the next barrier
401 // so threads execute this method asyncrhonouzly
402 //(TerminateRun allows for synch via G4RunAction::EndOfRun)
403 const G4UserWorkerInitialization* uwi =
405 if(uwi)
406 uwi->WorkerRunEnd();
407 }
408
409 if(currentRun)
410 {
412 }
413 // Signal this thread has finished envent-loop.
414 // Note this will return only whan all threads reach this point
416}
417
418//============================================================================//
419
421{
422 if(verboseLevel > 0 && !fakeRun)
423 {
424 timer->Stop();
425 // prefix with thread # info due to how TBB calls this function
427 "[thread " + std::to_string(workerContext->GetThreadId()) + "] ";
428 G4cout << prefix << "Thread-local run terminated." << G4endl;
429 G4cout << prefix << "Run Summary" << G4endl;
430 if(runAborted)
431 G4cout << prefix << " Run Aborted after " << numberOfEventProcessed
432 << " events processed." << G4endl;
433 else
434 G4cout << prefix
435 << " Number of events processed : " << numberOfEventProcessed
436 << G4endl;
437 G4cout << prefix << " " << *timer << G4endl;
438 }
439}
440
441//============================================================================//
442
443void G4WorkerTaskRunManager::SetupDefaultRNGEngine()
444{
445 const CLHEP::HepRandomEngine* mrnge =
447 assert(mrnge); // Master has created RNG
450 uwti->SetupRNGEngine(mrnge);
451}
452
453//============================================================================//
454
456{
457 std::ostringstream os;
458 os << randomNumberStatusDir << "G4Worker" << workerContext->GetThreadId()
459 << "_" << fn << ".rndm";
460 G4Random::saveEngineStatus(os.str().c_str());
461}
462
463//============================================================================//
464
466{
468 if(!mrm)
469 return;
470
471 //------------------------------------------------------------------------//
472 // Check UI commands not already processed
473 auto command_stack = mrm->GetCommandStack();
474 bool matching = (command_stack.size() == processedCommandStack.size());
475 if(matching)
476 {
477 for(uintmax_t i = 0; i < command_stack.size(); ++i)
478 if(processedCommandStack.at(i) != command_stack.at(i))
479 {
480 matching = false;
481 break;
482 }
483 }
484
485 //------------------------------------------------------------------------//
486 // Execute UI commands stored in the master UI manager
487 if(!matching)
488 {
489 for(const auto& itr : command_stack)
491 processedCommandStack = command_stack;
492 }
493}
494
495//============================================================================//
496
498{
500 if(currentRun)
501 delete currentRun;
502 currentRun = nullptr;
503}
504
505//============================================================================//
506
508{
510 G4bool newRun = false;
511 const G4Run* run = mrm->GetCurrentRun();
512 G4ThreadLocalStatic G4int runId = -1;
513 if(run && run->GetRunID() != runId)
514 {
515 runId = run->GetRunID();
516 newRun = true;
517 if(runId > 0)
518 {
519 ProcessUI();
520 assert(workerContext != nullptr);
521 }
523 }
524
525 // Start this run
527 G4int numSelect = mrm->GetNumberOfSelectEvents();
528 G4String macroFile = mrm->GetSelectMacro();
529 bool empty_macro = (macroFile == "" || macroFile == " ");
530
531 const char* macro = (empty_macro) ? nullptr : macroFile.c_str();
532 numSelect = (empty_macro) ? -1 : numSelect;
533
534 if(newRun)
535 {
537 if(cond)
538 {
541 }
542 }
543 DoEventLoop(nevts, macro, numSelect);
544}
545
546//============================================================================//
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void ProcessOneEvent(G4Event *anEvent)
void SetRandomNumberStatus(G4String &st)
Definition: G4Event.hh:90
G4int GetEventID() const
Definition: G4Event.hh:118
void SetEventID(G4int i)
Definition: G4Event.hh:80
static G4int SeedOncePerCommunication()
virtual G4int SetUpNEvents(G4Event *, G4SeedsQueue *seedsQueue, G4bool reseedRequired=true)
virtual G4bool SetUpAnEvent(G4Event *, long &s1, long &s2, long &s3, G4bool reseedRequired=true)
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
virtual void ThisWorkerReady()
G4int GetEventModulo() const
static G4MTRunManager * GetMasterRunManager()
std::vector< G4String > GetCommandStack()
virtual void ThisWorkerEndEventLoop()
static G4ParallelWorldProcessStore * GetInstance()
G4bool RunInitialization(G4bool fakeRun=false)
G4bool isScoreNtupleWriter
void CleanUpPreviousEvents()
G4int storeRandomNumberStatusToG4Event
const G4UserWorkerInitialization * GetUserWorkerInitialization() const
std::list< G4Event * > * previousEvents
G4Timer * timer
G4int n_select_msg
G4int numberOfEventProcessed
G4int GetNumberOfEventsToBeProcessed() const
virtual void InitializeEventLoop(G4int n_event, const char *macroFile=nullptr, G4int n_select=-1)
G4int runIDCounter
G4RunManagerKernel * kernel
G4int verboseLevel
G4Run * currentRun
virtual G4bool ConfirmBeamOnCondition()
static G4RunManager * GetRunManager()
G4DCtable * DCtable
G4String randomNumberStatusForThisRun
G4bool runAborted
G4String msgText
static G4bool IfGeometryHasBeenDestroyed()
G4UserRunAction * userRunAction
G4bool rngStatusEventsFlag
virtual void RunTermination()
const G4String & GetSelectMacro() const
G4VUserPrimaryGeneratorAction * userPrimaryGeneratorAction
const G4Run * GetCurrentRun() const
G4int numberOfEventToBeProcessed
G4String randomNumberStatusDir
G4String randomNumberStatusForThisEvent
const G4UserWorkerThreadInitialization * GetUserWorkerThreadInitialization() const
G4int n_perviousEventsToBeStored
G4bool storeRandomNumberStatus
G4EventManager * eventManager
virtual void TerminateOneEvent()
G4int GetNumberOfSelectEvents() const
virtual void AnalyzeEvent(G4Event *anEvent)
void UpdateScoring()
G4Event * currentEvent
Definition: G4Run.hh:49
void SetHCtable(G4HCtable *HCtbl)
Definition: G4Run.hh:107
G4int GetRunID() const
Definition: G4Run.hh:78
void SetNumberOfEventToBeProcessed(G4int n_ev)
Definition: G4Run.hh:103
void SetRunID(G4int id)
Definition: G4Run.hh:102
void SetDCtable(G4DCtable *DCtbl)
Definition: G4Run.hh:108
void SetRandomNumberStatus(G4String &st)
Definition: G4Run.hh:109
G4HCofThisEvent * PrepareNewEvent()
Definition: G4SDManager.cc:113
static G4SDManager * GetSDMpointerIfExist()
Definition: G4SDManager.cc:47
G4HCtable * GetHCtable() const
Definition: G4SDManager.hh:101
static G4TaskRunManager * GetMasterRunManager()
static G4TemplateRNGHelper< T > * GetInstance()
Definition: G4RNGHelper.cc:42
virtual const T GetSeed(const G4int &sdId)
Definition: G4RNGHelper.hh:64
void Stop()
G4int ApplyCommand(const char *aCommand)
Definition: G4UImanager.cc:495
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:77
virtual void BeginOfRunAction(const G4Run *aRun)
virtual G4Run * GenerateRun()
virtual void SetupRNGEngine(const CLHEP::HepRandomEngine *aRNGEngine) const
virtual G4bool Book(G4HCofThisEvent *hce)=0
static G4VScoreNtupleWriter * Instance()
virtual void OpenFile()=0
virtual void GeneratePrimaries(G4Event *anEvent)=0
static G4VVisManager * GetConcreteInstance()
virtual void ConstructScoringWorlds()
virtual void MergePartialResults()
G4WorkerThread * workerContext
virtual void DoEventLoop(G4int n_event, const char *macroFile=nullptr, G4int n_select=-1) override
virtual G4Event * GenerateEvent(G4int i_event) override
virtual void StoreRNGStatus(const G4String &filenamePrefix) override
virtual void RunTermination() override
virtual void TerminateEventLoop() override
virtual void DoWork() override
G4ProfilerConfig< G4ProfileType::Run > ProfilerConfig
virtual void ProcessOneEvent(G4int i_event) override
static G4WorkerTaskRunManagerKernel * GetWorkerRunManagerKernel()
virtual void RunInitialization() override
static G4WorkerTaskRunManager * GetWorkerRunManager()
G4int GetThreadId() const
static void UpdateGeometryAndPhysicsVectorFromMaster()
G4int G4GetThreadId()
Definition: G4Threading.cc:122
#define G4ThreadLocalStatic
Definition: tls.hh:76