Import Geant4 10.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2016-06-30 14:12:05 +02:00
parent a654a7ab1f
commit 4ec577e5c4
2021 changed files with 100995 additions and 78277 deletions
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4AdjointPrimaryGeneratorAction.cc 81773 2014-06-05 08:35:38Z gcosmo $
// $Id: G4AdjointPrimaryGeneratorAction.cc 97327 2016-06-01 14:24:40Z gcosmo $
//
/////////////////////////////////////////////////////////////////////////////
// Class Name: G4AdjointPrimaryGeneratorAction
@@ -61,7 +61,7 @@ G4AdjointPrimaryGeneratorAction::G4AdjointPrimaryGeneratorAction()
ListOfPrimaryFwdParticles.clear();
ListOfPrimaryAdjParticles.clear();
nb_fwd_gammas_per_event = 10;
nb_fwd_gammas_per_event = 1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -72,7 +72,9 @@ G4AdjointPrimaryGeneratorAction::~G4AdjointPrimaryGeneratorAction()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void G4AdjointPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{ G4int evt_id=anEvent->GetEventID();
{
G4int evt_id=anEvent->GetEventID();
size_t n=ListOfPrimaryAdjParticles.size();
index_particle=size_t(evt_id)-n*(size_t(evt_id)/n);
@@ -146,7 +148,7 @@ void G4AdjointPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
//The factor pi is to normalise the weight to the directional flux
G4double adjoint_source_area = G4AdjointSimManager::GetInstance()->GetAdjointSourceArea();
G4double adjoint_weight = weight_correction*ComputeEnergyDistWeight(ekin,E1,E2)*adjoint_source_area*pi;
if (ListOfPrimaryFwdParticles[index_particle] ==G4Gamma::Gamma()) adjoint_weight = adjoint_weight/3.;
//if (ListOfPrimaryFwdParticles[index_particle] ==G4Gamma::Gamma()) adjoint_weight = adjoint_weight/3.;
adjPrimVertex->SetWeight(adjoint_weight);
@@ -155,7 +157,6 @@ void G4AdjointPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
G4AdjointSimManager::GetInstance()->SetAdjointTrackingMode(true);
/* if ( !last_generated_part_was_adjoint ) {
index_particle++;
@@ -309,12 +310,14 @@ void G4AdjointPrimaryGeneratorAction::UpdateListOfPrimaryParticles()
G4String adj_particle_name = G4String("adj_") + fwd_particle_name;
ListOfPrimaryFwdParticles.push_back(theParticleTable->FindParticle(fwd_particle_name));
ListOfPrimaryAdjParticles.push_back(theParticleTable->FindParticle(adj_particle_name));
/*
if ( fwd_particle_name == "gamma") {
for (G4int i=0;i<2;i++){
ListOfPrimaryFwdParticles.push_back(theParticleTable->FindParticle(fwd_particle_name));
ListOfPrimaryAdjParticles.push_back(theParticleTable->FindParticle(adj_particle_name));
}
}
*/
}
else {
if (fwd_ion ){
+12 -6
View File
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4AdjointSimManager.cc 86968 2014-11-21 11:52:04Z gcosmo $
// $Id: G4AdjointSimManager.cc 97327 2016-06-01 14:24:40Z gcosmo $
//
/////////////////////////////////////////////////////////////////////////////
// Class Name: G4AdjointCrossSurfChecker
@@ -102,10 +102,10 @@ G4AdjointSimManager::G4AdjointSimManager():
//Define user action and set this class instance as RunAction
//----------------
DefineUserActions();
G4RunManager* theRunManager = G4RunManager::GetRunManager();
//DefineUserActions();
//G4RunManager* theRunManager = G4RunManager::GetRunManager();
theRunManager->G4RunManager::SetUserAction(this);
//theRunManager->G4RunManager::SetUserAction(this);
/*
#ifdef G4MULTITHREADED
@@ -158,6 +158,7 @@ void G4AdjointSimManager::RunAdjointSimulation(G4int nb_evt)
//------------
nb_evt_of_last_run =nb_evt;
G4cout<<"Test Sim Adjoint1"<<std::endl;
G4RunManager::GetRunManager()->BeamOn(nb_evt*theAdjointPrimaryGeneratorAction->GetNbOfAdjointPrimaryTypes());
//G4RunManager::GetRunManager()->BeamOn(theAdjointPrimaryGeneratorAction->GetNbOfAdjointPrimaryTypes()*2*nb_evt);
@@ -233,9 +234,10 @@ void G4AdjointSimManager::SetAdjointActions()
if (!user_action_already_defined) DefineUserActions();
//Replace the user action by the adjoint actions
//-------------------------------------------------
theRunManager->G4RunManager::SetUserAction(this);
theRunManager->G4RunManager::SetUserAction(theAdjointPrimaryGeneratorAction);
theRunManager->G4RunManager::SetUserAction(theAdjointStackingAction);
if (use_user_StackingAction) theAdjointStackingAction->SetUserFwdStackingAction(fUserStackingAction);
@@ -271,7 +273,7 @@ void G4AdjointSimManager::ResetUserActions()
//Restore the user defined actions
//-------------------------------
theRunManager->G4RunManager::SetUserAction(fUserRunAction);
theRunManager->G4RunManager::SetUserAction(fUserEventAction);
theRunManager->G4RunManager::SetUserAction(fUserSteppingAction);
theRunManager->G4RunManager::SetUserAction(fUserTrackingAction);
@@ -620,12 +622,16 @@ void G4AdjointSimManager::SetNbOfPrimaryFwdGammasPerEvent(G4int nb)
void G4AdjointSimManager::BeginOfRunAction(const G4Run* aRun)
{
/*
if (!adjoint_sim_mode){
if(fUserRunAction) fUserRunAction->BeginOfRunAction(aRun);
}
else {
if (theAdjointRunAction) theAdjointRunAction->BeginOfRunAction(aRun);
}
*/
fUserRunAction->BeginOfRunAction(aRun);
}
///////////////////////////////////////////////////////////////////////////////
//
+45 -325
View File
@@ -55,13 +55,6 @@ namespace {
G4Mutex setUpEventMutex = G4MUTEX_INITIALIZER;
}
//This is needed to initialize windows conditions
#if defined(WIN32)
namespace {
void InitializeWindowsConditions();
}
#endif
G4MTRunManager* G4MTRunManager::GetMasterRunManager()
{
////////#ifdef G4MULTITHREADED
@@ -84,14 +77,14 @@ G4MTRunManagerKernel* G4MTRunManager::GetMTMasterRunManagerKernel()
G4MTRunManager::G4MTRunManager() : G4RunManager(masterRM),
nworkers(2),forcedNwokers(-1),pinAffinity(0),
masterRNGEngine(0),
nextActionRequest(UNDEFINED),
nextActionRequest(WorkerActionRequest::UNDEFINED),
eventModuloDef(0),eventModulo(1),
nSeedsUsed(0),nSeedsFilled(0),
nSeedsMax(10000),nSeedsPerEvent(2)
{
if ( fMasterRM )
{
G4Exception("G4MTRunManager::G4MTRunManager", "Run0035",FatalException,
G4Exception("G4MTRunManager::G4MTRunManager", "Run0110",FatalException,
"Another instance of a G4MTRunManager already exists.");
}
fMasterRM = this;
@@ -101,7 +94,7 @@ G4MTRunManager::G4MTRunManager() : G4RunManager(masterRM),
msg << "Geant4 code is compiled without multi-threading support"
<< "(-DG4MULTITHREADED is set to off).\n";
msg << "G4MTRunManager can only be used in multi-threaded applications.";
G4Exception("G4MTRunManager::G4MTRunManager","Run0035",FatalException,msg);
G4Exception("G4MTRunManager::G4MTRunManager","Run0111",FatalException,msg);
#endif
G4int numberOfStaticAllocators = kernel->GetNumberOfStaticAllocators();
@@ -122,9 +115,6 @@ G4MTRunManager::G4MTRunManager() : G4RunManager(masterRM),
//G4Random::getTheEngine(); //User did not specify RNG, create defaults
//Now remember the master instance of the RNG Engine
masterRNGEngine = G4Random::getTheEngine();
#if defined (WIN32)
InitializeWindowsConditions();
#endif
numberOfEventToBeProcessed = 0;
randDbl = new double[nSeedsPerEvent*nSeedsMax];
@@ -185,7 +175,7 @@ void G4MTRunManager::SetNumberOfThreads(G4int n )
msg << "Number of threads cannot be changed at this moment \n"
<< "(old threads are still alive). Method ignored.";
G4Exception("G4MTRunManager::SetNumberOfThreads(G4int)",
"Run0035", JustWarning, msg);
"Run0112", JustWarning, msg);
}
else if ( forcedNwokers > 0 )
{
@@ -194,7 +184,7 @@ void G4MTRunManager::SetNumberOfThreads(G4int n )
<< " by G4FORCENUMBEROFTHREADS shell variable.\n"
<< "Method ignored.";
G4Exception("G4MTRunManager::SetNumberOfThreads(G4int)",
"Run0035", JustWarning, msg);
"Run0113", JustWarning, msg);
}
else
{
@@ -259,7 +249,7 @@ void G4MTRunManager::CreateAndStartWorkers()
}
}
//Signal to threads they can start a new run
NewActionRequest(NEXTITERATION);
NewActionRequest(WorkerActionRequest::NEXTITERATION);
}
@@ -448,31 +438,31 @@ void G4MTRunManager::SetUserAction(G4UserRunAction* userAction)
void G4MTRunManager::SetUserAction(G4VUserPrimaryGeneratorAction* /*userAction*/)
{
G4Exception("G4MTRunManager::SetUserAction()", "Run3011", FatalException,
G4Exception("G4MTRunManager::SetUserAction()", "Run0123", FatalException,
"For multi-threaded version, define G4VUserPrimaryGeneratorAction in G4VUserActionInitialization.");
}
void G4MTRunManager::SetUserAction(G4UserEventAction* /*userAction*/)
{
G4Exception("G4MTRunManager::SetUserAction()", "Run3011", FatalException,
G4Exception("G4MTRunManager::SetUserAction()", "Run0124", FatalException,
"For multi-threaded version, define G4UserEventAction in G4VUserActionInitialization.");
}
void G4MTRunManager::SetUserAction(G4UserStackingAction* /*userAction*/)
{
G4Exception("G4MTRunManager::SetUserAction()", "Run3011", FatalException,
G4Exception("G4MTRunManager::SetUserAction()", "Run0125", FatalException,
"For multi-threaded version, define G4UserStackingAction in G4VUserActionInitialization.");
}
void G4MTRunManager::SetUserAction(G4UserTrackingAction* /*userAction*/)
{
G4Exception("G4MTRunManager::SetUserAction()", "Run3011", FatalException,
G4Exception("G4MTRunManager::SetUserAction()", "Run0126", FatalException,
"For multi-threaded version, define G4UserTrackingAction in G4VUserActionInitialization.");
}
void G4MTRunManager::SetUserAction(G4UserSteppingAction* /*userAction*/)
{
G4Exception("G4MTRunManager::SetUserAction()", "Run3011", FatalException,
G4Exception("G4MTRunManager::SetUserAction()", "Run0127", FatalException,
"For multi-threaded version, define G4UserSteppingAction in G4VUserActionInitialization.");
}
@@ -542,7 +532,10 @@ G4int G4MTRunManager::SetUpNEvents(G4Event* evt, G4SeedsQueue* seedsQueue,G4bool
void G4MTRunManager::TerminateWorkers()
{
NewActionRequest( ENDWORKER );
//Force workers to execute (if any) all UI commands left in the stack
RequestWorkersProcessCommandsStack();
//Ask workers to exit
NewActionRequest( WorkerActionRequest::ENDWORKER );
//Now join threads.
#ifdef G4MULTITHREADED //protect here to prevent warning in compilation
while ( ! threads.empty() )
@@ -578,328 +571,55 @@ void G4MTRunManager::AbortEvent()
// nothing to do in the master thread
}
// =====================================
// Barriers mechanism
// =====================================
// We want to implement barriers.
// We define a barrier has a point in which threads synchronize.
// When workers threads reach a barrier they wait for the master thread a
// signal that they can continue. The master thread broadcast this signal
// only when all worker threads have reached this point.
// Currently only three points require this sync in the life-time of a G4 applicattion:
// Just before and just after the for-loop controlling the thread event-loop.
// Between runs.
// TODO: If this mechanism is needed in other parts of the code we can provide
// the barrier mechanism as a utility class/functions to the kernel.
// Note: we need a special treatment for WIN32
//
// The basic algorith of each barrier works like this:
// In the master:
// WaitWorkers() {
// while (true)
// {
// G4AutoLock l(&counterMutex); || Mutex is locked (1)
// if ( counter == nActiveThreads ) break;
// G4CONDITIONWAIT( &conditionOnCounter, &counterMutex); || Mutex is atomically released and wait, upon return locked (2)
// } || unlock mutex
// G4AutoLock l(&counterMutex); || lock again mutex (3)
// G4CONDITIONBROADCAST( &doSomethingCanStart ); || Here mutex is locked (4)
// } || final unlock (5)
// In the workers:
// WaitSignalFromMaster() {
// G4AutoLock l(&counterMutex); || (6)
// ++counter;
// G4CONDITIONBROADCAST(&conditionOnCounter); || (7)
// G4CONDITIONWAIT( &doSomethingCanStart , &counterMutex);|| (8)
// }
// Each barriers requires 2 conditions and one mutex, plus a counter.
// Important note: the thread calling broadcast should hold the mutex
// before calling broadcast to obtain predictible behavior
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_broadcast.html
// Also remember that the wait for condition will atomically release the mutex
// and wait on condition, but it will lock again on mutex when returning
// Here it is how the control flows.
// Imagine master starts and only one worker (nActiveThreads==1)
// Master | Worker | counter | Who holds mutex
// Gets to (1) | Blocks on (6) | 0 | M
// Waits in (2) | | 0 | -
// | Arrives to (7) | 1 | W
// | Waits in (8) | 1 | -
// Gets to (1) | | 1 | M
// Jumps to (3) | | 1 | M
// End | | 1 | -
// | End | 1 | -
// Similarly for more than one worker threads or if worker starts
#ifdef WIN32
#include <windows.h> //For CRITICAL_SECTION objects
#endif
namespace {
//Avoid compilation warning if squenetial for unused variables
#ifdef G4MULTITHREADED
//Conditions
// Condition to signal green light for start of event loop
G4Condition beginEventLoopCondition = G4CONDITION_INITIALIZER;
// Condition to signal green light to finish event loop
// (actuallyt exit function performing event loop)
G4Condition endEventLoopCondition = G4CONDITION_INITIALIZER;
// Condition to signal the num of workers ready for event loop has changed
G4Condition numWorkersBeginEventLoopChangeCondition = G4CONDITION_INITIALIZER;
// Condition to signal the num of workers that terminated event loop
// has changed
G4Condition numWorkersEndEventLoopChangedCondition = G4CONDITION_INITIALIZER;
// This condition is to handle more than one run w/o killing threads
G4Condition requestChangeActionForWorker = G4CONDITION_INITIALIZER;
G4Condition numberOfReadyWorkersForNewActionChangedCondition = G4CONDITION_INITIALIZER;
#endif
// Counter/mutex for workers ready to begin event loop
G4Mutex numberOfReadyWorkersMutex = G4MUTEX_INITIALIZER;
G4int numberOfReadyWorkers = 0;
//Counter/mutex for workers with end of event loop
G4Mutex numberOfEndOfEventLoopWorkersMutex = G4MUTEX_INITIALIZER;
G4int numberOfEndOfEventLoopWorkers = 0;
//
//Action handling
G4Mutex nextActionRequestMutex = G4MUTEX_INITIALIZER;
G4int numberOfReadyWorkersForNewAction = 0;
G4Mutex numberOfReadyWorkersForNewActionMutex = G4MUTEX_INITIALIZER;
#ifdef WIN32
CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2;
CRITICAL_SECTION cs3;
//Note we need to use two separate counters because
//we can get a situation in which a thread is much faster then the others
//(for example if last thread has less events to process.
//We have the extreme case of some medical applications (moving setups)
//in which the number of events of a run is ~ number of threads
void InitializeWindowsConditions()
{
#ifdef G4MULTITHREADED
InitializeConditionVariable( &beginEventLoopCondition );
InitializeConditionVariable( &endEventLoopCondition );
InitializeConditionVariable( &numWorkersBeginEventLoopChangeCondition );
InitializeConditionVariable( &numWorkersEndEventLoopChangedCondition );
InitializeConditionVariable( &requestChangeActionForWorker);
InitializeConditionVariable( &numberOfReadyWorkersForNewActionChangedCondition );
#endif
InitializeCriticalSection( &cs1 );
InitializeCriticalSection( &cs2 );
InitializeCriticalSection( &cs3 );
}
#endif
void G4MTRunManager::WaitForReadyWorkers() {
beginOfEventLoopBarrier.Wait( GetNumberActiveThreads() );
endOfEventLoopBarrier.ResetCounter();
beginOfEventLoopBarrier.ReleaseBarrier();
}
void G4MTRunManager::WaitForReadyWorkers()
{
while (true) //begin barrier
{
#ifndef WIN32
G4AutoLock lockLoop(&numberOfReadyWorkersMutex);
#else
EnterCriticalSection( &cs1 );
#endif
//Check number of workers ready to begin
G4int activethreads = threads.size();
if (numberOfReadyWorkers == activethreads )
{
//Ok, interrupt the loop
break;
}
//Wait for the number of workers to be changed
#ifdef WIN32
G4CONDITIONWAIT(&numWorkersBeginEventLoopChangeCondition,
&cs1);
LeaveCriticalSection( &cs1 );
#else
G4CONDITIONWAIT(&numWorkersBeginEventLoopChangeCondition,
&numberOfReadyWorkersMutex);
#endif
}
//Now number of workers is as expected.
////// static G4bool createIsomerOnlyOnce = false;
////// if(!createIsomerOnlyOnce)
////// {
////// createIsomerOnlyOnce = true;
////// G4ParticleDefinition* gion = G4ParticleTable::GetParticleTable()->GetGenericIon();
////// if(gion)
////// {
////// ////G4ParticleTable::GetParticleTable()->GetIonTable()->CreateAllIsomer();
////// G4int gionId = gion->GetParticleDefinitionID();
////// G4ParticleTable::G4PTblDicIterator* pItr = G4ParticleTable::GetParticleTable()->GetIterator();
////// pItr->reset(false);
////// while( (*pItr)() )
////// {
////// G4ParticleDefinition* particle = pItr->value();
////// if(particle->IsGeneralIon()) particle->SetParticleDefinitionID(gionId);
////// }
////// }
////// }
//Prepare to wait for workers to end eventloop
//Reset number of workers in "EndOfEventLoop"
G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
numberOfEndOfEventLoopWorkers = 0;
//signal workers they can start the event-loop
G4AutoLock l2(&numberOfReadyWorkersMutex);
G4CONDTIONBROADCAST(&beginEventLoopCondition);
void G4MTRunManager::ThisWorkerReady() {
beginOfEventLoopBarrier.ThisWorkerReady();
}
void G4MTRunManager::ThisWorkerReady()
{
//Increament number of active worker by 1
#ifndef WIN32
G4AutoLock lockLoop(&numberOfReadyWorkersMutex);
#else
EnterCriticalSection( &cs1 );
#endif
++numberOfReadyWorkers;
//Signal the number of workers has changed
G4CONDTIONBROADCAST(&numWorkersBeginEventLoopChangeCondition);
//Wait for condition to start eventloop
#ifdef WIN32
G4CONDITIONWAIT(&beginEventLoopCondition,&cs1);
LeaveCriticalSection( &cs1 );
#else
G4CONDITIONWAIT(&beginEventLoopCondition,&numberOfReadyWorkersMutex);
#endif
//Protects access to shared resource, guarantees we do not call this method
//while someone else is modifying its content (e.g. creating a new particle)
//G4PDefManager& pdm = const_cast<G4PDefManager&>(G4ParticleDefinition::GetSubInstanceManager());
//pdm.Lock();
//pdm.NewSubInstances();
//pdm.UnLock();
//const_cast<G4PDefManager&>(G4ParticleDefinition::GetSubInstanceManager()).NewSubInstances();
// I believe this is not necessary and safe to remove (Makoto)
//G4ParticleTable::GetParticleTable()->WorkerG4ParticleTable();
void G4MTRunManager::WaitForEndEventLoopWorkers() {
endOfEventLoopBarrier.Wait( GetNumberActiveThreads() );
beginOfEventLoopBarrier.ResetCounter();
endOfEventLoopBarrier.ReleaseBarrier();
}
void G4MTRunManager::WaitForEndEventLoopWorkers()
{
while (true)
{
#ifndef WIN32
G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
#else
EnterCriticalSection( &cs2 );
#endif
G4int activethreads = threads.size();
if ( numberOfEndOfEventLoopWorkers == activethreads )
{
break;
}
#ifdef WIN32
G4CONDITIONWAIT(&numWorkersEndEventLoopChangedCondition,
&cs2);
LeaveCriticalSection( &cs2 );
#else
G4CONDITIONWAIT(&numWorkersEndEventLoopChangedCondition,
&numberOfEndOfEventLoopWorkersMutex);
#endif
}
//Now number of workers that reached end of event loop is as expected
//Reset number of workers in ready for work state so a new run can start
G4AutoLock l(&numberOfReadyWorkersMutex);
numberOfReadyWorkers = 0;
//Signal workers they can end event-loop
G4AutoLock l2(&numberOfEndOfEventLoopWorkersMutex);
G4CONDTIONBROADCAST(&endEventLoopCondition);
void G4MTRunManager::ThisWorkerEndEventLoop() {
endOfEventLoopBarrier.ThisWorkerReady();
}
void G4MTRunManager::ThisWorkerEndEventLoop()
{
//Increament number of workers in end of evnet loop by 1
#ifndef WIN32
G4AutoLock l(&numberOfEndOfEventLoopWorkersMutex);
#else
EnterCriticalSection( &cs2 );
#endif
++numberOfEndOfEventLoopWorkers;
//Signale this number has changed
G4CONDTIONBROADCAST(&numWorkersEndEventLoopChangedCondition);
//Wait for condition to exit eventloop
#ifdef WIN32
G4CONDITIONWAIT(&endEventLoopCondition,&cs2);
LeaveCriticalSection( &cs2 );
#else
G4CONDITIONWAIT(&endEventLoopCondition,&numberOfEndOfEventLoopWorkersMutex);
#endif
void G4MTRunManager::NewActionRequest(G4MTRunManager::WorkerActionRequest newRequest) {
nextActionRequestBarrier.Wait( GetNumberActiveThreads() );
//nextActionRequest is a shared resource, but there is no
//data-race thanks to the barrier: all threads are waiting
nextActionRequest = newRequest;
nextActionRequestBarrier.ReleaseBarrier();
}
void G4MTRunManager::NewActionRequest(G4MTRunManager::WorkerActionRequest newRequest)
{
//Wait for all workers to be ready to accept a new action request
while (true)
{
#ifndef WIN32
G4AutoLock l(&numberOfReadyWorkersForNewActionMutex);
#else
EnterCriticalSection( &cs3 );
#endif
//Check the number of workers that are ready for next action
G4int activethreads = threads.size();
if ( numberOfReadyWorkersForNewAction == activethreads )
{
//Ok, exit the loop
break;
}
//Wait for the number of workers ready for new action to change
#ifdef WIN32
G4CONDITIONWAIT(&numberOfReadyWorkersForNewActionChangedCondition,
&cs3);
LeaveCriticalSection( &cs3 );
#else
G4CONDITIONWAIT(&numberOfReadyWorkersForNewActionChangedCondition,
&numberOfReadyWorkersForNewActionMutex);
#endif
}
//Now set the new action to the shared resource
G4AutoLock l(&nextActionRequestMutex);
nextActionRequest = newRequest;
l.unlock();
//Reset counter of workers ready-for-new-action in preparation of next call
G4AutoLock l2(&numberOfReadyWorkersForNewActionMutex);
numberOfReadyWorkersForNewAction = 0;
//l2.unlock(); //<----- This thread needs to have control on mutex associated
//to condition variable (report from valgrind --tool=drd)
//see: http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fapis%2Fusers_73.htm
//Now signal all workers that there is a new action to be performed
G4CONDTIONBROADCAST(&requestChangeActionForWorker);
G4MTRunManager::WorkerActionRequest G4MTRunManager::ThisWorkerWaitForNextAction() {
nextActionRequestBarrier.ThisWorkerReady();
return nextActionRequest;
}
G4MTRunManager::WorkerActionRequest G4MTRunManager::ThisWorkerWaitForNextAction()
{
//This worker is ready to receive a new action request,
//increment counter by 1
#ifndef WIN32
G4AutoLock l(&numberOfReadyWorkersForNewActionMutex);
#else
EnterCriticalSection( &cs3 );
#endif
++numberOfReadyWorkersForNewAction;
//Singal the sahred resource has changed to the master
G4CONDTIONBROADCAST(&numberOfReadyWorkersForNewActionChangedCondition);
//Wait for condition that a new aciton is ready
#ifdef WIN32
G4CONDITIONWAIT(&requestChangeActionForWorker,&cs3);
LeaveCriticalSection( &cs3 );
#else
G4CONDITIONWAIT(&requestChangeActionForWorker,&numberOfReadyWorkersForNewActionMutex);
#endif
//Ok, if I am here it means that a new action has been requested by the master
//reads it value that is now read-only, so no mutex is needed, but you never know...
G4AutoLock l2(&nextActionRequestMutex);
WorkerActionRequest result = nextActionRequest;
return result;
void G4MTRunManager::RequestWorkersProcessCommandsStack() {
PrepareCommandsStack();
NewActionRequest(WorkerActionRequest::PROCESSUI);
processUIBarrier.SetActiveThreads( GetNumberActiveThreads() );
processUIBarrier.WaitForReadyWorkers();
}
void G4MTRunManager::ThisWorkerProcessCommandsStackDone() {
processUIBarrier.ThisWorkerReady();
}
void G4MTRunManager::SetPinAffinity(G4int n)
{
if ( n == 0 )
{
G4Exception("G4MTRunManager::SetPinAffinity",
"Run0035",FatalException,
"Run0114",FatalException,
"Pin affinity must be >0 or <0.");
}
pinAffinity = n;
+1 -1
View File
@@ -42,7 +42,7 @@ G4MTRunManagerKernel::G4MTRunManagerKernel() : G4RunManagerKernel(masterRMK)
G4ExceptionDescription msg;
msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
msg<<" This type of RunManager can only be used in mult-threaded applications.";
G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0035",FatalException,msg);
G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0109",FatalException,msg);
#endif
G4AutoLock l(&workerRMMutex);
if(!workerRMvector) workerRMvector = new std::vector<G4WorkerRunManager*>;
+77
View File
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4MultiRunAction.hh 90212 2016-01-27 18:33:12Z adotti $
//
//---------------------------------------------------------------
//
// G4MultiRunAction.hh
//
// Created on: Jan 17, 2016
// Author: adotti
//
// ---------------------------------------------------------------
//
#include "G4MultiRunAction.hh"
#include "G4Run.hh"
#include <algorithm>
G4Run* G4MultiRunAction::GenerateRun() {
G4Run* aRun = nullptr;
for ( auto& ru : *this ) {
auto anotherRun = ru->GenerateRun();
if ( aRun != nullptr && anotherRun != nullptr ) {
G4Exception("G4MultiRunAction::GenerateRun()","Run0036",FatalException,
"More than one registered UserRunAction return an instance"\
" of G4Run, not allowed.");
return nullptr;
}
aRun = anotherRun;
}
return aRun;
}
void G4MultiRunAction::BeginOfRunAction(const G4Run* run) {
std::for_each( begin() , end() ,
[run](G4UserRunActionUPtr& e) { e->BeginOfRunAction(run); }
);
}
void G4MultiRunAction::EndOfRunAction(const G4Run* run) {
std::for_each( begin() , end() ,
[run](G4UserRunActionUPtr& e) { e->EndOfRunAction(run); }
);
}
void G4MultiRunAction::SetMaster(G4bool val) {
G4UserRunAction::SetMaster(val);
std::for_each( begin() , end() ,
[val](G4UserRunActionUPtr& e) { e->SetMaster(val); }
);
}
+13 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4PhysicsListHelper.cc 82663 2014-07-02 08:57:58Z gcosmo $
// $Id: G4PhysicsListHelper.cc 97386 2016-06-02 10:01:40Z gcosmo $
//
//
// ------------------------------------------------------------
@@ -676,7 +676,7 @@ void G4PhysicsListHelper::ReadInDefaultOrderingParameter()
tmp.processSubType = 10;
tmp.ordering[0] = -1;
tmp.ordering[1] = 1;
tmp.ordering[2] = 1;
tmp.ordering[2] = -1;
tmp.isDuplicable = false;
theTable->push_back(tmp);
sizeOfTable +=1;
@@ -1064,7 +1064,7 @@ void G4PhysicsListHelper::ReadInDefaultOrderingParameter()
tmp.processTypeName = "DecayUnKnown";
tmp.processType = 6;
tmp.processSubType = 211;
tmp.ordering[0] = 1000;
tmp.ordering[0] = -1;
tmp.ordering[1] = -1;
tmp.ordering[2] = 1000;
tmp.isDuplicable = false;
@@ -1110,6 +1110,16 @@ void G4PhysicsListHelper::ReadInDefaultOrderingParameter()
tmp.isDuplicable = false;
theTable->push_back(tmp);
sizeOfTable +=1;
tmp.processTypeName = "ParallelWorld";
tmp.processType = 10;
tmp.processSubType = 491;
tmp.ordering[0] = 9900;
tmp.ordering[1] = 1;
tmp.ordering[2] = 9900;
tmp.isDuplicable = true;
theTable->push_back(tmp);
sizeOfTable +=1;
}
+12 -8
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4RunManager.cc 90233 2015-05-21 08:56:28Z gcosmo $
// $Id: G4RunManager.cc 95232 2016-02-01 14:31:22Z gcosmo $
//
//
@@ -59,10 +59,10 @@
#include "G4UImanager.hh"
#include "G4ProductionCutsTable.hh"
#include "G4ParallelWorldProcessStore.hh"
#include "G4ios.hh"
#include <sstream>
using namespace CLHEP;
G4ThreadLocal G4RunManager* G4RunManager::fRunManager = 0;
@@ -139,7 +139,7 @@ G4RunManager::G4RunManager( RMType rmType )
G4ExceptionDescription msg;
msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
msg<<" This type of RunManager can only be used in mult-threaded applications.";
G4Exception("G4RunManager::G4RunManager(G4bool)","Run0035",FatalException,msg);
G4Exception("G4RunManager::G4RunManager(G4bool)","Run0107",FatalException,msg);
#endif
if(fRunManager)
@@ -161,7 +161,7 @@ G4RunManager::G4RunManager( RMType rmType )
default:
G4ExceptionDescription msgx;
msgx<<" This type of RunManager can only be used in mult-threaded applications.";
G4Exception("G4RunManager::G4RunManager(G4bool)","Run0035",FatalException,msgx);
G4Exception("G4RunManager::G4RunManager(G4bool)","Run0108",FatalException,msgx);
return;
}
runManagerType = rmType;
@@ -765,9 +765,9 @@ void G4RunManager::ConstructScoringWorlds()
{
pmanager->AddProcess(theParallelWorldProcess);
if(theParallelWorldProcess->IsAtRestRequired(particle))
{ pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9999); }
{ pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9900); }
pmanager->SetProcessOrderingToSecond(theParallelWorldProcess, idxAlongStep);
pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9999);
pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9900);
}
}
}
@@ -860,10 +860,14 @@ void G4RunManager::SetUserInitialization(G4VUserActionInitialization* userInit)
}
void G4RunManager::SetUserAction(G4UserRunAction* userAction)
{ userRunAction = userAction; }
{
userRunAction = userAction;
}
void G4RunManager::SetUserAction(G4VUserPrimaryGeneratorAction* userAction)
{ userPrimaryGeneratorAction = userAction; }
{
userPrimaryGeneratorAction = userAction;
}
void G4RunManager::SetUserAction(G4UserEventAction* userAction)
{
+3 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4RunManagerKernel.cc 90233 2015-05-21 08:56:28Z gcosmo $
// $Id: G4RunManagerKernel.cc 95232 2016-02-01 14:31:22Z gcosmo $
//
//
@@ -156,7 +156,7 @@ numberOfParallelWorld(0),geometryNeedsToBeClosed(true),
G4ExceptionDescription msg;
msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
msg<<" This type of RunManagerKernel can only be used in mult-threaded applications.";
G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)","Run0035",FatalException,msg);
G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)","Run0105",FatalException,msg);
#endif
#ifdef G4FPE_DEBUG
@@ -197,7 +197,7 @@ numberOfParallelWorld(0),geometryNeedsToBeClosed(true),
defaultRegionForParallelWorld = 0;
G4ExceptionDescription msgx;
msgx<<" This type of RunManagerKernel can only be used in mult-threaded applications.";
G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)","Run0035",FatalException,msgx);
G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)","Run0106",FatalException,msgx);
}
runManagerKernelType = rmkType;
+28 -2
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4RunMessenger.cc 94337 2015-11-12 10:02:04Z gcosmo $
// $Id: G4RunMessenger.cc 95634 2016-02-17 08:05:21Z gcosmo $
//
#include "G4RunMessenger.hh"
@@ -324,6 +324,12 @@ G4RunMessenger::G4RunMessenger(G4RunManager * runMgr)
randEvtCmd->SetRange("flag>=0 && flag<3");
randEvtCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
procUICmds = new G4UIcmdWithoutParameter("/run/workersProcessCmds",this);
procUICmds->SetToBeBroadcasted(false);
procUICmds->SetGuidance("Force workers to process current stack of UI commands.");
procUICmds->SetGuidance("This commands is meaningful only in MT mode.");
procUICmds->AvailableForStates(G4State_PreInit,G4State_Idle,G4State_GeomClosed);
}
G4RunMessenger::~G4RunMessenger()
@@ -334,6 +340,7 @@ G4RunMessenger::~G4RunMessenger()
delete printProgCmd;
delete nThreadsCmd;
delete maxThreadsCmd;
delete pinAffinityCmd;
delete evModCmd;
delete optCmd;
delete dumpRegCmd;
@@ -348,6 +355,7 @@ G4RunMessenger::~G4RunMessenger()
delete physCmd;
delete randEvtCmd;
delete constScoreCmd;
delete procUICmds;
delete seedCmd;
delete savingFlagCmd;
@@ -356,7 +364,7 @@ G4RunMessenger::~G4RunMessenger()
delete restoreRandCmd;
delete randomDirectory;
delete saveEachEventCmd;
delete randDirCmd;
delete runDirectory;
@@ -526,6 +534,24 @@ void G4RunMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
{ runManager->ConstructScoringWorlds(); }
else if( command==restoreRandCmdMT)
{ runManager->RestoreRndmEachEvent(restoreRandCmdMT->GetNewBoolValue(newValue)); }
else if ( command==procUICmds)
{
G4RunManager::RMType rmType = runManager->GetRunManagerType();
if( rmType==G4RunManager::masterRM ) {
auto rm = dynamic_cast<G4MTRunManager*>(runManager);
if ( rm != nullptr ) {
rm->RequestWorkersProcessCommandsStack();
}
else { G4Exception("G4RunManager::ApplyNewCommand","Run0128",FatalException,"/run/workersProcessCmds command issued on a non-G4MTRunManager class instance."); }
} else if ( rmType==G4RunManager::sequentialRM ) {
G4cout<<"*** /run/workersProcessCmds command is issued in sequential mode."
<<"\nCommand is ignored."<<G4endl;
} else {
G4Exception("G4RunMessenger::ApplyNewCommand","Run0129",FatalException,
"/run/workersProcessCmds command is issued to local thread.");
}
}
}
G4String G4RunMessenger::GetCurrentValue(G4UIcommand * command)
@@ -128,7 +128,7 @@ void G4UserWorkerThreadInitialization::SetupRNGEngine(const CLHEP::HepRandomEngi
<< " Cannot clone this type of RNG engine, as required for this thread" << G4endl
<< " Aborting " << G4endl;
G4Exception("G4UserWorkerInitializition::SetupRNGEngine()",
"Run10099",FatalException,msg);
"Run0122",FatalException,msg);
}
}
+21 -14
View File
@@ -61,7 +61,7 @@ G4WorkerRunManager::G4WorkerRunManager() : G4RunManager(workerRM) {
G4ExceptionDescription msg;
msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
msg<<" This type of RunManager can only be used in mult-threaded applications.";
G4Exception("G4WorkerRunManager::G4WorkerRunManager()","Run0035",FatalException,msg);
G4Exception("G4WorkerRunManager::G4WorkerRunManager()","Run0103",FatalException,msg);
#endif
G4ParticleTable::GetParticleTable()->WorkerG4ParticleTable();
G4ScoringManager* masterScM = G4MTRunManager::GetMasterScoringManager();
@@ -465,7 +465,7 @@ void G4WorkerRunManager::ConstructScoringWorlds()
if(!pWorld)
{
G4ExceptionDescription ed;
ed<<"Mesh name <"<<ScM->GetWorldName(iw)<<"> is not found in the masther thread.";
ed<<"Mesh name <"<<ScM->GetWorldName(iw)<<"> is not found in the master thread.";
G4Exception("G4WorkerRunManager::ConstructScoringWorlds()","RUN79001",
FatalException,ed);
}
@@ -493,9 +493,9 @@ void G4WorkerRunManager::ConstructScoringWorlds()
{
pmanager->AddProcess(theParallelWorldProcess);
if(theParallelWorldProcess->IsAtRestRequired(particle))
{ pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9999); }
{ pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9900); }
pmanager->SetProcessOrderingToSecond(theParallelWorldProcess, idxAlongStep);
pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9999);
pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9900);
} //if(pmanager)
}//while
}
@@ -506,25 +506,25 @@ void G4WorkerRunManager::ConstructScoringWorlds()
void G4WorkerRunManager::SetUserInitialization(G4UserWorkerInitialization*)
{
G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerInitialization*)", "Run3021",
G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerInitialization*)", "Run0118",
FatalException, "This method should be used only with an instance of G4MTRunManager");
}
void G4WorkerRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)
{
G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "Run3021",
G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "Run0119",
FatalException, "This method should be used only with an instance of G4MTRunManager");
}
void G4WorkerRunManager::SetUserInitialization(G4VUserActionInitialization*)
{
G4Exception("G4RunManager::SetUserInitialization(G4VUserActionInitialization*)", "Run3021",
G4Exception("G4RunManager::SetUserInitialization(G4VUserActionInitialization*)", "Run0120",
FatalException, "This method should be used only with an instance of G4MTRunManager");
}
void G4WorkerRunManager::SetUserInitialization(G4VUserDetectorConstruction*)
{
G4Exception("G4RunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "Run3021",
G4Exception("G4RunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "Run0121",
FatalException, "This method should be used only with an instance of G4MTRunManager");
}
@@ -587,9 +587,9 @@ void G4WorkerRunManager::DoWork()
{
G4MTRunManager* mrm = G4MTRunManager::GetMasterRunManager();
G4MTRunManager::WorkerActionRequest nextAction = mrm->ThisWorkerWaitForNextAction();
while( nextAction != G4MTRunManager::ENDWORKER )
while( nextAction != G4MTRunManager::WorkerActionRequest::ENDWORKER )
{
if( nextAction == G4MTRunManager::NEXTITERATION ) // start the next run
if( nextAction == G4MTRunManager::WorkerActionRequest::NEXTITERATION ) // start the next run
{
//The following code deals with changing materials between runs
static G4ThreadLocal G4bool skipInitialization = true;
@@ -604,7 +604,7 @@ void G4WorkerRunManager::DoWork()
workerContext->UpdateGeometryAndPhysicsVectorFromMaster();
}
// Execute UI commands stored in the masther UI manager
// Execute UI commands stored in the master UI manager
std::vector<G4String> cmds = mrm->GetCommandStack();
G4UImanager* uimgr = G4UImanager::GetUIpointer(); //TLS instance
std::vector<G4String>::const_iterator it = cmds.begin();
@@ -623,13 +623,20 @@ void G4WorkerRunManager::DoWork()
this->BeamOn(numevents,macroFile,numSelect);
}
}
else if (nextAction == G4MTRunManager::WorkerActionRequest::PROCESSUI ) {
std::vector<G4String> cmds = mrm->GetCommandStack();
G4UImanager* uimgr = G4UImanager::GetUIpointer(); //TLS instance
std::vector<G4String>::const_iterator it = cmds.begin();
for(;it!=cmds.end();it++)
{ uimgr->ApplyCommand(*it); }
mrm->ThisWorkerProcessCommandsStackDone();
}
else
{
G4ExceptionDescription d;
d<<"Cannot continue, this worker has been requested an unknwon action: "
<<nextAction<<" expecting: ENDWORKER(=" <<G4MTRunManager::ENDWORKER
<<") or NEXTITERATION(="<<G4MTRunManager::NEXTITERATION<<")";
G4Exception("G4WorkerRunManager::DoWork","Run0035",FatalException,d);
<<static_cast<std::underlying_type<G4MTRunManager::WorkerActionRequest>::type>(nextAction);
G4Exception("G4WorkerRunManager::DoWork","Run0104",FatalException,d);
}
//Now wait for master thread to signal new action to be performed
+4 -4
View File
@@ -34,7 +34,7 @@ G4WorkerRunManagerKernel::G4WorkerRunManagerKernel() : G4RunManagerKernel(worker
G4ExceptionDescription msg;
msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
msg<<" This type of RunManager can only be used in mult-threaded applications.";
G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0035",FatalException,msg);
G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0102",FatalException,msg);
#endif
}
@@ -63,7 +63,7 @@ void G4WorkerRunManagerKernel::SetupShadowProcess() const
msg << "Process manager or process manager shadow to master are not set.\n";
msg << "Particle : "<<pd->GetParticleName()<<" ("<<pd<<"), proc-manager: "<<pm;
msg << " proc-manager-shadow: "<<pmM;
G4Exception("G4WorkerRunManagerKernel::SetupShadowProcess()","Run11001",FatalException,
G4Exception("G4WorkerRunManagerKernel::SetupShadowProcess()","Run0116",FatalException,
msg);
return;
}
@@ -84,8 +84,8 @@ void G4WorkerRunManagerKernel::SetupShadowProcess() const
msg<<" Size of G4ProcessVector is inconsistent between master and worker threads ";
msg<<" for the particle <"<<pd->GetParticleName()<<">. \n";
msg<<" size of G4ProcessVector for worker thread is "<<procs.size();
msg<<" while masther thread is "<<procsM.size()<<".";
G4Exception("G4WorkerRunManagerKernel::SetupShadowProcess()","Run11002",FatalException,msg);
msg<<" while master thread is "<<procsM.size()<<".";
G4Exception("G4WorkerRunManagerKernel::SetupShadowProcess()","Run0117",FatalException,msg);
}
//To each process add the reference to the same
//process from master. Note that we rely on
+2 -2
View File
@@ -212,7 +212,7 @@ void G4WorkerThread::SetPinAffinity(G4int affinity) const
G4int offset = affinity;
G4int cpuindex = 0;
if ( std::abs(offset)>G4Threading::G4GetNumberOfCores() ) {
G4Exception("G4WorkerThread::SetPinAffinity","Run0035",
G4Exception("G4WorkerThread::SetPinAffinity","Run0100",
JustWarning,
"Cannot set thread affinity, affinity parameter larger than number of cores");
return;
@@ -235,7 +235,7 @@ void G4WorkerThread::SetPinAffinity(G4int affinity) const
#endif
G4bool success = G4Threading::G4SetPinAffinity(cpuindex,t);
if ( ! success ) {
G4Exception("G4MTRunManagerKernel::StarThread","Run0035",JustWarning,"Cannot set thread affinity.");
G4Exception("G4MTRunManagerKernel::StarThread","Run0101",JustWarning,"Cannot set thread affinity.");
}
#endif
}