Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4SubEvtRunManager.cc

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 ]

Diff markup

Differences between /run/src/G4SubEvtRunManager.cc (Version 11.3.0) and /run/src/G4SubEvtRunManager.cc (Version 9.5)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //                                                
 27                                                   
 28 #include "G4SubEvtRunManager.hh"                  
 29                                                   
 30 #include "G4AutoLock.hh"                          
 31 #include "G4EnvironmentUtils.hh"                  
 32 #include "G4ProductionCutsTable.hh"               
 33 #include "G4Run.hh"                               
 34 #include "G4ScoringManager.hh"                    
 35 #include "G4THitsMap.hh"                          
 36 #include "G4StateManager.hh"                      
 37 #include "G4Task.hh"                              
 38 #include "G4TaskGroup.hh"                         
 39 #include "G4TaskManager.hh"                       
 40 #include "G4TaskRunManagerKernel.hh"              
 41 #include "G4ThreadLocalSingleton.hh"              
 42 #include "G4ThreadPool.hh"                        
 43 #include "G4Threading.hh"                         
 44 #include "G4Timer.hh"                             
 45 #include "G4TransportationManager.hh"             
 46 #include "G4UImanager.hh"                         
 47 #include "G4UserRunAction.hh"                     
 48 #include "G4UserTaskInitialization.hh"            
 49 #include "G4UserTaskQueue.hh"                     
 50 #include "G4UserSubEvtThreadInitialization.hh"    
 51 #include "G4VUserActionInitialization.hh"         
 52 #include "G4VUserPhysicsList.hh"                  
 53 #include "G4UserEventAction.hh"                   
 54 #include "G4VScoreNtupleWriter.hh"                
 55 #include "G4WorkerSubEvtRunManager.hh"            
 56 #include "G4WorkerThread.hh"                      
 57 #include "G4VVisManager.hh"                       
 58 #include "G4Trajectory.hh"                        
 59                                                   
 60 #include <cstdlib>                                
 61 #include <cstring>                                
 62 #include <iterator>                               
 63 #include <algorithm>                              
 64                                                   
 65 //============================================    
 66                                                   
 67 namespace                                         
 68 {                                                 
 69 G4Mutex scorerMergerMutex;                        
 70 G4Mutex accessSubEventMutex;                      
 71 G4Mutex registerSubEvtWorkerMutex;                
 72 }  // namespace                                   
 73                                                   
 74 //============================================    
 75                                                   
 76 G4SubEvtRunManager::G4SubEvtRunManager(G4VUser    
 77                                                   
 78  : G4TaskRunManager(task_queue, useTBB, grains    
 79 {                                                 
 80   runManagerType = subEventMasterRM;              
 81   G4UImanager::GetUIpointer()->SetAlias("RunMo    
 82 }                                                 
 83                                                   
 84 //============================================    
 85                                                   
 86 G4SubEvtRunManager::G4SubEvtRunManager(G4bool     
 87  : G4SubEvtRunManager(nullptr, useTBB, 0)         
 88 { runManagerType = subEventMasterRM; }            
 89                                                   
 90 //============================================    
 91                                                   
 92 G4SubEvtRunManager::~G4SubEvtRunManager()         
 93 {                                                 
 94   // relying all the necessary deletion upon t    
 95   // G4TaskRunManager::~G4TaskRunManager()        
 96 }                                                 
 97                                                   
 98 //============================================    
 99                                                   
100 void G4SubEvtRunManager::Initialize()             
101 {                                                 
102   SetSeedOncePerCommunication(1);                 
103   G4bool firstTime = (threadPool == nullptr);     
104   if (firstTime) G4TaskRunManager::InitializeT    
105                                                   
106   G4RunManager::Initialize();                     
107                                                   
108   // make sure all worker threads are set up.     
109   G4RunManager::BeamOn(0);                        
110   if (firstTime) G4RunManager::SetRunIDCounter    
111   // G4UImanager::GetUIpointer()->SetIgnoreCmd    
112 }                                                 
113                                                   
114 //============================================    
115                                                   
116 void G4SubEvtRunManager::RunInitialization()      
117 {                                                 
118   G4RunManager::RunInitialization();              
119   if(!fakeRun)                                    
120   { if(CheckSubEvtTypes()) runInProgress = tru    
121 }                                                 
122                                                   
123 //============================================    
124                                                   
125 void G4SubEvtRunManager::ProcessOneEvent(G4int    
126 {                                                 
127   currentEvent = GenerateEvent(i_event);          
128   eventManager->ProcessOneEvent(currentEvent);    
129                                                   
130   // Following two lines should not be execute    
131   // be still being processed. These methods a    
132   // to this event are processed and scores of    
133   // corresponding master event.                  
134   //AnalyzeEvent(currentEvent);                   
135   //UpdateScoring();                              
136                                                   
137   if (i_event < n_select_msg) G4UImanager::Get    
138 }                                                 
139                                                   
140 //============================================    
141                                                   
142 void G4SubEvtRunManager::TerminateOneEvent()      
143 {                                                 
144   // We must serialize access here because wor    
145   // and we can't override StackPreviousEvent     
146   G4AutoLock l(&accessSubEventMutex);             
147   StackPreviousEvent(currentEvent);               
148   currentEvent = nullptr;                         
149   ++numberOfEventProcessed;                       
150 }                                                 
151                                                   
152 //============================================    
153                                                   
154 void G4SubEvtRunManager::StackPreviousEvent(G4    
155 {                                                 
156   if(n_perviousEventsToBeStored>0) {              
157     G4ExceptionDescription ed;                    
158     ed << "G4RunManager::SetNumberOfEventsToBe    
159        << "User may still keep events bu G4Eve    
160     G4Exception("G4SubEvtRunManager::StackPrev    
161     return;                                       
162   }                                               
163                                                   
164   if(anEvent->GetNumberOfRemainingSubEvents()>    
165   // sub-events are still under processing. Ev    
166   {                                               
167     currentRun->StoreEvent(anEvent);              
168   }                                               
169   else                                            
170   // Event is already completed.                  
171   {                                               
172     // making sure this is the first path         
173     if(!(anEvent->IsEventCompleted()))            
174     {                                             
175       anEvent->EventCompleted();                  
176       if(userEventAction!=nullptr) userEventAc    
177       auto pVisManager = G4VVisManager::GetCon    
178       if (pVisManager) pVisManager->EventReady    
179       UpdateScoring(anEvent);                     
180       if(anEvent->ToBeKept() || anEvent->GetNu    
181       { // we keep this event for post-process    
182         currentRun->StoreEvent(anEvent);          
183       }                                           
184       else                                        
185       {                                           
186         ReportEventDeletion(anEvent);             
187         delete anEvent;                           
188       }                                           
189     } else {                                      
190       G4Exception("G4SubEvtRunManager::StackPr    
191     }                                             
192   }                                               
193                                                   
194   CleanUpUnnecessaryEvents(0);                    
195 }                                                 
196                                                   
197 //============================================    
198                                                   
199 void G4SubEvtRunManager::CleanUpUnnecessaryEve    
200 {                                                 
201   // Delete events that are no longer necessar    
202   // processing such as visualization.            
203   // N.B. If ToBeKept() is true, the pointer o    
204   // kept in G4Run, and deleted along with the    
205                                                   
206   if(keepNEvents>0) {                             
207     G4ExceptionDescription ed;                    
208     ed << "G4RunManager::SetNumberOfEventsToBe    
209        << "User may still keep events bu G4Eve    
210     G4Exception("G4SubEvtRunManager::CleanUpUn    
211     return;                                       
212   }                                               
213                                                   
214   assert(currentRun!=nullptr);                    
215                                                   
216   auto eventVector = currentRun->GetEventVecto    
217   if(eventVector==nullptr || eventVector->empt    
218   auto eItr = eventVector->cbegin();              
219   while(eItr != eventVector->cend())              
220   {                                               
221     const G4Event* ev = *eItr;                    
222     if(ev!=nullptr)                               
223     {                                             
224       if(!(ev->IsEventCompleted()))               
225       {                                           
226         if(ev->GetNumberOfRemainingSubEvents()    
227         { // This event has been completed sin    
228           ev->EventCompleted();                   
229           if(userEventAction!=nullptr) userEve    
230           auto pVisManager = G4VVisManager::Ge    
231           if (pVisManager) pVisManager->EventR    
232           UpdateScoring(ev);                      
233           if(ev->ToBeKept() || ev->GetNumberOf    
234           { // we keep this event for post-pro    
235             eItr++;                               
236           }                                       
237           else                                    
238           { // this event is no longer needed     
239             ReportEventDeletion(ev);              
240             delete ev;                            
241             eItr = eventVector->erase(eItr);      
242           }                                       
243         }                                         
244         else                                      
245         { // this event is still incomplete       
246           eItr++;                                 
247         }                                         
248       }                                           
249       else if(ev->ToBeKept() || ev->GetNumberO    
250       { // we still need this event               
251         eItr++;                                   
252       }                                           
253       else                                        
254       { // post-processing done. we no longer     
255         ReportEventDeletion(ev);                  
256         delete ev;                                
257         eItr = eventVector->erase(eItr);          
258       }                                           
259     }                                             
260     else                                          
261     { // ev is a null pointer                     
262       eItr = eventVector->erase(eItr);            
263     }                                             
264   }                                               
265 }                                                 
266                                                   
267 //============================================    
268                                                   
269 void G4SubEvtRunManager::CreateAndStartWorkers    
270 {                                                 
271   // Now loop on requested number of workers      
272   // This will also start the workers             
273   // Currently we do not allow to change the      
274   // number of threads: threads area created o    
275   // Instead of pthread based workers, create     
276   static G4bool initializeStarted = false;        
277                                                   
278   ComputeNumberOfTasks();                         
279                                                   
280   if (fakeRun) {                                  
281     if (initializeStarted) {                      
282       auto initCmdStack = GetCommandStack();      
283       if (!initCmdStack.empty()) {                
284         threadPool->execute_on_all_threads([cm    
285           for (auto& itr : cmds)                  
286             G4UImanager::GetUIpointer()->Apply    
287           G4WorkerTaskRunManager::GetWorkerRun    
288         });                                       
289       }                                           
290     }                                             
291     else {                                        
292       std::stringstream msg;                      
293       msg << "--> G4SubEvtRunManager::CreateAn    
294           << "Initializing workers...";           
295                                                   
296       std::stringstream ss;                       
297       ss.fill('=');                               
298       ss << std::setw((G4int)msg.str().length(    
299       G4cout << "\n" << ss.str() << "\n" << ms    
300                                                   
301       G4TaskRunManagerKernel::InitCommandStack    
302       threadPool->execute_on_all_threads([]()     
303     }                                             
304     initializeStarted = true;                     
305   }                                               
306   else {                                          
307     auto initCmdStack = GetCommandStack();        
308     if (!initCmdStack.empty()) {                  
309       threadPool->execute_on_all_threads([cmds    
310         for (auto& itr : cmds)                    
311           G4UImanager::GetUIpointer()->ApplyCo    
312       });                                         
313     }                                             
314                                                   
315     // cleans up a previous run and events in     
316     // does not execute any tasks                 
317     threadPool->execute_on_all_threads([]() {     
318                                                   
319     {                                             
320       std::stringstream msg;                      
321       msg << "--> G4SubEvtRunManager::CreateAn    
322           << "Creating " << numberOfTasks << "    
323           << " events/task...";                   
324                                                   
325       std::stringstream ss;                       
326       ss.fill('=');                               
327       ss << std::setw((G4int)msg.str().length(    
328       G4cout << "\n" << ss.str() << "\n" << ms    
329     }                                             
330                                                   
331     /* TODO (PHASE-II): Better calculation of     
332        Currently, number of tasks is equal to     
333        and each task has a loop that endlessly    
334        until no additional sub-event is availa    
335        This is not ideal. We should make each     
336        number of sub-events, and create as man    
337        on the fly during the event loop of the    
338     G4int remaining = numberOfEventToBeProcess    
339     for (G4int nt = 0; nt < numberOfTasks + 1;    
340       if (remaining > 0) AddEventTask(nt);        
341       remaining -= numberOfEventsPerTask;         
342     }                                             
343     */                                            
344     for(G4int nt = 0; nt < numberOfTasks; ++nt    
345     { AddEventTask(nt); }                         
346   }                                               
347 }                                                 
348                                                   
349 //============================================    
350                                                   
351 void G4SubEvtRunManager::AddEventTask(G4int nt    
352 {                                                 
353   if (verboseLevel > 3) G4cout << "Adding task    
354   workTaskGroup->exec([]() { G4TaskRunManagerK    
355 }                                                 
356                                                   
357 //============================================    
358                                                   
359 void G4SubEvtRunManager::RefillSeeds()            
360 {                                                 
361   G4RNGHelper* helper = G4RNGHelper::GetInstan    
362   G4int nFill = 0;                                
363   switch (SeedOncePerCommunication()) {           
364     case 0:                                       
365       nFill = numberOfEventToBeProcessed - nSe    
366       break;                                      
367     case 1:                                       
368       nFill = numberOfTasks - nSeedsFilled;       
369       break;                                      
370     case 2:                                       
371     default:                                      
372       nFill = (numberOfEventToBeProcessed - nS    
373   }                                               
374   // Generates up to nSeedsMax seed pairs only    
375   if (nFill > nSeedsMax) nFill = nSeedsMax;       
376   masterRNGEngine->flatArray(nSeedsPerEvent *     
377   helper->Refill(randDbl, nFill);                 
378   nSeedsFilled += nFill;                          
379 }                                                 
380                                                   
381 //============================================    
382                                                   
383 void G4SubEvtRunManager::InitializeEventLoop(G    
384 {                                                 
385   MTkernel->SetUpDecayChannels();                 
386   numberOfEventToBeProcessed = n_event;           
387   numberOfEventProcessed = 0;                     
388                                                   
389   if (!fakeRun) {                                 
390     nSeedsUsed = 0;                               
391     nSeedsFilled = 0;                             
392                                                   
393     if (verboseLevel > 0) timer->Start();         
394                                                   
395     n_select_msg = n_select;                      
396     if (macroFile != nullptr) {                   
397       if (n_select_msg < 0) n_select_msg = n_e    
398                                                   
399       msgText = "/control/execute ";              
400       msgText += macroFile;                       
401       selectMacro = macroFile;                    
402     }                                             
403     else {                                        
404       n_select_msg = -1;                          
405       selectMacro = "";                           
406     }                                             
407                                                   
408     ComputeNumberOfTasks();                       
409                                                   
410     // initialize seeds                           
411     // If user did not implement InitializeSee    
412     // use default: nSeedsPerEvent seeds per e    
413                                                   
414     if (n_event > 0) {                            
415       G4bool _overload = InitializeSeeds(n_eve    
416       G4bool _functor = false;                    
417       if (!_overload) _functor = initSeedsCall    
418       if (!_overload && !_functor) {              
419         G4RNGHelper* helper = G4RNGHelper::Get    
420         switch (SeedOncePerCommunication()) {     
421           case 1:                                 
422             nSeedsFilled = nworkers;              
423             break;                                
424           default:                                
425             G4ExceptionDescription msgd;          
426             msgd << "Parameter value <" << See    
427                  << "> of seedOncePerCommunica    
428                     "to 1.";                      
429             G4Exception("G4SubEvtRunManager::I    
430             SetSeedOncePerCommunication(1);       
431             nSeedsFilled = nworkers;              
432         }                                         
433                                                   
434         // Generates up to nSeedsMax seed pair    
435         if (nSeedsFilled > nSeedsMax) nSeedsFi    
436         masterRNGEngine->flatArray(nSeedsPerEv    
437         helper->Fill(randDbl, nSeedsFilled, n_    
438       }                                           
439     }                                             
440   }                                               
441                                                   
442   // Now initialize workers. Check if user def    
443   if (userWorkerThreadInitialization == nullpt    
444     userWorkerThreadInitialization = new G4Use    
445                                                   
446   // Prepare UI commands for threads              
447   PrepareCommandsStack();                         
448                                                   
449   // Start worker threads                         
450   CreateAndStartWorkers();                        
451 }                                                 
452                                                   
453 //============================================    
454                                                   
455 void G4SubEvtRunManager::RunTermination()         
456 {                                                 
457   // Wait for all worker threads to have finis    
458   // i.e. wait for them to return from RunTerm    
459   // This guarantee that userrunaction for wor    
460                                                   
461   runInProgress = false;                          
462                                                   
463   //TODO (PHASE-II): do we need this???           
464   workTaskGroup->wait();                          
465                                                   
466   // Wait now for all threads to finish event-    
467   WaitForEndEventLoopWorkers();                   
468                                                   
469   // Now call base-class method                   
470   G4RunManager::TerminateEventLoop();             
471   G4RunManager::RunTermination();                 
472                                                   
473   if(currentRun!=nullptr)                         
474   {                                               
475     auto eventVector = currentRun->GetEventVec    
476     if(eventVector!=nullptr)                      
477     {                                             
478       G4int notReady = 1;                         
479       while(notReady>0)                           
480       {                                           
481         notReady = 0;                             
482         for(auto ev:*eventVector)                 
483         {                                         
484           if(ev->GetNumberOfRemainingSubEvents    
485           { notReady++; }                         
486         }                                         
487         if(notReady>0)                            
488         {                                         
489           if(verboseLevel>2)                      
490           {                                       
491             G4cout << "G4SubEvtRunManager::Run    
492                    << " events are still incom    
493           }                                       
494           G4THREADSLEEP(1);                       
495         }                                         
496       }                                           
497     }                                             
498     CleanUpUnnecessaryEvents(0);                  
499   }                                               
500 }                                                 
501                                                   
502 //============================================    
503                                                   
504 void G4SubEvtRunManager::ConstructScoringWorld    
505 {                                                 
506   masterScM = G4ScoringManager::GetScoringMana    
507   // Call base class stuff...                     
508   G4RunManager::ConstructScoringWorlds();         
509                                                   
510   GetMasterWorlds().clear();                      
511   auto nWorlds = (G4int)G4TransportationManage    
512   auto itrW = G4TransportationManager::GetTran    
513   for (G4int iWorld = 0; iWorld < nWorlds; ++i    
514     addWorld(iWorld, *itrW);                      
515     ++itrW;                                       
516   }                                               
517 }                                                 
518                                                   
519 //============================================    
520                                                   
521 void G4SubEvtRunManager::MergeScores(const G4S    
522 {                                                 
523   G4AutoLock l(&scorerMergerMutex);               
524   if (masterScM != nullptr) masterScM->Merge(l    
525 }                                                 
526                                                   
527 const G4SubEvent* G4SubEvtRunManager::GetSubEv    
528               G4long& s1, G4long& s2, G4long&     
529 {                                                 
530   G4AutoLock l(&accessSubEventMutex);             
531                                                   
532 // This method is invoked from the worker, the    
533 // remains to the master, i.e. will be deleted    
534 // TerminateSubEvent() method.                    
535                                                   
536   if(currentRun==nullptr)                         
537   {                                               
538   // Run has not yet started.                     
539     notReady = true;                              
540     return nullptr;                               
541   }                                               
542                                                   
543   auto eventVector = currentRun->GetEventVecto    
544   // RACE HERE: against:                          
545   // 1 G4Run::StoreEvent(G4Event*) G4Run.cc:80    
546   // 2 G4RunManager::StackPreviousEvent(G4Even    
547   for(auto& ev : *eventVector)                    
548   {                                               
549   // looping over stored events                   
550     // RACE HERE: against:                        
551     // 1 G4Run::StoreEvent(G4Event*) G4Run.cc:    
552     // 2 G4RunManager::StackPreviousEvent(G4Ev    
553     auto se = const_cast<G4Event*>(ev)->PopSub    
554     if(se!=nullptr)                               
555     {                                             
556     // Sub-event is found in an event that is     
557       notReady = false;                           
558       if(reseedRequired) SetUpSeedsForSubEvent    
559       return se;                                  
560     }                                             
561   }                                               
562                                                   
563   auto sep = eventManager->PopSubEvent(ty);       
564   if(sep!=nullptr)                                
565   {                                               
566   // Sub-event is found in an event that is st    
567     notReady = false;                             
568     if(reseedRequired) SetUpSeedsForSubEvent(s    
569     return sep;                                   
570   } else {                                        
571   // No sub-event available                       
572     // RACE HERE vs line 345                      
573     if(runInProgress)                             
574     {                                             
575     // Run is still in progress. Worker should    
576       notReady = true;                            
577     }                                             
578     else                                          
579     {                                             
580     // Run is over. No more sub-event to come     
581       notReady = false;                           
582     }                                             
583     return nullptr;                               
584   }                                               
585 }                                                 
586                                                   
587 void G4SubEvtRunManager::SetUpSeedsForSubEvent    
588 {                                                 
589   //TODO (PHASE-II): Seeding scheme for sub-ev    
590   G4RNGHelper* helper = G4RNGHelper::GetInstan    
591   G4int idx_rndm = nSeedsPerEvent * nSeedsUsed    
592   s1 = helper->GetSeed(idx_rndm);                 
593   s2 = helper->GetSeed(idx_rndm + 1);             
594   if (nSeedsPerEvent == 3) s3 = helper->GetSee    
595   ++nSeedsUsed;                                   
596   if (nSeedsUsed == nSeedsFilled) RefillSeeds(    
597 }                                                 
598                                                   
599                                                   
600 //============================================    
601 //                                                
602 //G4bool G4SubEvtRunManager::SetUpAnEvent(G4Ev    
603 //                                      G4bool    
604 //{                                               
605 //  G4AutoLock l(&setUpEventMutex);               
606 //  if (numberOfEventProcessed < numberOfEvent    
607 //    evt->SetEventID(numberOfEventProcessed);    
608 //    if (reseedRequired) {                       
609 //      G4RNGHelper* helper = G4RNGHelper::Get    
610 //      G4int idx_rndm = nSeedsPerEvent * nSee    
611 //      s1 = helper->GetSeed(idx_rndm);           
612 //      s2 = helper->GetSeed(idx_rndm + 1);       
613 //      if (nSeedsPerEvent == 3) s3 = helper->    
614 //      ++nSeedsUsed;                             
615 //      if (nSeedsUsed == nSeedsFilled) Refill    
616 //    }                                           
617 //    numberOfEventProcessed++;                   
618 //    return true;                                
619 //  }                                             
620 //  return false;                                 
621 //}                                               
622                                                   
623 //============================================    
624 //                                                
625 //G4int G4SubEvtRunManager::SetUpNEvents(G4Eve    
626 //{                                               
627 //  G4AutoLock l(&setUpEventMutex);               
628 //  if (numberOfEventProcessed < numberOfEvent    
629 //    G4int nevt = numberOfEventsPerTask;         
630 //    G4int nmod = eventModulo;                   
631 //    if (numberOfEventProcessed + nevt > numb    
632 //      nevt = numberOfEventToBeProcessed - nu    
633 //      nmod = numberOfEventToBeProcessed - nu    
634 //    }                                           
635 //    evt->SetEventID(numberOfEventProcessed);    
636 //                                                
637 //    if (reseedRequired) {                       
638 //      G4RNGHelper* helper = G4RNGHelper::Get    
639 //      G4int nevRnd = nmod;                      
640 //      if (SeedOncePerCommunication() > 0) ne    
641 //      for (G4int i = 0; i < nevRnd; ++i) {      
642 //        seedsQueue->push(helper->GetSeed(nSe    
643 //        seedsQueue->push(helper->GetSeed(nSe    
644 //        if (nSeedsPerEvent == 3) seedsQueue-    
645 //        nSeedsUsed++;                           
646 //        if (nSeedsUsed == nSeedsFilled) Refi    
647 //      }                                         
648 //    }                                           
649 //    numberOfEventProcessed += nevt;             
650 //    return nevt;                                
651 //  }                                             
652 //  return 0;                                     
653 //}                                               
654                                                   
655 //============================================    
656                                                   
657 void G4SubEvtRunManager::SubEventFinished(cons    
658 {                                                 
659   G4AutoLock l(&accessSubEventMutex);             
660   auto masterEvt = se->GetEvent();                
661   if(masterEvt==nullptr) {                        
662     G4Exception("G4SubEvtRunManager::SubEventF    
663       FatalException,"Pointer of master event     
664     return; // NOLINT: required to help Coveri    
665   }                                               
666                                                   
667   if(userEventAction) {                           
668     userEventAction->MergeSubEvent(masterEvt,e    
669   }                                               
670   if(trajectoriesToBeMerged) MergeTrajectories    
671   UpdateScoringForSubEvent(se,evt);               
672   evt->ScoresRecorded();                          
673   eventManager->TerminateSubEvent(se,evt);        
674 }                                                 
675                                                   
676 //============================================    
677                                                   
678 void G4SubEvtRunManager::MergeTrajectories(con    
679 {                                                 
680   auto masterEvt = se->GetEvent();                
681   auto* trajVector = evt->GetTrajectoryContain    
682   auto* masterTrajContainer = masterEvt->GetTr    
683   if(masterTrajContainer==nullptr)                
684   {                                               
685     masterTrajContainer = new G4TrajectoryCont    
686     masterEvt->SetTrajectoryContainer(masterTr    
687   }                                               
688   for(auto& traj : *trajVector)                   
689   {                                               
690     if(traj!=nullptr) {                           
691       auto* cloned = traj->CloneForMaster();      
692       masterTrajContainer->push_back(cloned);     
693     }                                             
694   }                                               
695 }                                                 
696                                                   
697 //============================================    
698                                                   
699 void G4SubEvtRunManager::UpdateScoringForSubEv    
700 {                                                 
701   auto masterEvt = se->GetEvent();                
702                                                   
703   G4ScoringManager* ScM = G4ScoringManager::Ge    
704   if (ScM == nullptr) return;                     
705   auto nPar = (G4int)ScM->GetNumberOfMesh();      
706   if (nPar < 1) return;                           
707                                                   
708   if(verboseLevel>3) {                            
709     G4cout << "merging scores of sub-event bel    
710            << " --- sub-event has " << evt->Ge    
711            << " hits collections" << G4endl;      
712   }                                               
713   G4HCofThisEvent* HCE = evt->GetHCofThisEvent    
714   if (HCE == nullptr) return;                     
715   auto nColl = (G4int)HCE->GetCapacity();         
716   G4HCofThisEvent* masterHCE = masterEvt->GetH    
717   if (masterHCE == nullptr || (G4int)masterHCE    
718   {                                               
719     G4Exception("G4SubEvtRunManager::UpdateSco    
720       FatalException,"Number of hits colleacti    
721     return;                                       
722   }                                               
723   for (G4int i = 0; i < nColl; ++i) {             
724     auto* HC = dynamic_cast<G4THitsMap<G4doubl    
725     auto* masterHC = dynamic_cast<G4THitsMap<G    
726     if (HC != nullptr && masterHC != nullptr)     
727     { *masterHC += *HC; }                         
728     else                                          
729     {                                             
730        G4Exception("G4SubEvtRunManager::Update    
731          FatalException,"HitsCollection is not    
732        return;                                    
733     }                                             
734   }                                               
735                                                   
736 }                                                 
737                                                   
738 //============================================    
739                                                   
740 void G4SubEvtRunManager::CleanUpPreviousEvents    
741 {                                                 
742   // Delete all events carried over from previ    
743   // This method is invoked at the beginning o    
744   // or from the destructor of G4RunManager at    
745   // the program.                                 
746   auto evItr = previousEvents->cbegin();          
747   while (evItr != previousEvents->cend()) {       
748     G4Event* evt = *evItr;                        
749     if (evt != nullptr)                           
750     {                                             
751       ReportEventDeletion(evt);                   
752       // remove evt from the event vector of G    
753       if(currentRun!=nullptr)                     
754       {                                           
755         auto eventVector = currentRun->GetEven    
756         auto eItr = std::find(eventVector->cbe    
757         if(eItr != eventVector->cend()) eventV    
758       }                                           
759       delete evt;                                 
760     }                                             
761     evItr = previousEvents->erase(evItr);         
762   }                                               
763   if(currentRun!=nullptr)                         
764   {                                               
765     auto eventVector = currentRun->GetEventVec    
766     if(eventVector==nullptr || eventVector->em    
767     auto eItr = eventVector->cbegin();            
768     while(eItr != eventVector->cend())            
769     {                                             
770       const G4Event* ev = *eItr;                  
771       if(ev!=nullptr)                             
772       {                                           
773         ReportEventDeletion(ev);                  
774         delete ev;                                
775       }                                           
776       eItr = eventVector->erase(eItr);            
777     }                                             
778   }                                               
779 }                                                 
780                                                   
781 //============================================    
782                                                   
783 void G4SubEvtRunManager::TerminateWorkers()       
784 {                                                 
785   // Force workers to execute (if any) all UI     
786   RequestWorkersProcessCommandsStack();           
787                                                   
788   if (workTaskGroup != nullptr) {                 
789     workTaskGroup->join();                        
790     if (!fakeRun)                                 
791       threadPool->execute_on_all_threads([]()     
792   }                                               
793 }                                                 
794                                                   
795 //============================================    
796                                                   
797 void G4SubEvtRunManager::AbortRun(G4bool softA    
798 {                                                 
799   // This method is valid only for GeomClosed     
800   G4ApplicationState currentState = G4StateMan    
801   if (currentState == G4State_GeomClosed || cu    
802     runAborted = true;                            
803     MTkernel->BroadcastAbortRun(softAbort);       
804   }                                               
805   else {                                          
806     G4cerr << "Run is not in progress. AbortRu    
807   }                                               
808 }                                                 
809                                                   
810 //============================================    
811                                                   
812 void G4SubEvtRunManager::AbortEvent()             
813 {                                                 
814   // nothing to do in the master thread           
815 }                                                 
816                                                   
817 //============================================    
818                                                   
819 void G4SubEvtRunManager::WaitForEndEventLoopWo    
820 {                                                 
821   if (workTaskGroup != nullptr) {                 
822     workTaskGroup->join();                        
823     if (!fakeRun)                                 
824       threadPool->execute_on_all_threads(         
825         []() { G4TaskRunManagerKernel::Termina    
826   }                                               
827 }                                                 
828                                                   
829 //============================================    
830                                                   
831 void G4SubEvtRunManager::RequestWorkersProcess    
832 {                                                 
833   PrepareCommandsStack();                         
834                                                   
835   auto process_commands_stack = []() {            
836     G4MTRunManager* mrm = G4MTRunManager::GetM    
837     if (mrm != nullptr) {                         
838       auto cmds = mrm->GetCommandStack();         
839       for (const auto& itr : cmds)                
840         G4UImanager::GetUIpointer()->ApplyComm    
841       mrm->ThisWorkerProcessCommandsStackDone(    
842     }                                             
843   };                                              
844                                                   
845   if (threadPool != nullptr) threadPool->execu    
846 }                                                 
847                                                   
848 //============================================    
849                                                   
850 void G4SubEvtRunManager::ThisWorkerProcessComm    
851                                                   
852 //============================================    
853                                                   
854 void G4SubEvtRunManager::RegisterSubEventType(    
855 {                                                 
856   G4AutoLock l(&registerSubEvtWorkerMutex);       
857   fSubEvtTypeMap[ty] = maxEnt;                    
858   eventManager->UseSubEventParallelism();         
859   eventManager->GetStackManager()->RegisterSub    
860 }                                                 
861                                                   
862 void G4SubEvtRunManager::RegisterSubEvtWorker(    
863 {                                                 
864   G4AutoLock l(&registerSubEvtWorkerMutex);       
865   fWorkerMap[wrm] = typ;                          
866 }                                                 
867                                                   
868 G4bool G4SubEvtRunManager::CheckSubEvtTypes()     
869 {                                                 
870   for(auto& seT : fSubEvtTypeMap)                 
871   {                                               
872     G4int ty = seT.first;                         
873     G4int seTyp = -1;                             
874     for(auto& worker : fWorkerMap)                
875     {                                             
876       if(worker.second==ty)                       
877       { seTyp = ty; break; }                      
878     }                                             
879     if(seTyp==-1)                                 
880     {                                             
881       G4ExceptionDescription ed;                  
882       ed << "There is no worker with sub-event    
883          << " registered. There must be at lea    
884       G4Exception("G4SubEvtRunManager::CheckSu    
885          "SubEvtRM1210",FatalException,ed);       
886       return false;                               
887     }                                             
888   }                                               
889   return true;                                    
890 }                                                 
891                                                   
892 void G4SubEvtRunManager::SetUserInitialization    
893 {                                                 
894   userWorkerInitialization = userInit;            
895 }                                                 
896                                                   
897 // -------------------------------------------    
898 void G4SubEvtRunManager::SetUserInitialization    
899 {                                                 
900   userWorkerThreadInitialization = userInit;      
901 }                                                 
902                                                   
903 // -------------------------------------------    
904 void G4SubEvtRunManager::SetUserInitialization    
905 {                                                 
906   userActionInitialization = userInit;            
907   userActionInitialization->BuildForMaster();     
908 }                                                 
909                                                   
910 // -------------------------------------------    
911 void G4SubEvtRunManager::SetUserInitialization    
912 {                                                 
913   G4RunManager::SetUserInitialization(userDC);    
914 }                                                 
915                                                   
916 // -------------------------------------------    
917 void G4SubEvtRunManager::SetUserInitialization    
918 {                                                 
919   pl->InitializeWorker();                         
920   G4RunManager::SetUserInitialization(pl);        
921 }                                                 
922                                                   
923 // -------------------------------------------    
924 void G4SubEvtRunManager::SetUserAction(G4UserR    
925 {                                                 
926   G4RunManager::SetUserAction(userAction);        
927   if (userAction != nullptr) userAction->SetMa    
928 }                                                 
929                                                   
930 // -------------------------------------------    
931 void G4SubEvtRunManager::SetUserAction(G4UserE    
932 {                                                 
933   G4RunManager::SetUserAction(ua);                
934 }                                                 
935                                                   
936 // -------------------------------------------    
937 void G4SubEvtRunManager::SetUserAction(G4VUser    
938 {                                                 
939   G4RunManager::SetUserAction(ua);                
940 }                                                 
941                                                   
942 // -------------------------------------------    
943 void G4SubEvtRunManager::SetUserAction(G4UserS    
944 {                                                 
945   G4RunManager::SetUserAction(ua);                
946 }                                                 
947                                                   
948 // -------------------------------------------    
949 void G4SubEvtRunManager::SetUserAction(G4UserT    
950 {                                                 
951   G4RunManager::SetUserAction(ua);                
952 }                                                 
953                                                   
954 // -------------------------------------------    
955 void G4SubEvtRunManager::SetUserAction(G4UserS    
956 {                                                 
957   G4RunManager::SetUserAction(ua);                
958 }                                                 
959                                                   
960                                                   
961