60 void InitializeWindowsConditions();
80 return fMasterRM->MTkernel;
84 nworkers(2),forcedNwokers(-1),
86 nextActionRequest(UNDEFINED),
87 eventModuloDef(0),eventModulo(1),
88 nSeedsUsed(0),nSeedsFilled(0),
89 nSeedsMax(10000),nSeedsPerEvent(2)
94 "Another instance of a G4MTRunManager already exists.");
98 #ifndef G4MULTITHREADED
100 msg <<
"Geant4 code is compiled without multi-threading support"
101 <<
"(-DG4MULTITHREADED is set to off).\n";
102 msg <<
"G4MTRunManager can only be used in multi-threaded applications.";
107 if(numberOfStaticAllocators>0)
110 msg1 <<
"There are " << numberOfStaticAllocators
111 <<
" static G4Allocator objects detected.\n"
112 <<
"In multi-threaded mode, all G4Allocator objects must be dynamicly instantiated.";
123 masterRNGEngine = G4Random::getTheEngine();
125 InitializeWindowsConditions();
131 char* env = getenv(
"G4FORCENUMBEROFTHREADS");
135 if(envS==
"MAX"||envS==
"max")
139 std::istringstream is(env);
143 { forcedNwokers = val; }
147 msg2 <<
"Environment variable G4FORCENUMBEROFTHREADS has an invalid value <"
148 << envS <<
">. It has to be an integer or a word \"max\".\n"
149 <<
"G4FORCENUMBEROFTHREADS is ignored.";
155 nworkers = forcedNwokers;
156 G4cout <<
"### Number of threads is forced to " << forcedNwokers
157 <<
" by Environment variable G4FORCENUMBEROFTHREADS." <<
G4endl;
174 std::ostringstream os;
176 G4Random::saveEngineStatus(os.str().c_str());
181 if ( threads.size() != 0 )
184 msg <<
"Number of threads cannot be changed at this moment \n"
185 <<
"(old threads are still alive). Method ignored.";
186 G4Exception(
"G4MTRunManager::SetNumberOfThreads(G4int)",
189 else if ( forcedNwokers > 0 )
192 msg <<
"Number of threads is forced to " << forcedNwokers
193 <<
" by G4FORCENUMBEROFWORKERS shell variable.\n"
194 <<
"Method ignored.";
195 G4Exception(
"G4MTRunManager::SetNumberOfThreads(G4int)",
229 uiCmdsForWorkers.clear();
231 for ( std::vector<G4String>::const_iterator it = cmdCopy->begin() ;
232 it != cmdCopy->end(); ++it )
233 uiCmdsForWorkers.push_back(*it);
241 return uiCmdsForWorkers;
250 if ( threads.size() == 0 ) {
251 for (
G4int nw = 0 ; nw<nworkers; ++nw) {
257 threads.push_back(thread);
304 msgd <<
"Event modulo is reduced to " <<
eventModulo
305 <<
" to distribute events to all threads.";
306 G4Exception(
"G4MTRunManager::InitializeEventLoop()",
349 nSeedsFilled += nFill;
372 masterWorlds.clear();
374 std::vector<G4VPhysicalVolume*>::iterator itrW
376 for(
size_t iWorld=0;iWorld<nWorlds;iWorld++)
419 "For multi-threaded version, define G4VUserPrimaryGeneratorAction in G4VUserActionInitialization.");
425 "For multi-threaded version, define G4UserEventAction in G4VUserActionInitialization.");
431 "For multi-threaded version, define G4UserStackingAction in G4VUserActionInitialization.");
437 "For multi-threaded version, define G4UserTrackingAction in G4VUserActionInitialization.");
443 "For multi-threaded version, define G4UserSteppingAction in G4VUserActionInitialization.");
449 if(masterScM) masterScM->
Merge(localScoringManager);
466 s1 = helper->
GetSeed(idx_rndm);
467 s2 = helper->
GetSeed(idx_rndm+1);
487 for(
int i=0;i<nev;i++)
506 #ifdef G4MULTITHREADED //protect here to prevent warning in compilation
507 while ( ! threads.empty() )
509 G4Thread* t = * ( threads.begin() );
542 G4cerr <<
"Run is not in progress. AbortRun() ignored." <<
G4endl;
609 #ifdef G4MULTITHREADED
627 G4int numberOfReadyWorkers = 0;
630 G4int numberOfEndOfEventLoopWorkers = 0;
634 G4int numberOfReadyWorkersForNewAction = 0;
637 CRITICAL_SECTION cs1;
638 CRITICAL_SECTION cs2;
639 CRITICAL_SECTION cs3;
645 void InitializeWindowsConditions()
647 #ifdef G4MULTITHREADED
648 InitializeConditionVariable( &beginEventLoopCondition );
649 InitializeConditionVariable( &endEventLoopCondition );
650 InitializeConditionVariable( &numWorkersBeginEventLoopChangeCondition );
651 InitializeConditionVariable( &numWorkersEndEventLoopChangedCondition );
652 InitializeConditionVariable( &requestChangeActionForWorker);
653 InitializeConditionVariable( &numberOfReadyWorkersForNewActionChangedCondition );
655 InitializeCriticalSection( &cs1 );
656 InitializeCriticalSection( &cs2 );
657 InitializeCriticalSection( &cs3 );
667 G4AutoLock lockLoop(&numberOfReadyWorkersMutex);
669 EnterCriticalSection( &cs1 );
672 G4int activethreads = threads.size();
673 if (numberOfReadyWorkers == activethreads )
682 LeaveCriticalSection( &cs1 );
685 &numberOfReadyWorkersMutex);
710 G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
711 numberOfEndOfEventLoopWorkers = 0;
722 G4AutoLock lockLoop(&numberOfReadyWorkersMutex);
724 EnterCriticalSection( &cs1 );
726 ++numberOfReadyWorkers;
732 LeaveCriticalSection( &cs1 );
753 G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
755 EnterCriticalSection( &cs2 );
757 G4int activethreads = threads.size();
758 if ( numberOfEndOfEventLoopWorkers == activethreads )
765 LeaveCriticalSection( &cs2 );
768 &numberOfEndOfEventLoopWorkersMutex);
774 numberOfReadyWorkers = 0;
776 G4AutoLock l2(&numberOfEndOfEventLoopWorkersMutex);
784 G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
786 EnterCriticalSection( &cs2 );
788 ++numberOfEndOfEventLoopWorkers;
794 LeaveCriticalSection( &cs2 );
796 G4CONDITIONWAIT(&endEventLoopCondition,&numberOfEndOfEventLoopWorkersMutex);
806 G4AutoLock l(&numberOfReadyWorkersForNewActionMutex);
808 EnterCriticalSection( &cs3 );
811 G4int activethreads = threads.size();
812 if ( numberOfReadyWorkersForNewAction == activethreads )
821 LeaveCriticalSection( &cs3 );
824 &numberOfReadyWorkersForNewActionMutex);
832 G4AutoLock l2(&numberOfReadyWorkersForNewActionMutex);
833 numberOfReadyWorkersForNewAction = 0;
846 G4AutoLock l(&numberOfReadyWorkersForNewActionMutex);
848 EnterCriticalSection( &cs3 );
850 ++numberOfReadyWorkersForNewAction;
856 LeaveCriticalSection( &cs3 );
858 G4CONDITIONWAIT(&requestChangeActionForWorker,&numberOfReadyWorkersForNewActionMutex);
virtual void InitializeEventLoop(G4int n_event, const char *macroFile=0, G4int n_select=-1)
void SetMaster(G4bool val=true)
static G4TemplateRNGHelper * GetInstance()
std::vector< G4String > GetCommandStack()
virtual void PrepareCommandsStack()
virtual void SetUserInitialization(G4VUserDetectorConstruction *userInit)
virtual void Merge(const G4Run *)
std::map< G4int, G4VPhysicalVolume * > masterWorlds_t
void Fill(double *dbl, int nev, int nev_tot, int nrpe)
virtual G4bool SetUpAnEvent(G4Event *, long &s1, long &s2, long &s3)
void SetUpDecayChannels()
G4int numberOfEventProcessed
static void addWorld(G4int counter, G4VPhysicalVolume *w)
WorkerActionRequest nextActionRequest
virtual void RunTermination()
std::ostringstream G4ExceptionDescription
virtual void ThisWorkerEndEventLoop()
void SetNumberOfThreads(G4int n)
std::vector< G4VPhysicalVolume * >::iterator GetWorldsIterator()
G4VUserActionInitialization * userActionInitialization
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
#define G4CONDTIONBROADCAST(cond)
G4UserWorkerThreadInitialization * userWorkerThreadInitialization
virtual G4bool InitializeSeeds(G4int)
G4double G4NeutronHPJENDLHEData::G4double result
virtual void ConstructScoringWorlds()
virtual void BeamOn(G4int n_event, const char *macroFile=0, G4int n_select=-1)
virtual void BuildForMaster() const
virtual void RunTermination()
virtual const T GetSeed(const G4int &sdId)
virtual void InitializePhysics()
void SetThreadId(G4int threadId)
#define G4CONDITIONWAIT(cond, mutex)
std::vector< G4String > * GetCommandStack()
virtual void SetUserAction(G4UserRunAction *userAction)
#define G4MUTEX_INITIALIZER
std::queue< long > G4SeedsQueue
virtual void WaitForEndEventLoopWorkers()
virtual void TerminateOneEvent()
static G4UImanager * GetUIpointer()
virtual void TerminateWorkers()
static G4StateManager * GetStateManager()
static G4RunManagerKernel * GetMasterRunManagerKernel()
G4GLOB_DLL std::ostream G4cout
virtual void InitializePhysics()
void MergeRun(const G4Run *localRun)
static G4ScoringManager * GetScoringManagerIfExist()
void Refill(double *dbl, int nev)
G4UserWorkerInitialization * userWorkerInitialization
G4String randomNumberStatusDir
virtual void ProcessOneEvent(G4int i_event)
virtual void ConstructScoringWorlds()
virtual void WaitForReadyWorkers()
virtual G4int SetUpNEvents(G4Event *, G4SeedsQueue *seedsQueue)
static G4MTRunManager * GetMasterRunManager()
G4int G4GetNumberOfCores()
virtual WorkerActionRequest ThisWorkerWaitForNextAction()
virtual void SetUserInitialization(G4VUserPhysicsList *userPL)
virtual void AbortRun(G4bool softAbort=false)
G4ApplicationState GetCurrentState() const
virtual void NewActionRequest(WorkerActionRequest newRequest)
void Merge(const G4ScoringManager *scMan)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static G4TransportationManager * GetTransportationManager()
virtual void Initialize()
virtual void ThisWorkerReady()
virtual void AbortEvent()
void SetRunIDCounter(G4int i)
virtual G4Thread * CreateAndStartWorker(G4WorkerThread *workerThreadContext)
virtual ~G4MTRunManager()
virtual void Initialize()
size_t GetNoWorlds() const
G4int numberOfEventToBeProcessed
G4int GetNumberOfStaticAllocators() const
G4RunManagerKernel * kernel
void BroadcastAbortRun(G4bool softAbort)
static G4MTRunManagerKernel * GetMTMasterRunManagerKernel()
virtual void flatArray(const int size, double *vect)=0
virtual void JoinWorker(G4Thread *aThread)
void SetNumberThreads(G4int numnberThreads)
void MergeScores(const G4ScoringManager *localScoringManager)
virtual void TerminateEventLoop()
void SetMasterUIManager(G4bool val)
virtual void StoreRNGStatus(const G4String &filenamePrefix)
G4GLOB_DLL std::ostream G4cerr
virtual void SetUserAction(G4UserRunAction *userAction)
virtual void CreateAndStartWorkers()
#define G4CONDITION_INITIALIZER