Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4WorkerSubEvtRunManager.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
30#include "G4AutoLock.hh"
31#include "G4MTRunManager.hh"
34#include "G4RNGHelper.hh"
35#include "G4Run.hh"
36#include "G4SDManager.hh"
37#include "G4ScoringManager.hh"
38#include "G4SubEvtRunManager.hh"
39#include "G4Timer.hh"
41#include "G4UImanager.hh"
42#include "G4UserRunAction.hh"
46#include "G4VScoringMesh.hh"
49#include "G4VUserPhysicsList.hh"
51#include "G4VVisManager.hh"
53#include "G4WorkerThread.hh"
54
55#include <fstream>
56#include <sstream>
57
58//============================================================================//
59
64
65//============================================================================//
66
71
72//============================================================================//
73
79
81{
82#ifdef G4MULTITHREADED
83 if (!visIsSetUp) {
85 if (pVVis != nullptr) {
86 pVVis->SetUpForAThread();
87 visIsSetUp = true;
88 }
89 }
90#endif
91 runIsSeeded = false;
92
93 if (!(kernel->RunInitialization(fakeRun))) return;
94
95 // Signal this thread can start event loop.
96 // Note this will return only when all threads reach this point
98 if (fakeRun) return;
99
100 const G4UserWorkerInitialization* uwi =
102
104
105 delete currentRun;
106
107 currentRun = nullptr;
108
110
111 // Call a user hook: this is guaranteed all threads are "synchronized"
112 if (uwi != nullptr) uwi->WorkerRunStart();
113
114 if (userRunAction != nullptr) currentRun = userRunAction->GenerateRun();
115 if (currentRun == nullptr) currentRun = new G4Run();
116
117 currentRun->SetRunID(runIDCounter);
120 currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
121
122 currentRun->SetDCtable(DCtable);
124 if (fSDM != nullptr) {
125 currentRun->SetHCtable(fSDM->GetHCtable());
126 }
127
128 if (G4VScoreNtupleWriter::Instance() != nullptr) {
129 auto hce = (fSDM != nullptr) ? fSDM->PrepareNewEvent() : nullptr;
131 delete hce;
132 }
133
134 std::ostringstream oss;
135 G4Random::saveFullState(oss);
137 currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
138
139 for (G4int i_prev = 0; i_prev < n_perviousEventsToBeStored; ++i_prev)
140 previousEvents->push_back(nullptr);
141
142 if (printModulo > 0 || verboseLevel > 0) {
143 G4cout << "### Run " << currentRun->GetRunID() << " starts on worker thread "
144 << G4Threading::G4GetThreadId() << "." << G4endl;
145 }
146
147 if (userRunAction != nullptr) userRunAction->BeginOfRunAction(currentRun);
148
151 }
152
154 G4String fileN = "currentRun";
156 std::ostringstream os;
157 os << "run" << currentRun->GetRunID();
158 fileN = os.str();
159 }
160 StoreRNGStatus(fileN);
161 }
162
163 runAborted = false;
165 if(verboseLevel > 0) timer->Start();
166}
167
168//============================================================================//
169
170void G4WorkerSubEvtRunManager::DoEventLoop(G4int /*n_event*/, const char* /*macroFile*/,
171 G4int /*n_select*/)
172{
173 // This method is not used in worker sub-event mode
174 G4Exception("G4WorkerSubEvtRunManager::DoEventLoop()","SubEvtXXX001",FatalException,
175 "This method is not used in the worker thread of sub-event parallel mode");
176}
177
178//============================================================================//
179
181{
182 // This method is not used in worker sub-event mode
183 G4Exception("G4WorkerSubEvtRunManager::ProcessOneEvent()","SubEvtXXX002",FatalException,
184 "This method is not used in the worker thread of sub-event parallel mode");
185}
186
187//============================================================================//
188
190{
191 // This method is not used in worker sub-event mode
192 G4Exception("G4WorkerSubEvtRunManager::GenerateEvent()","SubEvtXXX003",FatalException,
193 "This method is not used in the worker thread of sub-event parallel mode");
194 return nullptr;
195}
196
197//============================================================================//
198
200{
201 if (!fakeRun && (currentRun != nullptr)) {
203
204 // Call a user hook: note this is before the next barrier
205 // so threads execute this method asyncrhonouzly
206 //(TerminateRun allows for synch via G4RunAction::EndOfRun)
207 const G4UserWorkerInitialization* uwi =
209 if (uwi != nullptr) uwi->WorkerRunEnd();
210 }
211
212 if (currentRun != nullptr) {
214 }
215 // Signal this thread has finished envent-loop.
216 // Note this will return only whan all threads reach this point
218}
219
220//============================================================================//
221
223{
224 if (verboseLevel > 0 && !fakeRun) {
225 timer->Stop();
226 // prefix with thread # info due to how TBB calls this function
227 G4String prefix = "[thread " + std::to_string(workerContext->GetThreadId()) + "] ";
228 G4cout << prefix << "Thread-local run terminated." << G4endl;
229 G4cout << prefix << "Run Summary" << G4endl;
230 if (runAborted)
231 G4cout << prefix << " Run Aborted after " << numberOfEventProcessed << " sub-events processed."
232 << G4endl;
233 else
234 G4cout << prefix << " Number of sub-events processed : " << numberOfEventProcessed << G4endl;
235 G4cout << prefix << " " << *timer << G4endl;
236 }
237}
238
239//============================================================================//
240
250
251//============================================================================//
252
254{
255 std::ostringstream os;
256 os << randomNumberStatusDir << "G4Worker" << workerContext->GetThreadId() << "_" << fn << ".rndm";
257 G4Random::saveEngineStatus(os.str().c_str());
258}
259
260//============================================================================//
261
263{
265 if (mrm == nullptr) return;
266
267 //------------------------------------------------------------------------//
268 // Check UI commands not already processed
269 auto command_stack = mrm->GetCommandStack();
270 bool matching = (command_stack.size() == processedCommandStack.size());
271 if (matching) {
272 for (uintmax_t i = 0; i < command_stack.size(); ++i)
273 if (processedCommandStack.at(i) != command_stack.at(i)) {
274 matching = false;
275 break;
276 }
277 }
278
279 //------------------------------------------------------------------------//
280 // Execute UI commands stored in the master UI manager
281 if (!matching) {
282 for (const auto& itr : command_stack)
284 processedCommandStack = std::move(command_stack);
285 }
286}
287
288//============================================================================//
289
291{
292 // Nothing to do for a run
293
294 //CleanUpPreviousEvents();
295 //
296 //delete currentRun;
297 //currentRun = nullptr;
298}
299
300//============================================================================//
301
303{
304 if(verboseLevel>1) {
305 G4cout << "G4WorkerSubEvtRunManager::DoWork() starts.........." << G4endl;
306 }
307
309 G4bool newRun = false;
310 const G4Run* run = mrm->GetCurrentRun();
311 G4ThreadLocalStatic G4int runId = -1;
312 if ((run != nullptr) && run->GetRunID() != runId) {
313 runId = run->GetRunID();
314 newRun = true;
315 if (runId > 0) { ProcessUI(); }
316 }
317
318 G4bool reseedRequired = false;
319 if (newRun) {
321 if (cond) {
324 }
325 reseedRequired = true;
326 }
327
328 assert(workerContext != nullptr);
329 workerContext->UpdateGeometryAndPhysicsVectorFromMaster();
330
331 eventManager->UseSubEventParallelism(true);
332
333 G4bool needMoreWork = true;
334 while(needMoreWork)
335 {
336 G4bool notReady = false;
337 G4long s1, s2, s3;
338 auto subEv = mrm->GetSubEvent(fSubEventType, notReady, s1, s2, s3, reseedRequired);
339 if(subEv==nullptr && notReady)
340 {
341 // Master is not yet ready for tasking a sub-event.
342 // Wait 1 second and retry.
343 G4THREADSLEEP(1);
344 }
345 else if(subEv==nullptr)
346 {
347 // No more sub-event to process
348 // Report the results of previous sub-events if any
349 G4Event* remainingE = nullptr;
350 do
351 {
352 remainingE = eventManager->RetrieveCompletedSubEvent();
353 if(remainingE)
354 {
355 mrm->SubEventFinished(remainingE->GetSubEvent(),remainingE);
356 delete remainingE;
357 }
358 }
359 while(remainingE);
360
361 // Check if no more sub-event in event manager
362 if(eventManager->GetNumberOfRemainingSubEvents()==0)
363 { needMoreWork = false; }
364 else
365 { // Wait 1 second and revisit.
366 G4THREADSLEEP(1);
367 if(verboseLevel>1) {
368 G4cout << "G4WorkerSubEvtRunManager::DoWork() - "
369 << eventManager->GetNumberOfRemainingSubEvents()
370 << " sub-events are still incomplete in the event manager."<< G4endl;
371 }
372 }
373 }
374 else
375 {
376 // Let's work for this sub-event.
377 if(reseedRequired)
378 {
379 G4long seeds[3] = {s1, s2, s3};
380 G4Random::setTheSeeds(seeds, -1);
381 reseedRequired = false;
382 }
383
384 // create a G4Event object for this sub-event. This G4Event object will contain output
385 // to be merged into the master event.
386 auto masterEvent = subEv->GetEvent();
387 G4Event* ev = new G4Event(masterEvent->GetEventID());
388 ev->FlagAsSubEvent(masterEvent,fSubEventType,subEv);
390
391 // Create a G4TrackVector as the input
392 G4TrackVector* tv = new G4TrackVector();
393 for(auto& stackedTrack : *subEv)
394 {
395 // tracks (and trajectories) stored in G4SubEvent object belong to the master thread
396 // and thus they must not be deleted by the worker thread. They must be cloned.
397 G4Track* tr = new G4Track();
398 tr->CopyTrackInfo(*(stackedTrack.GetTrack()),false);
399 tv->push_back(tr);
400 }
401
402 // Process this sub-event
403 currentEvent = ev;
404 eventManager->ProcessOneEvent(tv,ev);
405
406 // We don't need following two lines, as they are taken care by the master
407 //////AnalyzeEvent(ev);
408 //////UpdateScoring();
409
410 // Report the results to the master if sub-event is completed
411 if(subEv->IsCompleted())
412 {
413 mrm->SubEventFinished(subEv,ev);
414 delete ev;
415 }
416
417 // Report the results of previous sub-events if any
418 G4Event* remainingE = nullptr;
419 do
420 {
421 remainingE = eventManager->RetrieveCompletedSubEvent();
422 if(remainingE)
423 {
424 mrm->SubEventFinished(remainingE->GetSubEvent(),remainingE);
425 delete remainingE;
426 }
427 }
428 while(remainingE);
429
430 if(verboseLevel>2)
431 {
432 G4cout << "G4WorkerSubEvtRunManager::DoWork() - "
433 << eventManager->GetNumberOfRemainingSubEvents()
434 << " sub-events are still incomplete in the event manager."<< G4endl;
435 }
436
437 // clean up
438 delete tv;
439 }
440 }
441
442 if(verboseLevel>1) {
443 G4cout << "G4WorkerSubEvtRunManager::DoWork() completed.........." << G4endl;
444 }
445
446}
447
449{
451 mrm->RegisterSubEvtWorker(this,ty);
452 fSubEventType = ty;
453}
454
455//============================================================================//
456
458{
459 G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerInitialization*)", "RunSE0118",
460 FatalException, "This method should be used only with an instance of the master thread");
461}
462
463// --------------------------------------------------------------------
465{
466 G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "RunSE0119",
467 FatalException, "This method should be used only with an instance of the master thread");
468}
469
470// --------------------------------------------------------------------
472{
473 G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserActionInitialization*)", "RunSE0120",
474 FatalException, "This method should be used only with an instance of the master thread");
475}
476
477// --------------------------------------------------------------------
479{
480 G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "RunSE0121",
481 FatalException, "This method should be used only with an instance of the master thread");
482}
483
484// --------------------------------------------------------------------
490
491// --------------------------------------------------------------------
493{
494 G4Exception("G4WorkerSubEvtRunManager::SetUserAction(G4UserRunAction*)", "RunSE0221",
495 FatalException, "This method should be used only with an instance of the master thread");
496}
497
498// Forward calls (avoid GCC compilation warnings)
499
500// --------------------------------------------------------------------
505
506// --------------------------------------------------------------------
508{
509 G4Exception("G4WorkerSubEvtRunManager::SetUserAction(G4VUserPrimaryGeneratorAction*)", "RunSE0223",
510 FatalException, "This method should be used only with an instance of the master thread");
511}
512
513// --------------------------------------------------------------------
518
519// --------------------------------------------------------------------
524
525// --------------------------------------------------------------------
530
531
532
533
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4THREADSLEEP(tick)
std::vector< G4Track * > G4TrackVector
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4WorkerTaskRunManagerKernel G4WorkerSubEvtRunManagerKernel
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
const G4SubEvent * GetSubEvent() const
Definition G4Event.hh:298
void FlagAsSubEvent(G4Event *me, G4int ty, const G4SubEvent *se)
Definition G4Event.hh:288
const CLHEP::HepRandomEngine * getMasterRandomEngine() const
virtual void ThisWorkerReady()
static G4MTRunManager * GetMasterRunManager()
std::vector< G4String > GetCommandStack()
virtual void ThisWorkerEndEventLoop()
static G4ParallelWorldProcessStore * GetInstance()
G4bool isScoreNtupleWriter
virtual void CleanUpPreviousEvents()
const G4UserWorkerInitialization * GetUserWorkerInitialization() const
std::list< G4Event * > * previousEvents
G4Timer * timer
G4int numberOfEventProcessed
G4int GetNumberOfEventsToBeProcessed() const
G4RunManagerKernel * kernel
G4Run * currentRun
virtual G4bool ConfirmBeamOnCondition()
static G4RunManager * GetRunManager()
G4DCtable * DCtable
G4String randomNumberStatusForThisRun
static G4bool IfGeometryHasBeenDestroyed()
G4UserRunAction * userRunAction
G4bool rngStatusEventsFlag
virtual void RunTermination()
const G4Run * GetCurrentRun() const
G4int numberOfEventToBeProcessed
G4String randomNumberStatusDir
virtual void SetUserAction(G4UserRunAction *userAction)
const G4UserWorkerThreadInitialization * GetUserWorkerThreadInitialization() const
RMType runManagerType
G4int n_perviousEventsToBeStored
virtual void SetUserInitialization(G4VUserDetectorConstruction *userInit)
G4bool storeRandomNumberStatus
G4EventManager * eventManager
G4Event * currentEvent
Definition G4Run.hh:48
G4int GetRunID() const
Definition G4Run.hh:82
G4HCofThisEvent * PrepareNewEvent()
static G4SDManager * GetSDMpointerIfExist()
G4HCtable * GetHCtable() const
void SubEventFinished(const G4SubEvent *se, const G4Event *evt) override
static G4SubEvtRunManager * GetMasterRunManager()
const G4SubEvent * GetSubEvent(G4int ty, G4bool &notReady, G4long &s1, G4long &s2, G4long &s3, G4bool reseedRequired=true) override
static G4TaskRunManager * GetMasterRunManager()
void CopyTrackInfo(const G4Track &, G4bool copyTouchables=true)
Definition G4Track.cc:158
G4int ApplyCommand(const char *aCommand)
static G4UImanager * GetUIpointer()
virtual void SetupRNGEngine(const CLHEP::HepRandomEngine *aRNGEngine) const
virtual G4bool Book(G4HCofThisEvent *hce)=0
static G4VScoreNtupleWriter * Instance()
virtual void OpenFile()=0
virtual void InitializeWorker()
static G4VVisManager * GetConcreteInstance()
virtual void SetUpForAThread()
virtual void MergePartialResults(G4bool mergeEvents=true)
G4WorkerThread * workerContext
void ConstructScoringWorlds() override
void DoEventLoop(G4int n_event, const char *macroFile=nullptr, G4int n_select=-1) override
static G4WorkerSubEvtRunManagerKernel * GetWorkerRunManagerKernel()
G4WorkerSubEvtRunManager(G4int subEventType=0)
static G4WorkerSubEvtRunManager * GetWorkerRunManager()
G4Event * GenerateEvent(G4int i_event) override
void StoreRNGStatus(const G4String &filenamePrefix) override
void SetUserAction(G4UserRunAction *userAction) override
void SetUserInitialization(G4VUserPhysicsList *userPL) override
void ProcessOneEvent(G4int i_event) override
G4int G4GetThreadId()
std::string to_string(G4FermiAtomicMass mass)
#define G4ThreadLocalStatic
Definition tls.hh:76