Import Geant4 11.3.0.beta source tree
This commit is contained in:
+33
-4
@@ -6,7 +6,36 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-12-13 Ben Morgan (run-V11-01-11)
|
||||
## 2024-06-14 I. Hrivnacova (run-V11-02-08)
|
||||
- G4RunManager::ReinitializeGeometry: added call to G4FieldBuilder::Reinitialize
|
||||
|
||||
## 2024-06-04 John Apostolakis (run-V11-02-07)
|
||||
- Add call in G4WorkerRunManager to use parallel initialisation of voxels
|
||||
(Requires geommng-V11-02-02.)
|
||||
|
||||
## 2024-06-01 Makoto Asaim (run-V11-02-06)
|
||||
- Initial implementation of creation/processing of SubEvents
|
||||
- Co-working with event-V11-02-04, track-V11-02-03
|
||||
|
||||
## 2024-05-09 Ben Morgan (run-V11-02-05)
|
||||
- Remove use of no longer supported TiMemory.
|
||||
|
||||
## 2024-05-07 Makoto Asai (run-V11-02-04)
|
||||
- G4RunManager : add SetDefaultClassification methods to enable to set the
|
||||
default classification for the track newly arriving to a stack.
|
||||
|
||||
## 2024-04-11 Gabriele Cosmo (run-V11-02-03)
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode
|
||||
on G4MSSteppingAction. Use consistently G4 types.
|
||||
|
||||
## 2024-04-04 Shogo Okada (run-V11-02-02)
|
||||
- G4PhysicsListHelper: added `DNATripleIoni` and `DNAQuadrupleIoni` for the
|
||||
implementation of multiple-ionisation processes in Geant4-DNA.
|
||||
|
||||
## 2024-04-03 Alvaro Tolosa-Delgado (run-V11-02-01)
|
||||
- Material Scan output extended.
|
||||
|
||||
## 2023-12-13 Ben Morgan (run-V11-02-00)
|
||||
- Fix Issue #86: report number of threads from G4TaskRunManager correctly.
|
||||
|
||||
## 2023-11-17 I. Hrivnacova (run-V11-01-10)
|
||||
@@ -83,7 +112,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
call to `geant4_add_category` to define library build from source modules.
|
||||
- Make DLL export symbol a CMake module-level compile definition to aid
|
||||
future modularization
|
||||
|
||||
|
||||
## 2022-01-18 Jonas Hahnfeld (run-V11-00-02)
|
||||
- Prefer pointer to `const G4Material` if possible
|
||||
|
||||
@@ -125,12 +154,12 @@ July 01, 2021 Vladimir Ivanchenko (run-V10-07-07)
|
||||
|
||||
May 20, 2021 Vladimir Ivanchenko (run-V10-07-06)
|
||||
- G4VPhysicsConstructor - fix initialisation of hadronic parameters
|
||||
avoiding uncontrolled override of the verbosityLevel
|
||||
avoiding uncontrolled override of the verbosityLevel
|
||||
|
||||
May 17, 2021 Jonathan Madsen (run-V10-07-05)
|
||||
- Removed calling physicsList->TerminateWorker() in G4WorkerRunManager
|
||||
as this appears to cause errors at termination
|
||||
|
||||
|
||||
April 25, 2021 Hoang Tran (run-V10-07-04)
|
||||
- Added new G4DNAStaticMoleculeReactionProcess in PhysicsListHelper for DNA processs
|
||||
|
||||
|
||||
@@ -36,9 +36,13 @@
|
||||
|
||||
#include "G4UserSteppingAction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class G4Region;
|
||||
|
||||
|
||||
class G4MSSteppingAction : public G4UserSteppingAction
|
||||
{
|
||||
public:
|
||||
@@ -52,12 +56,84 @@ class G4MSSteppingAction : public G4UserSteppingAction
|
||||
inline G4double GetX0() const { return x0; }
|
||||
inline G4double GetLambda0() const { return lambda; }
|
||||
|
||||
/// Print material properties verbosely for each step of geantino
|
||||
/// This function is useful for single shot scans.
|
||||
void PrintEachMaterialVerbose(std::ostream & oss);
|
||||
|
||||
/// Print list of {material name, thickness, x0, lambda}, integrated by material name
|
||||
/// This function is useful for global scans.
|
||||
void PrintIntegratedMaterialVerbose(std::ostream & oss);
|
||||
|
||||
private:
|
||||
G4bool regionSensitive = false;
|
||||
G4Region* theRegion = nullptr;
|
||||
G4double length = 0.0;
|
||||
G4double x0 = 0.0;
|
||||
G4double lambda = 0.0;
|
||||
struct shape_mat_info_t
|
||||
{
|
||||
/// Calculated average atomic number
|
||||
G4double aveZ = 0.0;
|
||||
/// Calculated average mass number
|
||||
G4double aveA = 0.0;
|
||||
/// Density of material given by user
|
||||
G4double density = 0.0;
|
||||
/// Material radiation length
|
||||
G4double radiation_length = 0.0;
|
||||
/// Material interaction length
|
||||
G4double interaction_length = 0.0;
|
||||
/// Step of the geantino
|
||||
G4double thickness = 0.0;
|
||||
/// Integrated path of the geantino
|
||||
G4double integrated_thickness = 0.0;
|
||||
/// Calculated x0 = thickness/radiation_length
|
||||
G4double x0 = 0.0;
|
||||
/// Calculated lambda = thickness/interaction_length
|
||||
G4double lambda = 0.0;
|
||||
/// Integrated x0
|
||||
G4double integrated_x0 = 0.0;
|
||||
/// Integrated lambda
|
||||
G4double integrated_lambda = 0.0;
|
||||
/// Entry point of the geantino into the solid
|
||||
G4ThreeVector entry_point = { };
|
||||
/// Exit point of the geantino out of the solid
|
||||
G4ThreeVector exit_point = { };
|
||||
/// Material name. Composition is not checked.
|
||||
/// That is, if there are two identical materials
|
||||
/// except for the name, they are treated as different
|
||||
G4String material_name = { };
|
||||
/// Getter that returns the full material name
|
||||
G4String GetName(){return material_name;};
|
||||
/// Getter that returns the material name, splitted in blocks of length 'column_width'
|
||||
G4String GetName(G4int column_width)
|
||||
{
|
||||
G4int input_name_length = (G4int)material_name.length();
|
||||
if( input_name_length < column_width) return material_name;
|
||||
|
||||
G4String formated_name;
|
||||
|
||||
for (size_t i = 0; i < material_name.length(); i += column_width)
|
||||
{
|
||||
// for each block of characters of length 'column_width', append '\n'
|
||||
formated_name += material_name.substr(i, column_width);
|
||||
if (i + column_width < material_name.length())
|
||||
{
|
||||
formated_name += '\n';
|
||||
}
|
||||
// append spaces for last block of characters so its length corresponds to column_width
|
||||
else
|
||||
{
|
||||
formated_name+=G4String( column_width-(input_name_length%column_width),' ');
|
||||
}
|
||||
}
|
||||
|
||||
return formated_name;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
std::vector<shape_mat_info_t> shape_mat_info_v;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#define G4MTRunManager_hh 1
|
||||
|
||||
#include "G4MTBarrier.hh"
|
||||
#include "G4Profiler.hh"
|
||||
#include "G4RNGHelper.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4Threading.hh"
|
||||
@@ -60,10 +59,6 @@ class G4MTRunManager : public G4RunManager
|
||||
friend class G4RunManagerFactory;
|
||||
|
||||
public:
|
||||
// The profiler aliases are only used when compiled with
|
||||
// GEANT4_USE_TIMEMORY.
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
|
||||
// Map of defined worlds.
|
||||
using masterWorlds_t = std::map<G4int, G4VPhysicalVolume*>;
|
||||
|
||||
@@ -157,8 +152,8 @@ class G4MTRunManager : public G4RunManager
|
||||
void SetUserAction(G4UserSteppingAction* userAction) override;
|
||||
|
||||
// To be invoked solely from G4WorkerRunManager to merge the results
|
||||
void MergeScores(const G4ScoringManager* localScoringManager);
|
||||
void MergeRun(const G4Run* localRun);
|
||||
virtual void MergeScores(const G4ScoringManager* localScoringManager);
|
||||
virtual void MergeRun(const G4Run* localRun);
|
||||
|
||||
// Handling of more than one run per thread
|
||||
enum class WorkerActionRequest
|
||||
@@ -274,7 +269,7 @@ class G4MTRunManager : public G4RunManager
|
||||
G4MTBarrier nextActionRequestBarrier;
|
||||
G4MTBarrier processUIBarrier;
|
||||
|
||||
private:
|
||||
protected:
|
||||
// List of workers (i.e. thread)
|
||||
using G4ThreadsList = std::list<G4Thread*>;
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ class G4MaterialScanner
|
||||
inline G4bool GetRegionSensitive() const { return regionSensitive; }
|
||||
G4bool SetRegionName(const G4String& val);
|
||||
inline const G4String& GetRegionName() const { return regionName; }
|
||||
inline void SetVerbosity(G4int v) { verbosity = v; };
|
||||
|
||||
private:
|
||||
void DoScan();
|
||||
@@ -115,6 +116,12 @@ class G4MaterialScanner
|
||||
G4bool regionSensitive = false;
|
||||
G4String regionName = "notDefined";
|
||||
G4Region* theRegion = nullptr;
|
||||
|
||||
/// Configure degree of verbosity of Material Scan
|
||||
/// verbosity 0: default
|
||||
/// verbosity 1: call PrintIntegratedMaterialVerbose
|
||||
/// verbosity 2: call PrintEachMaterialVerbose
|
||||
G4int verbosity = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#ifndef G4Run_hh
|
||||
#define G4Run_hh 1
|
||||
|
||||
#include "G4Profiler.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <vector>
|
||||
@@ -47,9 +46,6 @@ class G4DCtable;
|
||||
|
||||
class G4Run
|
||||
{
|
||||
public:
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
|
||||
public:
|
||||
G4Run();
|
||||
virtual ~G4Run();
|
||||
@@ -102,6 +98,8 @@ class G4Run
|
||||
|
||||
// Returns the event vector.
|
||||
inline std::vector<const G4Event*>* GetEventVector() const { return eventVector; }
|
||||
inline G4int GetEventVectorSize() const
|
||||
{ return (eventVector!=nullptr) ? (G4int)(eventVector->size()) : 0; }
|
||||
|
||||
inline void SetRunID(G4int id) { runID = id; }
|
||||
inline void SetNumberOfEventToBeProcessed(G4int n_ev) { numberOfEventToBeProcessed = n_ev; }
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
|
||||
#include "G4Event.hh"
|
||||
#include "G4EventManager.hh"
|
||||
#include "G4Profiler.hh"
|
||||
#include "G4RunManagerKernel.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
@@ -139,11 +138,6 @@ class G4RunManager
|
||||
{
|
||||
friend class G4RunManagerFactory;
|
||||
|
||||
public:
|
||||
// the profiler aliases are only used when compiled with the
|
||||
// GEANT4_USE_TIMEMORY flag enabled.
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
|
||||
public:
|
||||
// Static method which returns the singleton pointer of G4RunManager
|
||||
// or its derived class.
|
||||
@@ -253,12 +247,6 @@ class G4RunManager
|
||||
virtual G4Event* GenerateEvent(G4int i_event);
|
||||
virtual void AnalyzeEvent(G4Event* anEvent);
|
||||
|
||||
// This method configures the global fallback query and label generators.
|
||||
virtual void ConfigureProfilers(const std::vector<std::string>& args = {});
|
||||
|
||||
// Calls the above virtual method.
|
||||
void ConfigureProfilers(G4int argc, char** argv);
|
||||
|
||||
// Dummy methods to dispatch generic inheritance calls from G4RunManager
|
||||
// base class.
|
||||
virtual void SetNumberOfThreads(G4int) {}
|
||||
@@ -404,6 +392,20 @@ class G4RunManager
|
||||
eventManager->GetStackManager()->SetNumberOfAdditionalWaitingStacks(iAdd);
|
||||
}
|
||||
|
||||
// Define the default classification for a newly arriving track.
|
||||
// Default can be alternated by the UserStackingAction.
|
||||
// G4ExceptionSeverity can be set to warn the user if the classification is changed
|
||||
// by the UserStackingAction.
|
||||
inline void SetDefaultClassification(G4TrackStatus ts,
|
||||
G4ClassificationOfNewTrack val,
|
||||
G4ExceptionSeverity es = G4ExceptionSeverity::IgnoreTheIssue)
|
||||
{ eventManager->GetStackManager()->SetDefaultClassification(ts,val,es); }
|
||||
inline void SetDefaultClassification(const G4ParticleDefinition* pd,
|
||||
G4ClassificationOfNewTrack val,
|
||||
G4ExceptionSeverity es = G4ExceptionSeverity::IgnoreTheIssue)
|
||||
{ eventManager->GetStackManager()->SetDefaultClassification(pd,val,es); }
|
||||
|
||||
|
||||
inline const G4String& GetVersionString() const { return kernel->GetVersionString(); }
|
||||
|
||||
inline void SetPrimaryTransformer(G4PrimaryTransformer* pt)
|
||||
@@ -519,22 +521,66 @@ class G4RunManager
|
||||
{
|
||||
sequentialRM,
|
||||
masterRM,
|
||||
workerRM
|
||||
workerRM,
|
||||
subEventMasterRM,
|
||||
subEventWorkerRM
|
||||
};
|
||||
|
||||
inline RMType GetRunManagerType() const { return runManagerType; }
|
||||
|
||||
// Following methods are used only for sub-event parallel mode.
|
||||
// Actual explanations of these methods are found in G4SubEvtRunManager class
|
||||
virtual void RegisterSubEventType(G4int, G4int)
|
||||
{
|
||||
G4Exception("G4RunManager::RegisterSubEventType","RunSE1000",FatalException,
|
||||
"Base class method is invoked for a RunManager that is not sub-event paralle mode");
|
||||
}
|
||||
virtual void UpdateScoringForSubEvent(const G4SubEvent*,const G4Event*)
|
||||
{
|
||||
G4Exception("G4RunManager::UpdateScoringForSubEvent","RunSE1001",FatalException,
|
||||
"Base class method is invoked for a RunManager that is not sub-event paralle mode");
|
||||
}
|
||||
virtual const G4SubEvent* GetSubEvent(G4int, G4bool&,
|
||||
G4long&, G4long&, G4long&, G4bool)
|
||||
{
|
||||
G4Exception("G4RunManager::GetSubEvent","RunSE1002",FatalException,
|
||||
"Base class method is invoked for a RunManager that is not sub-event paralle mode");
|
||||
return nullptr;
|
||||
}
|
||||
virtual void SubEventFinished(const G4SubEvent*,const G4Event*)
|
||||
{
|
||||
G4Exception("G4RunManager::SubEventFinished","RunSE1003",FatalException,
|
||||
"Base class method is invoked for a RunManager that is not sub-event paralle mode");
|
||||
}
|
||||
virtual G4int GetSubEventType() const
|
||||
{
|
||||
G4Exception("G4RunManager::GetSubEventType","RunSE1010",FatalException,
|
||||
"Base class method is invoked for RunManager that is not a worker in sub-event paralle mode");
|
||||
return -1;
|
||||
}
|
||||
virtual std::size_t GetMaxNTrack() const
|
||||
{ return 0; }
|
||||
|
||||
virtual void ReportEventDeletion(const G4Event* evt);
|
||||
|
||||
protected:
|
||||
// This constructor is called in case of multi-threaded build.
|
||||
G4RunManager(RMType rmType);
|
||||
|
||||
void CleanUpPreviousEvents();
|
||||
void CleanUpUnnecessaryEvents(G4int keepNEvents);
|
||||
void StackPreviousEvent(G4Event* anEvent);
|
||||
// This method is invoked at the end of processing each event
|
||||
virtual void StackPreviousEvent(G4Event* anEvent);
|
||||
|
||||
// This method is invoked at the beginning of next run or when the
|
||||
// program is quiting. So, we delete all the kept G4Event objects.
|
||||
virtual void CleanUpPreviousEvents();
|
||||
|
||||
// This method is invoked at the end of processing each event
|
||||
// to delete any G4Event objects that are no longer needed.
|
||||
virtual void CleanUpUnnecessaryEvents(G4int keepNEvents);
|
||||
|
||||
virtual void StoreRNGStatus(const G4String& filenamePrefix);
|
||||
|
||||
void UpdateScoring();
|
||||
void UpdateScoring(const G4Event* evt = nullptr);
|
||||
|
||||
// Called by destructor to delete user detector. Note: the user detector
|
||||
// is shared among threads, thus this should be re-implemented in derived
|
||||
@@ -605,8 +651,6 @@ class G4RunManager
|
||||
static G4ThreadLocal G4RunManager* fRunManager;
|
||||
|
||||
G4RunMessenger* runMessenger = nullptr;
|
||||
|
||||
std::unique_ptr<ProfilerConfig> masterRunProfiler;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SubEvtRunManager
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// This is a class for run control in sub-event parallel mode.
|
||||
// It extends G4TaskRunManager re-implementing multi-threaded behavior in
|
||||
// key methods (see documentation for G4MTRunManager).
|
||||
//
|
||||
// N.B. G4TaskRunManagerKernel is still used by this G4SubEvtRunManager
|
||||
// without any modification. -- future work for phase-II developments
|
||||
//
|
||||
// Original author: M. Asai (JLAB) - 2024
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4SubEvtRunManager_hh
|
||||
#define G4SubEvtRunManager_hh 1
|
||||
|
||||
#include "G4TaskRunManager.hh"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
class G4SubEvtRunManager : public G4TaskRunManager
|
||||
{
|
||||
friend class G4RunManagerFactory;
|
||||
|
||||
public:
|
||||
static G4SubEvtRunManager* GetMasterRunManager()
|
||||
{
|
||||
auto* _rm = G4MTRunManager::GetMasterRunManager();
|
||||
return dynamic_cast<G4SubEvtRunManager*>(_rm);
|
||||
}
|
||||
|
||||
G4SubEvtRunManager(G4bool useTBB = G4GetEnv<G4bool>("G4USE_TBB", false));
|
||||
G4SubEvtRunManager(G4VUserTaskQueue* taskQueue,
|
||||
G4bool useTBB = G4GetEnv<G4bool>("G4USE_TBB", false), G4int evtGrainsize = 0);
|
||||
~G4SubEvtRunManager() override;
|
||||
|
||||
// Inherited methods to re-implement for MT case
|
||||
void Initialize() override;
|
||||
void Initialize(uint64_t nthreads) override { PTL::TaskRunManager::Initialize(nthreads); }
|
||||
void RunInitialization() override;
|
||||
void InitializeEventLoop(G4int n_event, const char* macroFile = nullptr,
|
||||
G4int n_select = -1) override;
|
||||
void TerminateOneEvent() override;
|
||||
void ProcessOneEvent(G4int i_event) override;
|
||||
void ConstructScoringWorlds() override;
|
||||
void RunTermination() override;
|
||||
void CleanUpPreviousEvents() override;
|
||||
|
||||
// The following two methods are not used in sub-event parallel mode.
|
||||
G4bool SetUpAnEvent(G4Event*, G4long&, G4long&, G4long&, G4bool = true) override
|
||||
{ return false; }
|
||||
G4int SetUpNEvents(G4Event*, G4SeedsQueue*, G4bool = true) override
|
||||
{ return -1; }
|
||||
|
||||
void RegisterSubEventType(G4int ty, G4int maxEnt) override
|
||||
{
|
||||
eventManager->UseSubEventParallelism();
|
||||
eventManager->GetStackManager()->RegisterSubEventType(ty,maxEnt);
|
||||
}
|
||||
|
||||
// The following method should be invoked by G4WorkerSubEvtRunManager for each
|
||||
// sub-event. This method returns a sub-event. This sub-event object must not
|
||||
// be deleted by the worker thread.
|
||||
// Null pointer is returned if
|
||||
// - run is in progress but no sub-event is available yet (notReady=true), or
|
||||
// - run is over and no more sub-event is available unless new run starts (notReady=false)
|
||||
// If a worker runs with its own random number sequence, the Boolean flag 'reseedRequired'
|
||||
// should be set to false. This is *NOT* allowed for the first event.
|
||||
// G4Event object should be instantiated by G4WorkerSubEvtRunManager based on the
|
||||
// input provided in G4SubEvent.
|
||||
const G4SubEvent* GetSubEvent(G4int ty, G4bool& notReady,
|
||||
G4long& s1, G4long& s2, G4long& s3, G4bool reseedRequired = true) override;
|
||||
|
||||
// Notify the master thread that processing of sub-event "se" is over.
|
||||
// Outcome of processed sub-event must be kept in "evt".
|
||||
// "se" is deleted by the master thread, while "evt" must be deleted by the worker thread
|
||||
// after invoking this method.
|
||||
void SubEventFinished(const G4SubEvent* se,const G4Event* evt) override;
|
||||
|
||||
// Merge local scores to the master
|
||||
void MergeScores(const G4ScoringManager* localScoringManager) override;
|
||||
|
||||
// Nothing to do for merging run
|
||||
void MergeRun(const G4Run*) override
|
||||
{}
|
||||
|
||||
// Returns number of currently active threads.
|
||||
// This number may be different from the number of threads currently
|
||||
// in running state, e.g. the number returned by:
|
||||
// G4Threading::GetNumberOfActiveWorkerThreads() method.
|
||||
std::size_t GetNumberActiveThreads() const override
|
||||
{ return threads.size(); }
|
||||
|
||||
// Worker threads barrier: this method should be called by each
|
||||
// worker when ready to start thread event-loop.
|
||||
// This method will return only when all workers are ready.
|
||||
// void ThisWorkerReady() override;
|
||||
|
||||
// Worker threads barrier: this method should be called by each
|
||||
// worker when worker event loop is terminated.
|
||||
// void ThisWorkerEndEventLoop() override;
|
||||
|
||||
void SetUserInitialization(G4VUserPhysicsList* userPL) override;
|
||||
void SetUserInitialization(G4VUserDetectorConstruction* userDC) override;
|
||||
void SetUserInitialization(G4UserWorkerInitialization* userInit) override;
|
||||
void SetUserInitialization(G4UserWorkerThreadInitialization* userInit) override;
|
||||
void SetUserInitialization(G4VUserActionInitialization* userInit) override;
|
||||
void SetUserAction(G4UserRunAction* userAction) override;
|
||||
void SetUserAction(G4VUserPrimaryGeneratorAction* userAction) override;
|
||||
void SetUserAction(G4UserEventAction* userAction) override;
|
||||
void SetUserAction(G4UserStackingAction* userAction) override;
|
||||
void SetUserAction(G4UserTrackingAction* userAction) override;
|
||||
void SetUserAction(G4UserSteppingAction* userAction) override;
|
||||
|
||||
// Called to force workers to request and process the UI commands stack
|
||||
// This will block untill all workers have processed UI commands
|
||||
void RequestWorkersProcessCommandsStack() override;
|
||||
|
||||
// Called by workers to signal to master it has completed processing of
|
||||
// UI commands
|
||||
void ThisWorkerProcessCommandsStackDone() override;
|
||||
|
||||
// Worker thread barrier: this method should be used by workers' run
|
||||
// manager to wait, after an event loop for the next action to be
|
||||
// performed (for example execute a new run).
|
||||
void WaitForReadyWorkers() override {}
|
||||
void WaitForEndEventLoopWorkers() override;
|
||||
|
||||
// This returns the action to be performed.
|
||||
WorkerActionRequest ThisWorkerWaitForNextAction() override
|
||||
{
|
||||
return WorkerActionRequest::UNDEFINED;
|
||||
}
|
||||
|
||||
void AbortRun(G4bool softAbort = false) override;
|
||||
void AbortEvent() override;
|
||||
|
||||
protected:
|
||||
void ComputeNumberOfTasks() override
|
||||
{
|
||||
// This method is not used for sub-event parallel mode
|
||||
numberOfTasks = (G4int)threadPool->size();
|
||||
numberOfEventsPerTask = -1;
|
||||
eventModulo = -1;
|
||||
}
|
||||
|
||||
// Initialize the seeds list, if derived class does not implement this
|
||||
// method, a default generation will be used (nevents*2 random seeds).
|
||||
// Return true if initialization is done.
|
||||
// Adds one seed to the list of seeds.
|
||||
G4bool InitializeSeeds(G4int /*nevts*/) override { return false; };
|
||||
|
||||
// Adds one seed to the list of seeds
|
||||
void RefillSeeds() override;
|
||||
|
||||
//void PrepareCommandsStack() override;
|
||||
|
||||
// Creates worker threads and signal to start
|
||||
void CreateAndStartWorkers() override;
|
||||
|
||||
void TerminateWorkers() override;
|
||||
void NewActionRequest(WorkerActionRequest) override {}
|
||||
void AddEventTask(G4int) override;
|
||||
|
||||
void SetUpSeedsForSubEvent(G4long& s1, G4long& s2, G4long& s3);
|
||||
|
||||
void UpdateScoringForSubEvent(const G4SubEvent* se,const G4Event* evt) override;
|
||||
|
||||
void CleanUpUnnecessaryEvents(G4int keepNEvents) override;
|
||||
void StackPreviousEvent(G4Event* anEvent) override;
|
||||
|
||||
protected:
|
||||
std::atomic<G4bool> runInProgress = false;
|
||||
};
|
||||
|
||||
#endif // G4SubEvtRunManager_hh
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "G4EnvironmentUtils.hh"
|
||||
#include "G4MTBarrier.hh"
|
||||
#include "G4MTRunManager.hh"
|
||||
#include "G4Profiler.hh"
|
||||
#include "G4RNGHelper.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4TBBTaskGroup.hh"
|
||||
@@ -68,8 +67,6 @@ class G4TaskRunManager : public G4MTRunManager, public PTL::TaskRunManager
|
||||
friend class G4RunManagerFactory;
|
||||
|
||||
public:
|
||||
// the profiler aliases are only used when compiled with GEANT4_USE_TIMEMORY
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
using InitializeSeedsCallback = std::function<G4bool(G4int, G4int&, G4int&)>;
|
||||
using RunTaskGroup = G4TaskGroup<void>;
|
||||
|
||||
@@ -141,8 +138,8 @@ class G4TaskRunManager : public G4MTRunManager, public PTL::TaskRunManager
|
||||
G4int SetUpNEvents(G4Event*, G4SeedsQueue* seedsQueue, G4bool reseedRequired = true) override;
|
||||
|
||||
// To be invoked solely from G4WorkerTaskRunManager to merge the results
|
||||
void MergeScores(const G4ScoringManager* localScoringManager);
|
||||
void MergeRun(const G4Run* localRun);
|
||||
void MergeScores(const G4ScoringManager* localScoringManager) override;
|
||||
void MergeRun(const G4Run* localRun) override;
|
||||
|
||||
// Called to force workers to request and process the UI commands stack
|
||||
// This will block untill all workers have processed UI commands
|
||||
@@ -206,7 +203,7 @@ class G4TaskRunManager : public G4MTRunManager, public PTL::TaskRunManager
|
||||
return false;
|
||||
};
|
||||
|
||||
private:
|
||||
protected:
|
||||
// grainsize
|
||||
G4bool workersStarted = false;
|
||||
G4int eventGrainsize = 0;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Makoto Asai (JLAB)
|
||||
//
|
||||
// class description:
|
||||
//
|
||||
// This class is used for multi-threaded Geant4.
|
||||
// It encapsulates the mechanism of starting/stopping threads.
|
||||
|
||||
#ifndef G4UserSubEvtThreadInitialization_hh
|
||||
#define G4UserSubEvtThreadInitialization_hh
|
||||
|
||||
class G4VUserPrimaryGeneratorAction;
|
||||
class G4UserRunAction;
|
||||
class G4UserEventAction;
|
||||
class G4UserStackingAction;
|
||||
class G4UserTrackingAction;
|
||||
class G4UserSteppingAction;
|
||||
|
||||
class G4WorkerThread;
|
||||
class G4WorkerTaskRunManager;
|
||||
|
||||
#include "G4Threading.hh"
|
||||
#include "G4UserTaskThreadInitialization.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
class G4UserSubEvtThreadInitialization : public G4UserTaskThreadInitialization
|
||||
{
|
||||
public: // with description
|
||||
G4UserSubEvtThreadInitialization() = default;
|
||||
~G4UserSubEvtThreadInitialization() override = default;
|
||||
|
||||
// Called by StartThread function to create a run-manager implementing worker
|
||||
// behvior. User should re-implemtn this function in derived class to
|
||||
// instantiate his/her user-defined WorkerRunManager. By default this method
|
||||
// instantiates G4WorkerTaskRunManager object.
|
||||
G4WorkerRunManager* CreateWorkerRunManager() const override;
|
||||
};
|
||||
|
||||
#endif // G4UserSubEvtThreadInitialization_hh
|
||||
@@ -47,9 +47,6 @@ class G4WorkerRunManagerKernel;
|
||||
|
||||
class G4WorkerRunManager : public G4RunManager
|
||||
{
|
||||
public:
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
|
||||
public:
|
||||
static G4WorkerRunManager* GetWorkerRunManager();
|
||||
static G4WorkerRunManagerKernel* GetWorkerRunManagerKernel();
|
||||
@@ -95,7 +92,7 @@ class G4WorkerRunManager : public G4RunManager
|
||||
|
||||
// This method will merge (reduce) the results
|
||||
// of this run into the global run
|
||||
virtual void MergePartialResults();
|
||||
virtual void MergePartialResults(G4bool mergeEvents = true);
|
||||
|
||||
protected:
|
||||
G4WorkerThread* workerContext = nullptr;
|
||||
@@ -111,11 +108,8 @@ class G4WorkerRunManager : public G4RunManager
|
||||
G4SeedsQueue seedsQueue;
|
||||
G4bool readStatusFromFile = false;
|
||||
|
||||
private:
|
||||
void SetupDefaultRNGEngine();
|
||||
|
||||
private:
|
||||
std::unique_ptr<ProfilerConfig> workerRunProfiler;
|
||||
protected:
|
||||
virtual void SetupDefaultRNGEngine();
|
||||
};
|
||||
|
||||
#endif // G4WorkerRunManager_hh
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai (JLAB) - 2024
|
||||
//
|
||||
// class description:
|
||||
//
|
||||
// This is a class for run control in GEANT4 for multi-threaded runs
|
||||
// of worker thread running in sub-event parallel mode.
|
||||
// It extends G4RunManager re-implementing multi-threaded behavior in
|
||||
// key methods. See documentation for G4RunManager. User should never
|
||||
// initialize instances of this class, that are usually handled by
|
||||
// G4MTRunManager. There exists one instance of this class for each
|
||||
// worker in a MT application.
|
||||
|
||||
#ifndef G4WorkerSubEvtRunManager_h
|
||||
#define G4WorkerSubEvtRunManager_h 1
|
||||
|
||||
#include "G4WorkerTaskRunManager.hh"
|
||||
|
||||
class G4WorkerThread;
|
||||
class G4WorkerTaskRunManagerKernel;
|
||||
|
||||
// N.B. G4WorkerTaskRunManagerKernel is still used by this G4WorkerSubEvtRunManager
|
||||
// without any modification. -- future work for phase-II developments
|
||||
using G4WorkerSubEvtRunManagerKernel = G4WorkerTaskRunManagerKernel;
|
||||
|
||||
class G4WorkerSubEvtRunManager : public G4WorkerTaskRunManager
|
||||
{
|
||||
public:
|
||||
static G4WorkerSubEvtRunManager* GetWorkerRunManager();
|
||||
static G4WorkerSubEvtRunManagerKernel* GetWorkerRunManagerKernel();
|
||||
G4WorkerSubEvtRunManager(G4int subEventType = 1);
|
||||
//G4WorkerSubEvtRunManager() = delete;
|
||||
|
||||
// Modified for worker behavior
|
||||
void RunInitialization() override;
|
||||
void DoEventLoop(G4int n_event, const char* macroFile = nullptr, G4int n_select = -1) override;
|
||||
void ProcessOneEvent(G4int i_event) override;
|
||||
G4Event* GenerateEvent(G4int i_event) override;
|
||||
void RunTermination() override;
|
||||
void TerminateEventLoop() override;
|
||||
void DoWork() override;
|
||||
void RestoreRndmEachEvent(G4bool flag) override { readStatusFromFile = flag; }
|
||||
|
||||
void DoCleanup() override;
|
||||
void ProcessUI() override;
|
||||
|
||||
void SetUserInitialization(G4VUserPhysicsList* userPL) override;
|
||||
void SetUserInitialization(G4VUserDetectorConstruction* userDC) override;
|
||||
void SetUserInitialization(G4UserWorkerInitialization* userInit) override;
|
||||
void SetUserInitialization(G4UserWorkerThreadInitialization* userInit) override;
|
||||
void SetUserInitialization(G4VUserActionInitialization* userInit) override;
|
||||
void SetUserAction(G4UserRunAction* userAction) override;
|
||||
void SetUserAction(G4VUserPrimaryGeneratorAction* userAction) override;
|
||||
void SetUserAction(G4UserEventAction* userAction) override;
|
||||
void SetUserAction(G4UserStackingAction* userAction) override;
|
||||
void SetUserAction(G4UserTrackingAction* userAction) override;
|
||||
void SetUserAction(G4UserSteppingAction* userAction) override;
|
||||
|
||||
protected:
|
||||
void StoreRNGStatus(const G4String& filenamePrefix) override;
|
||||
void SetupDefaultRNGEngine() override;
|
||||
|
||||
private:
|
||||
G4int fSubEventType = -1;
|
||||
|
||||
public:
|
||||
G4int GetSubEventType() const override
|
||||
{ return fSubEventType; }
|
||||
};
|
||||
|
||||
#endif // G4WorkerSubEvtRunManager_h
|
||||
@@ -48,7 +48,6 @@ class G4WorkerTaskRunManagerKernel;
|
||||
class G4WorkerTaskRunManager : public G4WorkerRunManager
|
||||
{
|
||||
public:
|
||||
using ProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
using G4StrVector = std::vector<G4String>;
|
||||
|
||||
public:
|
||||
@@ -74,12 +73,11 @@ class G4WorkerTaskRunManager : public G4WorkerRunManager
|
||||
protected:
|
||||
void StoreRNGStatus(const G4String& filenamePrefix) override;
|
||||
|
||||
private:
|
||||
void SetupDefaultRNGEngine();
|
||||
protected:
|
||||
void SetupDefaultRNGEngine() override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
G4StrVector processedCommandStack;
|
||||
std::unique_ptr<ProfilerConfig> workerRunProfiler;
|
||||
};
|
||||
|
||||
#endif // G4WorkerTaskRunManager_h
|
||||
|
||||
@@ -44,6 +44,7 @@ class G4UIcmdWith3VectorAndUnit;
|
||||
class G4UIcmdWithABool;
|
||||
class G4UIcmdWithAString;
|
||||
class G4MaterialScanner;
|
||||
class G4UIcmdWithAnInteger;
|
||||
|
||||
class G4MatScanMessenger : public G4UImessenger
|
||||
{
|
||||
@@ -66,6 +67,7 @@ class G4MatScanMessenger : public G4UImessenger
|
||||
G4UIcmdWithABool* regSenseCmd = nullptr;
|
||||
G4UIcmdWithAString* regionCmd = nullptr;
|
||||
G4UIcmdWith3VectorAndUnit* eyePosCmd = nullptr;
|
||||
G4UIcmdWithAnInteger * verboseCmd = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,9 +20,11 @@ geant4_add_module(G4run
|
||||
G4RunManagerFactory.hh
|
||||
G4RunManager.hh
|
||||
G4RunManagerKernel.hh
|
||||
G4SubEvtRunManager.hh
|
||||
G4TaskRunManager.hh
|
||||
G4TaskRunManagerKernel.hh
|
||||
G4UserRunAction.hh
|
||||
G4UserSubEvtThreadInitialization.hh
|
||||
G4UserTaskInitialization.hh
|
||||
G4UserTaskThreadInitialization.hh
|
||||
G4UserWorkerInitialization.hh
|
||||
@@ -38,6 +40,7 @@ geant4_add_module(G4run
|
||||
G4VUserPrimaryGeneratorAction.hh
|
||||
G4WorkerRunManager.hh
|
||||
G4WorkerRunManagerKernel.hh
|
||||
G4WorkerSubEvtRunManager.hh
|
||||
G4WorkerTaskRunManager.hh
|
||||
G4WorkerTaskRunManagerKernel.hh
|
||||
G4WorkerThread.hh
|
||||
@@ -67,10 +70,12 @@ geant4_add_module(G4run
|
||||
G4RunManagerFactory.cc
|
||||
G4RunManagerKernel.cc
|
||||
G4RunMessenger.cc
|
||||
G4SubEvtRunManager.cc
|
||||
G4TaskRunManager.cc
|
||||
G4TaskRunManagerKernel.cc
|
||||
G4UserPhysicsListMessenger.cc
|
||||
G4UserRunAction.cc
|
||||
G4UserSubEvtThreadInitialization.cc
|
||||
G4UserTaskThreadInitialization.cc
|
||||
G4UserWorkerThreadInitialization.cc
|
||||
G4VModularPhysicsList.cc
|
||||
@@ -83,6 +88,7 @@ geant4_add_module(G4run
|
||||
G4VUserPrimaryGeneratorAction.cc
|
||||
G4WorkerRunManager.cc
|
||||
G4WorkerRunManagerKernel.cc
|
||||
G4WorkerSubEvtRunManager.cc
|
||||
G4WorkerTaskRunManager.cc
|
||||
G4WorkerTaskRunManagerKernel.cc
|
||||
G4WorkerThread.cc)
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "G4Step.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
|
||||
#include <map>
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4MSSteppingAction::Initialize(G4bool rSens, G4Region* reg)
|
||||
{
|
||||
@@ -44,6 +46,7 @@ void G4MSSteppingAction::Initialize(G4bool rSens, G4Region* reg)
|
||||
length = 0.;
|
||||
x0 = 0.;
|
||||
lambda = 0.;
|
||||
shape_mat_info_v.clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -59,4 +62,102 @@ void G4MSSteppingAction::UserSteppingAction(const G4Step* aStep)
|
||||
length += stlen;
|
||||
x0 += stlen / (material->GetRadlen());
|
||||
lambda += stlen / (material->GetNuclearInterLength());
|
||||
|
||||
// store information per step (1 geantino step = 1 solid)
|
||||
{
|
||||
shape_mat_info_v.push_back({});
|
||||
|
||||
shape_mat_info_t & thisMaterialInfo = shape_mat_info_v.back();
|
||||
|
||||
// calculate average mass number and atomic number
|
||||
{
|
||||
const std::vector<const G4Element*> * ElementVector_ptr = material->GetElementVector();
|
||||
for( auto & element : *ElementVector_ptr)
|
||||
{
|
||||
thisMaterialInfo.aveA += element->GetA();
|
||||
thisMaterialInfo.aveZ += element->GetZ();
|
||||
}
|
||||
thisMaterialInfo.aveA /= ElementVector_ptr->size();
|
||||
thisMaterialInfo.aveZ /= ElementVector_ptr->size();
|
||||
}
|
||||
thisMaterialInfo.density = material->GetDensity();
|
||||
thisMaterialInfo.radiation_length = material->GetRadlen();
|
||||
thisMaterialInfo.interaction_length = material->GetNuclearInterLength();
|
||||
thisMaterialInfo.thickness = aStep->GetStepLength();
|
||||
thisMaterialInfo.integrated_thickness = length;
|
||||
thisMaterialInfo.lambda = stlen / (material->GetNuclearInterLength());
|
||||
thisMaterialInfo.x0 = stlen / (material->GetRadlen());
|
||||
thisMaterialInfo.integrated_lambda = lambda;
|
||||
thisMaterialInfo.integrated_x0 = x0;
|
||||
thisMaterialInfo.entry_point = preStepPoint->GetPosition();
|
||||
thisMaterialInfo.exit_point = aStep->GetPostStepPoint()->GetPosition();
|
||||
thisMaterialInfo.material_name = material->GetName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void G4MSSteppingAction::PrintEachMaterialVerbose(std::ostream & oss)
|
||||
{
|
||||
|
||||
G4int colwidth = 11;
|
||||
G4int matname_colwidth = 15;
|
||||
|
||||
oss << G4endl<< G4endl;
|
||||
oss << " Material Atomic properties (averaged) Radiation Interaction Integr. Lambda X0 Entry point Exit point\n name Mass Z density length length Thickness Thickness (cm) (cm)\n (g/mole) (g/cm3) (cm) (cm) (cm) (cm) \n";
|
||||
oss << G4endl;
|
||||
|
||||
|
||||
for( auto & matInfo : shape_mat_info_v)
|
||||
{
|
||||
oss << std::setw(matname_colwidth) << std::left << matInfo.GetName(matname_colwidth) << " ";
|
||||
|
||||
oss << std::setw(colwidth) << std::fixed << std::setprecision(2) << matInfo.aveA / (CLHEP::g/CLHEP::mole);
|
||||
oss << std::setw(colwidth) << std::fixed << std::setprecision(2) << matInfo.aveZ;
|
||||
oss << std::setw(colwidth) << std::scientific << std::setprecision(2) << matInfo.density / (CLHEP::g/CLHEP::cm3);
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.radiation_length / CLHEP::cm;
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.interaction_length / CLHEP::cm;
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.thickness/CLHEP::cm;
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.integrated_thickness/CLHEP::cm;
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.lambda;
|
||||
oss << std::setw(colwidth) << std::scientific << matInfo.x0;
|
||||
oss << std::setw(colwidth) << " ";
|
||||
oss << std::scientific << std::right << "(";
|
||||
oss << std::scientific << std::left << matInfo.entry_point.x()/CLHEP::cm;
|
||||
oss << ", " << matInfo.entry_point.y()/CLHEP::cm;
|
||||
oss << ", " << matInfo.entry_point.z()/CLHEP::cm << ")";
|
||||
oss << std::setw(colwidth) << " ";
|
||||
oss << std::scientific << std::right << "(";
|
||||
oss << std::scientific << std::left << matInfo.exit_point.x()/CLHEP::cm;
|
||||
oss << ", " << matInfo.exit_point.y()/CLHEP::cm;
|
||||
oss << ", " << matInfo.exit_point.z()/CLHEP::cm << ")";
|
||||
oss << G4endl;
|
||||
oss << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4MSSteppingAction::PrintIntegratedMaterialVerbose(std::ostream& oss)
|
||||
{
|
||||
// create database (db) of material name (key) and information
|
||||
std::map<G4String, shape_mat_info_t> mat_db;
|
||||
// accumulate information for each material name into mat_db
|
||||
for( auto & matInfo : shape_mat_info_v)
|
||||
{
|
||||
G4String key = matInfo.material_name;
|
||||
if( 0 == mat_db.count( key ) )
|
||||
{
|
||||
mat_db[key] = shape_mat_info_t{};
|
||||
}
|
||||
|
||||
mat_db[key].x0 += matInfo.x0;
|
||||
mat_db[key].thickness += matInfo.thickness;
|
||||
mat_db[key].lambda += matInfo.lambda;
|
||||
}
|
||||
|
||||
oss << std::scientific << std::setprecision(2) << '\t';
|
||||
for(auto & [key,mat] : mat_db)
|
||||
oss << '\t' << key
|
||||
<< '\t'<< mat.thickness/CLHEP::mm
|
||||
<< '\t'<< mat.x0
|
||||
<< '\t'<< mat.lambda;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "G4Run.hh"
|
||||
#include "G4ScoringManager.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
@@ -625,8 +624,6 @@ void G4MTRunManager::TerminateWorkers()
|
||||
RequestWorkersProcessCommandsStack();
|
||||
// Ask workers to exit
|
||||
NewActionRequest(WorkerActionRequest::ENDWORKER);
|
||||
// finalize profiler before shutting down the threads
|
||||
G4Profiler::Finalize();
|
||||
// Now join threads.
|
||||
#ifdef G4MULTITHREADED // protect here to prevent warning in compilation
|
||||
while (!threads.empty()) {
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "G4UIcmdWithABool.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIparameter.hh"
|
||||
@@ -137,6 +138,14 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
|
||||
regionCmd->SetGuidance("set to TRUE with this command.");
|
||||
regionCmd->SetParameterName("region", true);
|
||||
regionCmd->SetDefaultValue("DefaultRegionForTheWorld");
|
||||
|
||||
verboseCmd = new G4UIcmdWithAnInteger("/control/matScan/verbose", this);
|
||||
verboseCmd->SetGuidance("Set verbose level of material scan");
|
||||
verboseCmd->SetGuidance("0: default, properties integrated over the scan");
|
||||
verboseCmd->SetGuidance("1: integrated properties per material");
|
||||
verboseCmd->SetGuidance("2: detailed properties per material crossed");
|
||||
verboseCmd->SetParameterName("verbose_level", false);
|
||||
verboseCmd->SetDefaultValue(0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -222,6 +231,10 @@ void G4MatScanMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
|
||||
else if (command == regionCmd) {
|
||||
if (theScanner->SetRegionName(newValue)) theScanner->SetRegionSensitive(true);
|
||||
}
|
||||
else if(command == verboseCmd)
|
||||
{
|
||||
theScanner->SetVerbosity(StoI(newValue));
|
||||
}
|
||||
else if (command == singleCmd || command == single2Cmd) {
|
||||
G4int ntheta = theScanner->GetNTheta();
|
||||
G4double thetaMin = theScanner->GetThetaMin();
|
||||
|
||||
@@ -166,7 +166,16 @@ void G4MaterialScanner::DoScan()
|
||||
|
||||
G4cout << " " << std::setw(11) << theta / deg << " " << std::setw(11) << phi / deg
|
||||
<< " " << std::setw(11) << length / mm << " " << std::setw(11) << x0 << " "
|
||||
<< std::setw(11) << lambda << G4endl;
|
||||
<< std::setw(11) << lambda;
|
||||
if(1 == verbosity)
|
||||
{
|
||||
theMatScannerSteppingAction->PrintIntegratedMaterialVerbose(G4cout);
|
||||
}
|
||||
else if(2 == verbosity)
|
||||
{
|
||||
theMatScannerSteppingAction->PrintEachMaterialVerbose(G4cout);
|
||||
}
|
||||
G4cout << G4endl;
|
||||
aveLength += length / mm;
|
||||
aveX0 += x0;
|
||||
aveLambda += lambda;
|
||||
|
||||
@@ -975,6 +975,26 @@ void G4PhysicsListHelper::ReadInDefaultOrderingParameter()
|
||||
theTable->push_back(tmp);
|
||||
sizeOfTable += 1;
|
||||
|
||||
tmp.processTypeName = "DNATripleIoni";
|
||||
tmp.processType = fElectromagnetic;
|
||||
tmp.processSubType = fLowEnergyTripleIonisation;
|
||||
tmp.ordering[0] = -1;
|
||||
tmp.ordering[1] = -1;
|
||||
tmp.ordering[2] = 1000;
|
||||
tmp.isDuplicable = false;
|
||||
theTable->push_back(tmp);
|
||||
sizeOfTable += 1;
|
||||
|
||||
tmp.processTypeName = "DNAQuadrupleIoni";
|
||||
tmp.processType = fElectromagnetic;
|
||||
tmp.processSubType = fLowEnergyQuadrupleIonisation;
|
||||
tmp.ordering[0] = -1;
|
||||
tmp.ordering[1] = -1;
|
||||
tmp.ordering[2] = 1000;
|
||||
tmp.isDuplicable = false;
|
||||
theTable->push_back(tmp);
|
||||
sizeOfTable += 1;
|
||||
|
||||
tmp.processTypeName = "HadElastic";
|
||||
tmp.processType = fHadronic;
|
||||
tmp.processSubType = fHadronElastic;
|
||||
|
||||
+14
-5
@@ -44,13 +44,22 @@ G4Run::G4Run()
|
||||
// --------------------------------------------------------------------
|
||||
G4Run::~G4Run()
|
||||
{
|
||||
// Objects made by local thread should not be deleted by the master thread
|
||||
G4RunManager::RMType rmType =
|
||||
G4RunManager::GetRunManager()->GetRunManagerType();
|
||||
if(rmType != G4RunManager::masterRM)
|
||||
if(G4RunManager::GetRunManager()->GetRunManagerType()!=G4RunManager::masterRM)
|
||||
{
|
||||
for(auto& itr : *eventVector)
|
||||
{ delete itr; }
|
||||
{
|
||||
// if(itr->ToBeKept()) {
|
||||
// G4ExceptionDescription ede;
|
||||
// ede << "Deleting G4Event (id:" << itr->GetEventID()
|
||||
// << ") that has ToBeKept() flag on.\n"
|
||||
// << " KeepEventFlag : " << itr->KeepTheEventFlag()
|
||||
// << " NoOfGrip : " << itr->GetNumberOfGrips()
|
||||
// << " NoOfSubEvt : " << itr->GetNumberOfRemainingSubEvents();
|
||||
// G4Exception("G4Run::~G4Run()","Run0002",JustWarning,ede);
|
||||
// }
|
||||
// G4RunManager::GetRunManager()->ReportEventDeletion(itr);
|
||||
delete itr;
|
||||
}
|
||||
}
|
||||
delete eventVector;
|
||||
}
|
||||
|
||||
+68
-184
@@ -47,7 +47,6 @@
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4ProcessTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Profiler.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "G4RunManagerKernel.hh"
|
||||
@@ -60,9 +59,9 @@
|
||||
#include "G4SmartVoxelStat.hh"
|
||||
#include "G4SolidStore.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4FieldBuilder.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4UserRunAction.hh"
|
||||
@@ -180,14 +179,11 @@ G4RunManager::G4RunManager(RMType rmType)
|
||||
G4Random::saveFullState(oss);
|
||||
randomNumberStatusForThisRun = oss.str();
|
||||
randomNumberStatusForThisEvent = oss.str();
|
||||
ConfigureProfilers();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4RunManager::~G4RunManager()
|
||||
{
|
||||
// finalise profiler before shutting down the threads
|
||||
G4Profiler::Finalize();
|
||||
G4StateManager* pStateManager = G4StateManager::GetStateManager();
|
||||
// set the application state to the quite state
|
||||
if (pStateManager->GetCurrentState() != G4State_Quit) {
|
||||
@@ -196,6 +192,14 @@ G4RunManager::~G4RunManager()
|
||||
}
|
||||
|
||||
CleanUpPreviousEvents();
|
||||
if (verboseLevel > 1 && currentRun!=nullptr) {
|
||||
G4cout << "Deleting G4Run (id:" << currentRun->GetRunID() << ") ";
|
||||
if(currentRun->GetEventVectorSize()>0) {
|
||||
G4cout << " that has " << currentRun->GetEventVectorSize()
|
||||
<< " events kept in eventVector";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
delete currentRun;
|
||||
delete timer;
|
||||
delete runMessenger;
|
||||
@@ -227,25 +231,25 @@ G4RunManager::~G4RunManager()
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::DeleteUserInitializations()
|
||||
{
|
||||
if (verboseLevel > 1) G4cout << "UserDetectorConstruction deleted " << userDetector << G4endl;
|
||||
delete userDetector;
|
||||
userDetector = nullptr;
|
||||
if (verboseLevel > 1) G4cout << "UserDetectorConstruction deleted." << G4endl;
|
||||
|
||||
if (verboseLevel > 1) G4cout << "UserPhysicsList deleted " << physicsList << G4endl;
|
||||
delete physicsList;
|
||||
physicsList = nullptr;
|
||||
if (verboseLevel > 1) G4cout << "UserPhysicsList deleted." << G4endl;
|
||||
|
||||
if (verboseLevel > 1) G4cout << "UserActionInitialization deleted " << userActionInitialization << G4endl;
|
||||
delete userActionInitialization;
|
||||
userActionInitialization = nullptr;
|
||||
if (verboseLevel > 1) G4cout << "UserActionInitialization deleted." << G4endl;
|
||||
|
||||
if (verboseLevel > 1) G4cout << "UserWorkerInitialization deleted " << userWorkerInitialization << G4endl;
|
||||
delete userWorkerInitialization;
|
||||
userWorkerInitialization = nullptr;
|
||||
if (verboseLevel > 1) G4cout << "UserWorkerInitialization deleted." << G4endl;
|
||||
|
||||
if (verboseLevel > 1) G4cout << "UserWorkerThreadInitialization deleted " << userWorkerThreadInitialization << G4endl;
|
||||
delete userWorkerThreadInitialization;
|
||||
userWorkerThreadInitialization = nullptr;
|
||||
if (verboseLevel > 1) G4cout << "UserWorkerThreadInitialization deleted." << G4endl;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -302,6 +306,14 @@ void G4RunManager::RunInitialization()
|
||||
numberOfEventProcessed = 0;
|
||||
|
||||
CleanUpPreviousEvents();
|
||||
if (verboseLevel > 2 && currentRun!=nullptr) {
|
||||
G4cout << "Deleting G4Run (id:" << currentRun->GetRunID() << ") ";
|
||||
if(currentRun->GetEventVectorSize()>0) {
|
||||
G4cout << " that has " << currentRun->GetEventVectorSize()
|
||||
<< " events kept in eventVector";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
delete currentRun;
|
||||
currentRun = nullptr;
|
||||
|
||||
@@ -341,10 +353,6 @@ void G4RunManager::RunInitialization()
|
||||
}
|
||||
if (userRunAction != nullptr) userRunAction->BeginOfRunAction(currentRun);
|
||||
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
masterRunProfiler.reset(new ProfilerConfig(currentRun));
|
||||
#endif
|
||||
|
||||
if (isScoreNtupleWriter) {
|
||||
G4VScoreNtupleWriter::Instance()->OpenFile();
|
||||
}
|
||||
@@ -487,10 +495,12 @@ void G4RunManager::AnalyzeEvent(G4Event* anEvent)
|
||||
void G4RunManager::RunTermination()
|
||||
{
|
||||
if (!fakeRun) {
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
masterRunProfiler.reset();
|
||||
#endif
|
||||
CleanUpUnnecessaryEvents(0);
|
||||
// if(G4int(previousEvents->size())>0) {
|
||||
// G4ExceptionDescription ed;
|
||||
// ed << "Run still has " << previousEvents->size() << " unfinished events!!";
|
||||
// G4Exception("G4RunManager::RunTermination()","RM09009",FatalException,ed);
|
||||
// }
|
||||
// tasking occasionally will call this function even
|
||||
// if there was not a current run
|
||||
if (currentRun != nullptr) {
|
||||
@@ -522,9 +532,13 @@ void G4RunManager::CleanUpPreviousEvents()
|
||||
auto evItr = previousEvents->cbegin();
|
||||
while (evItr != previousEvents->cend()) {
|
||||
G4Event* evt = *evItr;
|
||||
if (evt != nullptr && !(evt->ToBeKept())) delete evt;
|
||||
if (evt != nullptr && !(evt->ToBeKept())) {
|
||||
ReportEventDeletion(evt);
|
||||
delete evt;
|
||||
}
|
||||
evItr = previousEvents->erase(evItr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -543,7 +557,10 @@ void G4RunManager::CleanUpUnnecessaryEvents(G4int keepNEvents)
|
||||
G4Event* evt = *evItr;
|
||||
if (evt != nullptr) {
|
||||
if (evt->GetNumberOfGrips() == 0) {
|
||||
if (!(evt->ToBeKept())) delete evt;
|
||||
if (!(evt->ToBeKept())) {
|
||||
ReportEventDeletion(evt);
|
||||
delete evt;
|
||||
}
|
||||
evItr = previousEvents->erase(evItr);
|
||||
}
|
||||
else {
|
||||
@@ -569,9 +586,21 @@ void G4RunManager::StackPreviousEvent(G4Event* anEvent)
|
||||
previousEvents->push_back(anEvent);
|
||||
}
|
||||
}
|
||||
|
||||
CleanUpUnnecessaryEvents(n_perviousEventsToBeStored);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::ReportEventDeletion(const G4Event* evt)
|
||||
{
|
||||
if(verboseLevel > 2) {
|
||||
G4cout << "deleting G4Event(" << evt << ") eventID = " << evt->GetEventID();
|
||||
if(evt->GetNumberOfCompletedSubEvent()>0) {
|
||||
G4cout << " -- contains " << evt->GetNumberOfCompletedSubEvent() << " completed sub-events";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::Initialize()
|
||||
{
|
||||
@@ -821,19 +850,31 @@ void G4RunManager::ConstructScoringWorlds()
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::UpdateScoring()
|
||||
void G4RunManager::UpdateScoring(const G4Event* evt)
|
||||
{
|
||||
if(evt==nullptr) evt = currentEvent;
|
||||
|
||||
//MAMAMAMA need revisiting
|
||||
if(evt->ScoresAlreadyRecorded()) return;
|
||||
//MAMAMAMA need revisiting
|
||||
|
||||
if (isScoreNtupleWriter) {
|
||||
G4VScoreNtupleWriter::Instance()->Fill(currentEvent->GetHCofThisEvent(),
|
||||
currentEvent->GetEventID());
|
||||
G4VScoreNtupleWriter::Instance()->Fill(evt->GetHCofThisEvent(), evt->GetEventID());
|
||||
}
|
||||
|
||||
if(evt->ScoresAlreadyRecorded()) {
|
||||
G4Exception("G4RunManager::UpdateScoring()","RMSubEvt001",FatalException,
|
||||
"Double-counting!!!");
|
||||
}
|
||||
|
||||
evt->ScoresRecorded();
|
||||
|
||||
G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
|
||||
if (ScM == nullptr) return;
|
||||
auto nPar = (G4int)ScM->GetNumberOfMesh();
|
||||
if (nPar < 1) return;
|
||||
|
||||
G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
|
||||
G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
|
||||
if (HCE == nullptr) return;
|
||||
auto nColl = (G4int)HCE->GetCapacity();
|
||||
for (G4int i = 0; i < nColl; ++i) {
|
||||
@@ -1002,168 +1043,11 @@ void G4RunManager::ReinitializeGeometry(G4bool destroyFirst, G4bool prop)
|
||||
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
|
||||
if (pVVisManager != nullptr) pVVisManager->GeometryHasChanged();
|
||||
}
|
||||
// Reinitialize field builder
|
||||
if (G4FieldBuilder::IsInstance()) {
|
||||
G4FieldBuilder::Instance()->Reinitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::ConfigureProfilers(G4int argc, char** argv)
|
||||
{
|
||||
std::vector<std::string> _args;
|
||||
for (G4int i = 0; i < argc; ++i)
|
||||
_args.emplace_back(argv[i]);
|
||||
ConfigureProfilers(_args);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4RunManager::ConfigureProfilers(const std::vector<std::string>& args)
|
||||
{
|
||||
#ifdef GEANT4_USE_TIMEMORY
|
||||
// parse command line if arguments were passed
|
||||
G4Profiler::Configure(args);
|
||||
#else
|
||||
G4ConsumeParameters(args);
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#if !defined(GEANT4_USE_TIMEMORY)
|
||||
# define TIMEMORY_WEAK_PREFIX
|
||||
# define TIMEMORY_WEAK_POSTFIX
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// this allows the default setup to be overridden by linking
|
||||
// in an custom extern C function into the application
|
||||
TIMEMORY_WEAK_PREFIX
|
||||
void G4RunProfilerInit(void) TIMEMORY_WEAK_POSTFIX;
|
||||
|
||||
extern void G4ProfilerInit(void);
|
||||
|
||||
// this gets executed when the library gets loaded
|
||||
void G4RunProfilerInit(void)
|
||||
{
|
||||
#ifdef GEANT4_USE_TIMEMORY
|
||||
G4ProfilerInit();
|
||||
|
||||
// guard against re-initialization
|
||||
static G4bool _once = false;
|
||||
if (_once) return;
|
||||
_once = true;
|
||||
|
||||
puts(">>> G4RunProfilerInit <<<");
|
||||
|
||||
using RunProfilerConfig = G4ProfilerConfig<G4ProfileType::Run>;
|
||||
using EventProfilerConfig = G4ProfilerConfig<G4ProfileType::Event>;
|
||||
using TrackProfilerConfig = G4ProfilerConfig<G4ProfileType::Track>;
|
||||
using StepProfilerConfig = G4ProfilerConfig<G4ProfileType::Step>;
|
||||
using UserProfilerConfig = G4ProfilerConfig<G4ProfileType::User>;
|
||||
|
||||
//
|
||||
// these are the default functions for evaluating whether
|
||||
// to start profiling
|
||||
//
|
||||
RunProfilerConfig::GetFallbackQueryFunctor() = [](const G4Run* _run) {
|
||||
return G4Profiler::GetEnabled(G4ProfileType::Run) && _run;
|
||||
};
|
||||
|
||||
EventProfilerConfig::GetFallbackQueryFunctor() = [](const G4Event* _event) {
|
||||
return G4Profiler::GetEnabled(G4ProfileType::Event) && _event;
|
||||
};
|
||||
|
||||
TrackProfilerConfig::GetFallbackQueryFunctor() = [](const G4Track* _track) {
|
||||
return G4Profiler::GetEnabled(G4ProfileType::Track) && _track && _track->GetDynamicParticle();
|
||||
};
|
||||
|
||||
StepProfilerConfig::GetFallbackQueryFunctor() = [](const G4Step* _step) {
|
||||
return G4Profiler::GetEnabled(G4ProfileType::Step) && _step && _step->GetTrack();
|
||||
};
|
||||
|
||||
UserProfilerConfig::GetFallbackQueryFunctor() = [](const std::string& _user) {
|
||||
return G4Profiler::GetEnabled(G4ProfileType::User) && !_user.empty();
|
||||
};
|
||||
|
||||
//
|
||||
// these are the default functions which encode the profiling label.
|
||||
// Will not be called unless the query returned true
|
||||
//
|
||||
RunProfilerConfig::GetFallbackLabelFunctor() = [](const G4Run* _run) {
|
||||
return TIMEMORY_JOIN('/', "G4Run", _run->GetRunID());
|
||||
};
|
||||
|
||||
EventProfilerConfig::GetFallbackLabelFunctor() = [](const G4Event* _event) -> std::string {
|
||||
if (G4Profiler::GetPerEvent())
|
||||
return TIMEMORY_JOIN('/', "G4Event", _event->GetEventID());
|
||||
else
|
||||
return "G4Event";
|
||||
};
|
||||
|
||||
TrackProfilerConfig::GetFallbackLabelFunctor() = [](const G4Track* _track) {
|
||||
auto pdef = _track->GetDynamicParticle()->GetParticleDefinition();
|
||||
return TIMEMORY_JOIN('/', "G4Track", pdef->GetParticleName());
|
||||
};
|
||||
|
||||
StepProfilerConfig::GetFallbackLabelFunctor() = [](const G4Step* _step) {
|
||||
auto pdef = _step->GetTrack()->GetParticleDefinition();
|
||||
return TIMEMORY_JOIN('/', "G4Step", pdef->GetParticleName());
|
||||
};
|
||||
|
||||
UserProfilerConfig::GetFallbackLabelFunctor() = [](const std::string& _user) {
|
||||
return _user;
|
||||
};
|
||||
|
||||
using RunTool = typename RunProfilerConfig::type;
|
||||
using EventTool = typename EventProfilerConfig::type;
|
||||
using TrackTool = typename TrackProfilerConfig::type;
|
||||
using StepTool = typename StepProfilerConfig::type;
|
||||
using UserTool = typename UserProfilerConfig::type;
|
||||
|
||||
RunProfilerConfig::GetFallbackToolFunctor() = [](const std::string& _label) {
|
||||
return new RunTool{_label};
|
||||
};
|
||||
|
||||
EventProfilerConfig::GetFallbackToolFunctor() = [](const std::string& _label) {
|
||||
return new EventTool{_label};
|
||||
};
|
||||
|
||||
TrackProfilerConfig::GetFallbackToolFunctor() = [](const std::string& _label) {
|
||||
return new TrackTool(_label, tim::scope::config(tim::scope::flat{}));
|
||||
};
|
||||
|
||||
StepProfilerConfig::GetFallbackToolFunctor() = [](const std::string& _label) {
|
||||
return new StepTool(_label, tim::scope::config(tim::scope::flat{}));
|
||||
};
|
||||
|
||||
UserProfilerConfig::GetFallbackToolFunctor() = [](const std::string& _label) {
|
||||
return new UserTool(_label);
|
||||
};
|
||||
|
||||
auto comps = "wall_clock, cpu_clock, cpu_util, peak_rss";
|
||||
auto run_env_comps = tim::get_env<std::string>("G4PROFILE_RUN_COMPONENTS", comps);
|
||||
auto event_env_comps = tim::get_env<std::string>("G4PROFILE_EVENT_COMPONENTS", comps);
|
||||
auto track_env_comps = tim::get_env<std::string>("G4PROFILE_TRACK_COMPONENTS", comps);
|
||||
auto step_env_comps = tim::get_env<std::string>("G4PROFILE_STEP_COMPONENTS", comps);
|
||||
auto user_env_comps = tim::get_env<std::string>("G4PROFILE_USER_COMPONENTS", comps);
|
||||
|
||||
tim::configure<G4RunProfiler>(run_env_comps);
|
||||
tim::configure<G4EventProfiler>(event_env_comps);
|
||||
tim::configure<G4TrackProfiler>(track_env_comps);
|
||||
tim::configure<G4StepProfiler>(step_env_comps);
|
||||
tim::configure<G4UserProfiler>(user_env_comps);
|
||||
#endif
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifdef GEANT4_USE_TIMEMORY
|
||||
namespace
|
||||
{
|
||||
static G4bool profiler_is_initialized = (G4RunProfilerInit(), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4ScoreSplittingProcess.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
@@ -683,6 +682,12 @@ void G4RunManagerKernel::RunTermination()
|
||||
void G4RunManagerKernel::ResetNavigator()
|
||||
{
|
||||
if (runManagerKernelType == workerRMK) {
|
||||
// To ensure that it is called when using G4TaskRunManagerKernel
|
||||
if( G4GeometryManager::IsParallelOptimisationConfigured() &&
|
||||
!G4GeometryManager::IsParallelOptimisationFinished() )
|
||||
{
|
||||
G4GeometryManager::GetInstance()->UndertakeOptimisation();
|
||||
}
|
||||
geometryNeedsToBeClosed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -89,9 +89,10 @@ G4RunMessenger::G4RunMessenger(G4RunManager* runMgr) : runManager(runMgr)
|
||||
verboseCmd->SetGuidance(" 0 : Silent (default)");
|
||||
verboseCmd->SetGuidance(" 1 : Display main topics");
|
||||
verboseCmd->SetGuidance(" 2 : Display main topics and run summary");
|
||||
verboseCmd->SetGuidance(" 3 : Display some additional information");
|
||||
verboseCmd->SetParameterName("level", true);
|
||||
verboseCmd->SetDefaultValue(0);
|
||||
verboseCmd->SetRange("level >=0 && level <=2");
|
||||
verboseCmd->SetRange("level >=0 && level <=3");
|
||||
|
||||
printProgCmd = new G4UIcmdWithAnInteger("/run/printProgress", this);
|
||||
printProgCmd->SetGuidance("Display begin_of_event information at given frequency.");
|
||||
|
||||
@@ -0,0 +1,852 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4SubEvtRunManager.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
#include "G4EnvironmentUtils.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "G4ScoringManager.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4Task.hh"
|
||||
#include "G4TaskGroup.hh"
|
||||
#include "G4TaskManager.hh"
|
||||
#include "G4TaskRunManagerKernel.hh"
|
||||
#include "G4ThreadLocalSingleton.hh"
|
||||
#include "G4ThreadPool.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UserRunAction.hh"
|
||||
#include "G4UserTaskInitialization.hh"
|
||||
#include "G4UserTaskQueue.hh"
|
||||
#include "G4UserSubEvtThreadInitialization.hh"
|
||||
#include "G4VUserActionInitialization.hh"
|
||||
#include "G4VUserPhysicsList.hh"
|
||||
#include "G4UserEventAction.hh"
|
||||
#include "G4VScoreNtupleWriter.hh"
|
||||
#include "G4WorkerSubEvtRunManager.hh"
|
||||
#include "G4WorkerThread.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
//============================================================================//
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex scorerMergerMutex;
|
||||
G4Mutex accessSubEventMutex;
|
||||
} // namespace
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4SubEvtRunManager::G4SubEvtRunManager(G4VUserTaskQueue* task_queue, G4bool useTBB, G4int grainsize)
|
||||
: G4TaskRunManager(task_queue, useTBB, grainsize)
|
||||
{ runManagerType = subEventMasterRM; }
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4SubEvtRunManager::G4SubEvtRunManager(G4bool useTBB)
|
||||
: G4SubEvtRunManager(nullptr, useTBB, 0)
|
||||
{ runManagerType = subEventMasterRM; }
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4SubEvtRunManager::~G4SubEvtRunManager()
|
||||
{
|
||||
// relying all the necessary deletion upon the base class
|
||||
// G4TaskRunManager::~G4TaskRunManager()
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::Initialize()
|
||||
{
|
||||
G4bool firstTime = (threadPool == nullptr);
|
||||
if (firstTime) G4TaskRunManager::InitializeThreadPool();
|
||||
|
||||
G4RunManager::Initialize();
|
||||
|
||||
// make sure all worker threads are set up.
|
||||
G4RunManager::BeamOn(0);
|
||||
if (firstTime) G4RunManager::SetRunIDCounter(0);
|
||||
// G4UImanager::GetUIpointer()->SetIgnoreCmdNotFound(true);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::RunInitialization()
|
||||
{
|
||||
G4RunManager::RunInitialization();
|
||||
if(!fakeRun) runInProgress = true;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::ProcessOneEvent(G4int i_event)
|
||||
{
|
||||
currentEvent = GenerateEvent(i_event);
|
||||
eventManager->ProcessOneEventForSERM(currentEvent);
|
||||
|
||||
// Following two lines should not be executed here, as spawned sub-events may
|
||||
// be still being processed. These methods are invoked when all sub-events belongings
|
||||
// to this event are processed and scores of these sub-events are marged to the
|
||||
// corresponding master event.
|
||||
//AnalyzeEvent(currentEvent);
|
||||
//UpdateScoring();
|
||||
|
||||
if (i_event < n_select_msg) G4UImanager::GetUIpointer()->ApplyCommand(msgText);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::TerminateOneEvent()
|
||||
{
|
||||
// We must serialize access here because workers may access Run/Event vectors
|
||||
// and we can't override StackPreviousEvent
|
||||
G4AutoLock l(&accessSubEventMutex);
|
||||
StackPreviousEvent(currentEvent);
|
||||
currentEvent = nullptr;
|
||||
++numberOfEventProcessed;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::StackPreviousEvent(G4Event* anEvent)
|
||||
{
|
||||
if(n_perviousEventsToBeStored>0) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4RunManager::SetNumberOfEventsToBeStored() is not supported in sub-event parallel mode.\n"
|
||||
<< "User may still keep events bu G4EventManager::KeepTheCurrentEvent()";
|
||||
G4Exception("G4SubEvtRunManager::StackPreviousEvent","SubEvtRM1200",FatalException,ed);
|
||||
return;
|
||||
}
|
||||
|
||||
if(anEvent->GetNumberOfRemainingSubEvents()>0)
|
||||
// sub-events are still under processing. Event is not yet fully completed.
|
||||
{
|
||||
currentRun->StoreEvent(anEvent);
|
||||
}
|
||||
else
|
||||
// Event is already completed.
|
||||
{
|
||||
// making sure this is the first path
|
||||
if(!(anEvent->IsEventCompleted()))
|
||||
{
|
||||
anEvent->EventCompleted();
|
||||
if(userEventAction!=nullptr) userEventAction->EndOfEventAction(anEvent);
|
||||
auto pVisManager = G4VVisManager::GetConcreteInstance();
|
||||
if (pVisManager) pVisManager->EventReadyForVis(anEvent);
|
||||
UpdateScoring(anEvent);
|
||||
if(!(anEvent->ToBeKept()))
|
||||
{
|
||||
ReportEventDeletion(anEvent);
|
||||
delete anEvent;
|
||||
}
|
||||
else
|
||||
{ // we keep this event for post-processing (i.e. for vis)
|
||||
currentRun->StoreEvent(anEvent);
|
||||
}
|
||||
} else {
|
||||
G4Exception("G4SubEvtRunManager::StackPreviousEvent","SubEvtRM1209",FatalException,"We should not be here!!");
|
||||
}
|
||||
}
|
||||
|
||||
CleanUpUnnecessaryEvents(0);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::CleanUpUnnecessaryEvents(G4int keepNEvents)
|
||||
{
|
||||
// Delete events that are no longer necessary for post
|
||||
// processing such as visualization.
|
||||
// N.B. If ToBeKept() is true, the pointer of this event is
|
||||
// kept in G4Run, and deleted along with the deletion of G4Run.
|
||||
|
||||
if(keepNEvents>0) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4RunManager::SetNumberOfEventsToBeStored() is not supported in sub-event parallel mode.\n"
|
||||
<< "User may still keep events bu G4EventManager::KeepTheCurrentEvent()";
|
||||
G4Exception("G4SubEvtRunManager::CleanUpUnnecessaryEvents","SubEvtRM1201",FatalException,ed);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(currentRun!=nullptr);
|
||||
|
||||
auto eventVector = currentRun->GetEventVector();
|
||||
if(eventVector==nullptr || eventVector->empty()) return;
|
||||
auto eItr = eventVector->cbegin();
|
||||
while(eItr != eventVector->cend())
|
||||
{
|
||||
const G4Event* ev = *eItr;
|
||||
if(ev!=nullptr)
|
||||
{
|
||||
if(!(ev->IsEventCompleted()) && ev->GetNumberOfRemainingSubEvents()==0)
|
||||
{ // This event has been completed since last time we were here
|
||||
ev->EventCompleted();
|
||||
if(userEventAction!=nullptr) userEventAction->EndOfEventAction(ev);
|
||||
auto pVisManager = G4VVisManager::GetConcreteInstance();
|
||||
if (pVisManager) pVisManager->EventReadyForVis(ev);
|
||||
UpdateScoring(ev);
|
||||
if(!(ev->ToBeKept()))
|
||||
{
|
||||
ReportEventDeletion(ev);
|
||||
delete ev;
|
||||
eItr = eventVector->erase(eItr);
|
||||
}
|
||||
else
|
||||
{ // we keep this event for post-processing (i.e. for vis)
|
||||
eItr++;
|
||||
}
|
||||
}
|
||||
else if(!(ev->ToBeKept()))
|
||||
{ // post-processing done. we no longer need this event
|
||||
ReportEventDeletion(ev);
|
||||
delete ev;
|
||||
eItr = eventVector->erase(eItr);
|
||||
}
|
||||
else
|
||||
{ // we still need this event
|
||||
eItr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // ev is a null pointer
|
||||
eItr = eventVector->erase(eItr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::CreateAndStartWorkers()
|
||||
{
|
||||
// Now loop on requested number of workers
|
||||
// This will also start the workers
|
||||
// Currently we do not allow to change the
|
||||
// number of threads: threads area created once
|
||||
// Instead of pthread based workers, create tbbTask
|
||||
static G4bool initializeStarted = false;
|
||||
|
||||
ComputeNumberOfTasks();
|
||||
|
||||
if (fakeRun) {
|
||||
if (initializeStarted) {
|
||||
auto initCmdStack = GetCommandStack();
|
||||
if (!initCmdStack.empty()) {
|
||||
threadPool->execute_on_all_threads([initCmdStack]() {
|
||||
for (auto& itr : initCmdStack)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand(itr);
|
||||
G4WorkerTaskRunManager::GetWorkerRunManager()->DoWork();
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::stringstream msg;
|
||||
msg << "--> G4SubEvtRunManager::CreateAndStartWorkers() --> "
|
||||
<< "Initializing workers...";
|
||||
|
||||
std::stringstream ss;
|
||||
ss.fill('=');
|
||||
ss << std::setw((G4int)msg.str().length()) << "";
|
||||
G4cout << "\n" << ss.str() << "\n" << msg.str() << "\n" << ss.str() << "\n" << G4endl;
|
||||
|
||||
G4TaskRunManagerKernel::InitCommandStack() = GetCommandStack();
|
||||
threadPool->execute_on_all_threads([]() { G4TaskRunManagerKernel::InitializeWorker(); });
|
||||
}
|
||||
initializeStarted = true;
|
||||
}
|
||||
else {
|
||||
auto initCmdStack = GetCommandStack();
|
||||
if (!initCmdStack.empty()) {
|
||||
threadPool->execute_on_all_threads([initCmdStack]() {
|
||||
for (auto& itr : initCmdStack)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand(itr);
|
||||
});
|
||||
}
|
||||
|
||||
// cleans up a previous run and events in case a thread
|
||||
// does not execute any tasks
|
||||
threadPool->execute_on_all_threads([]() { G4TaskRunManagerKernel::ExecuteWorkerInit(); });
|
||||
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "--> G4SubEvtRunManager::CreateAndStartWorkers() --> "
|
||||
<< "Creating " << numberOfTasks << " tasks with " << numberOfEventsPerTask
|
||||
<< " events/task...";
|
||||
|
||||
std::stringstream ss;
|
||||
ss.fill('=');
|
||||
ss << std::setw((G4int)msg.str().length()) << "";
|
||||
G4cout << "\n" << ss.str() << "\n" << msg.str() << "\n" << ss.str() << "\n" << G4endl;
|
||||
}
|
||||
|
||||
/* TODO (PHASE-II): Better calculation of task/event/subevents
|
||||
Currently, number of tasks is equal to number of threads
|
||||
and each task has a loop that endlessly asks for next sub-event
|
||||
until no additional sub-event is available in the master.
|
||||
This is not ideal. We should make each task work only for some limited
|
||||
number of sub-events, and create as many number of tasks as needed
|
||||
on the fly during the event loop of the master thread., e.g.
|
||||
G4int remaining = numberOfEventToBeProcessed;
|
||||
for (G4int nt = 0; nt < numberOfTasks + 1; ++nt) {
|
||||
if (remaining > 0) AddEventTask(nt);
|
||||
remaining -= numberOfEventsPerTask;
|
||||
}
|
||||
*/
|
||||
for(G4int nt = 0; nt < numberOfTasks; ++nt)
|
||||
{ AddEventTask(nt); }
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::AddEventTask(G4int nt)
|
||||
{
|
||||
if (verboseLevel > 1) G4cout << "Adding task " << nt << " to task-group..." << G4endl;
|
||||
workTaskGroup->exec([]() { G4TaskRunManagerKernel::ExecuteWorkerTask(); });
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::RefillSeeds()
|
||||
{
|
||||
G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
G4int nFill = 0;
|
||||
switch (SeedOncePerCommunication()) {
|
||||
case 0:
|
||||
nFill = numberOfEventToBeProcessed - nSeedsFilled;
|
||||
break;
|
||||
case 1:
|
||||
nFill = numberOfTasks - nSeedsFilled;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
nFill = (numberOfEventToBeProcessed - nSeedsFilled * eventModulo) / eventModulo + 1;
|
||||
}
|
||||
// Generates up to nSeedsMax seed pairs only.
|
||||
if (nFill > nSeedsMax) nFill = nSeedsMax;
|
||||
masterRNGEngine->flatArray(nSeedsPerEvent * nFill, randDbl);
|
||||
helper->Refill(randDbl, nFill);
|
||||
nSeedsFilled += nFill;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::InitializeEventLoop(G4int n_event, const char* macroFile, G4int n_select)
|
||||
{
|
||||
MTkernel->SetUpDecayChannels();
|
||||
numberOfEventToBeProcessed = n_event;
|
||||
numberOfEventProcessed = 0;
|
||||
|
||||
if (!fakeRun) {
|
||||
nSeedsUsed = 0;
|
||||
nSeedsFilled = 0;
|
||||
|
||||
if (verboseLevel > 0) timer->Start();
|
||||
|
||||
n_select_msg = n_select;
|
||||
if (macroFile != nullptr) {
|
||||
if (n_select_msg < 0) n_select_msg = n_event;
|
||||
|
||||
msgText = "/control/execute ";
|
||||
msgText += macroFile;
|
||||
selectMacro = macroFile;
|
||||
}
|
||||
else {
|
||||
n_select_msg = -1;
|
||||
selectMacro = "";
|
||||
}
|
||||
|
||||
ComputeNumberOfTasks();
|
||||
|
||||
// initialize seeds
|
||||
// If user did not implement InitializeSeeds,
|
||||
// use default: nSeedsPerEvent seeds per event
|
||||
|
||||
if (n_event > 0) {
|
||||
G4bool _overload = InitializeSeeds(n_event);
|
||||
G4bool _functor = false;
|
||||
if (!_overload) _functor = initSeedsCallback(n_event, nSeedsPerEvent, nSeedsFilled);
|
||||
if (!_overload && !_functor) {
|
||||
G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
switch (SeedOncePerCommunication()) {
|
||||
case 0:
|
||||
nSeedsFilled = n_event;
|
||||
break;
|
||||
case 1:
|
||||
nSeedsFilled = numberOfTasks;
|
||||
break;
|
||||
case 2:
|
||||
nSeedsFilled = n_event / eventModulo + 1;
|
||||
break;
|
||||
default:
|
||||
G4ExceptionDescription msgd;
|
||||
msgd << "Parameter value <" << SeedOncePerCommunication()
|
||||
<< "> of seedOncePerCommunication is invalid. It is reset "
|
||||
"to 0.";
|
||||
G4Exception("G4SubEvtRunManager::InitializeEventLoop()", "Run10036", JustWarning, msgd);
|
||||
SetSeedOncePerCommunication(0);
|
||||
nSeedsFilled = n_event;
|
||||
}
|
||||
|
||||
// Generates up to nSeedsMax seed pairs only.
|
||||
if (nSeedsFilled > nSeedsMax) nSeedsFilled = nSeedsMax;
|
||||
masterRNGEngine->flatArray(nSeedsPerEvent * nSeedsFilled, randDbl);
|
||||
helper->Fill(randDbl, nSeedsFilled, n_event, nSeedsPerEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now initialize workers. Check if user defined a WorkerThreadInitialization
|
||||
if (userWorkerThreadInitialization == nullptr)
|
||||
userWorkerThreadInitialization = new G4UserSubEvtThreadInitialization();
|
||||
|
||||
// Prepare UI commands for threads
|
||||
PrepareCommandsStack();
|
||||
|
||||
// Start worker threads
|
||||
CreateAndStartWorkers();
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::RunTermination()
|
||||
{
|
||||
// Wait for all worker threads to have finished the run
|
||||
// i.e. wait for them to return from RunTermination()
|
||||
// This guarantee that userrunaction for workers has been called
|
||||
|
||||
runInProgress = false;
|
||||
|
||||
//TODO (PHASE-II): do we need this???
|
||||
workTaskGroup->wait();
|
||||
|
||||
// Wait now for all threads to finish event-loop
|
||||
WaitForEndEventLoopWorkers();
|
||||
|
||||
if(currentRun!=nullptr) CleanUpUnnecessaryEvents(0);
|
||||
|
||||
// Now call base-class method
|
||||
G4RunManager::TerminateEventLoop();
|
||||
G4RunManager::RunTermination();
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::ConstructScoringWorlds()
|
||||
{
|
||||
masterScM = G4ScoringManager::GetScoringManagerIfExist();
|
||||
// Call base class stuff...
|
||||
G4RunManager::ConstructScoringWorlds();
|
||||
|
||||
masterWorlds.clear();
|
||||
auto nWorlds = (G4int)G4TransportationManager::GetTransportationManager()->GetNoWorlds();
|
||||
auto itrW = G4TransportationManager::GetTransportationManager()->GetWorldsIterator();
|
||||
for (G4int iWorld = 0; iWorld < nWorlds; ++iWorld) {
|
||||
addWorld(iWorld, *itrW);
|
||||
++itrW;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::MergeScores(const G4ScoringManager* localScoringManager)
|
||||
{
|
||||
G4AutoLock l(&scorerMergerMutex);
|
||||
if (masterScM != nullptr) masterScM->Merge(localScoringManager);
|
||||
}
|
||||
|
||||
const G4SubEvent* G4SubEvtRunManager::GetSubEvent(G4int ty, G4bool& notReady,
|
||||
G4long& s1, G4long& s2, G4long& s3, G4bool reseedRequired)
|
||||
{
|
||||
G4AutoLock l(&accessSubEventMutex);
|
||||
|
||||
// This method is invoked from the worker, the ownership of G4SubEvent object
|
||||
// remains to the master, i.e. will be deleted by the master thread through
|
||||
// TerminateSubEvent() method.
|
||||
|
||||
if(currentRun==nullptr)
|
||||
{
|
||||
// Run has not yet started.
|
||||
notReady = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto eventVector = currentRun->GetEventVector();
|
||||
// RACE HERE: against:
|
||||
// 1 G4Run::StoreEvent(G4Event*) G4Run.cc:80
|
||||
// 2 G4RunManager::StackPreviousEvent(G4Event*) G4RunManager.cc:572
|
||||
for(auto& ev : *eventVector)
|
||||
{
|
||||
// looping over stored events
|
||||
// RACE HERE: against:
|
||||
// 1 G4Run::StoreEvent(G4Event*) G4Run.cc:80
|
||||
// 2 G4RunManager::StackPreviousEvent(G4Event*) G4RunManager.cc:572
|
||||
auto se = const_cast<G4Event*>(ev)->PopSubEvent(ty);
|
||||
if(se!=nullptr)
|
||||
{
|
||||
// Sub-event is found in an event that is already finished its event-loop
|
||||
notReady = false;
|
||||
if(reseedRequired) SetUpSeedsForSubEvent(s1,s2,s3);
|
||||
return se;
|
||||
}
|
||||
}
|
||||
|
||||
auto sep = eventManager->PopSubEvent(ty);
|
||||
if(sep!=nullptr)
|
||||
{
|
||||
// Sub-event is found in an event that is still in the event loop
|
||||
notReady = false;
|
||||
if(reseedRequired) SetUpSeedsForSubEvent(s1,s2,s3);
|
||||
return sep;
|
||||
} else {
|
||||
// No sub-event available
|
||||
// RACE HERE vs line 345
|
||||
if(runInProgress)
|
||||
{
|
||||
// Run is still in progress. Worker should wait until a sub-event is ready
|
||||
notReady = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run is over. No more sub-event to come unless new run starts.
|
||||
notReady = false;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SubEvtRunManager::SetUpSeedsForSubEvent(G4long& s1, G4long& s2, G4long& s3)
|
||||
{
|
||||
//TODO (PHASE-II): Seeding scheme for sub-event has to be revisited
|
||||
G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
G4int idx_rndm = nSeedsPerEvent * nSeedsUsed;
|
||||
s1 = helper->GetSeed(idx_rndm);
|
||||
s2 = helper->GetSeed(idx_rndm + 1);
|
||||
if (nSeedsPerEvent == 3) s3 = helper->GetSeed(idx_rndm + 2);
|
||||
++nSeedsUsed;
|
||||
if (nSeedsUsed == nSeedsFilled) RefillSeeds();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================//
|
||||
//
|
||||
//G4bool G4SubEvtRunManager::SetUpAnEvent(G4Event* evt, G4long& s1, G4long& s2, G4long& s3,
|
||||
// G4bool reseedRequired)
|
||||
//{
|
||||
// G4AutoLock l(&setUpEventMutex);
|
||||
// if (numberOfEventProcessed < numberOfEventToBeProcessed) {
|
||||
// evt->SetEventID(numberOfEventProcessed);
|
||||
// if (reseedRequired) {
|
||||
// G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
// G4int idx_rndm = nSeedsPerEvent * nSeedsUsed;
|
||||
// s1 = helper->GetSeed(idx_rndm);
|
||||
// s2 = helper->GetSeed(idx_rndm + 1);
|
||||
// if (nSeedsPerEvent == 3) s3 = helper->GetSeed(idx_rndm + 2);
|
||||
// ++nSeedsUsed;
|
||||
// if (nSeedsUsed == nSeedsFilled) RefillSeeds();
|
||||
// }
|
||||
// numberOfEventProcessed++;
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//============================================================================//
|
||||
//
|
||||
//G4int G4SubEvtRunManager::SetUpNEvents(G4Event* evt, G4SeedsQueue* seedsQueue, G4bool reseedRequired)
|
||||
//{
|
||||
// G4AutoLock l(&setUpEventMutex);
|
||||
// if (numberOfEventProcessed < numberOfEventToBeProcessed && !runAborted) {
|
||||
// G4int nevt = numberOfEventsPerTask;
|
||||
// G4int nmod = eventModulo;
|
||||
// if (numberOfEventProcessed + nevt > numberOfEventToBeProcessed) {
|
||||
// nevt = numberOfEventToBeProcessed - numberOfEventProcessed;
|
||||
// nmod = numberOfEventToBeProcessed - numberOfEventProcessed;
|
||||
// }
|
||||
// evt->SetEventID(numberOfEventProcessed);
|
||||
//
|
||||
// if (reseedRequired) {
|
||||
// G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
// G4int nevRnd = nmod;
|
||||
// if (SeedOncePerCommunication() > 0) nevRnd = 1;
|
||||
// for (G4int i = 0; i < nevRnd; ++i) {
|
||||
// seedsQueue->push(helper->GetSeed(nSeedsPerEvent * nSeedsUsed));
|
||||
// seedsQueue->push(helper->GetSeed(nSeedsPerEvent * nSeedsUsed + 1));
|
||||
// if (nSeedsPerEvent == 3) seedsQueue->push(helper->GetSeed(nSeedsPerEvent * nSeedsUsed + 2));
|
||||
// nSeedsUsed++;
|
||||
// if (nSeedsUsed == nSeedsFilled) RefillSeeds();
|
||||
// }
|
||||
// }
|
||||
// numberOfEventProcessed += nevt;
|
||||
// return nevt;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::SubEventFinished(const G4SubEvent* se,const G4Event* evt)
|
||||
{
|
||||
G4AutoLock l(&accessSubEventMutex);
|
||||
UpdateScoringForSubEvent(se,evt);
|
||||
eventManager->TerminateSubEvent(se,evt);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::UpdateScoringForSubEvent(const G4SubEvent* se,const G4Event* evt)
|
||||
{
|
||||
auto masterEvt = se->GetEvent();
|
||||
if(masterEvt==nullptr) {
|
||||
G4Exception("G4SubEvtRunManager::UpdateScoringForSubEvent()","SERM0001",
|
||||
FatalException,"Pointer of master event is null. PANIC!");
|
||||
}
|
||||
|
||||
if(userEventAction) {
|
||||
userEventAction->MergeSubEvent(masterEvt,evt);
|
||||
}
|
||||
//if (isScoreNtupleWriter) {
|
||||
// G4VScoreNtupleWriter::Instance()->Fill(evt->GetHCofThisEvent(),
|
||||
// se->GetEvent()->GetEventID());
|
||||
//}
|
||||
|
||||
evt->ScoresRecorded();
|
||||
|
||||
G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
|
||||
if (ScM == nullptr) return;
|
||||
auto nPar = (G4int)ScM->GetNumberOfMesh();
|
||||
if (nPar < 1) return;
|
||||
|
||||
if(verboseLevel>2) {
|
||||
G4cout << "merging scores of sub-event belonging to event id #" << masterEvt->GetEventID()
|
||||
<< " --- sub-event has " << evt->GetHCofThisEvent()->GetCapacity()
|
||||
<< " hits collections" << G4endl;
|
||||
}
|
||||
G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
|
||||
if (HCE == nullptr) return;
|
||||
auto nColl = (G4int)HCE->GetCapacity();
|
||||
for (G4int i = 0; i < nColl; ++i) {
|
||||
G4VHitsCollection* HC = HCE->GetHC(i);
|
||||
if (HC != nullptr) ScM->Accumulate(HC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::CleanUpPreviousEvents()
|
||||
{
|
||||
// Delete all events carried over from previous run.
|
||||
// This method is invoked at the beginning of the next run
|
||||
// or from the destructor of G4RunManager at the very end of
|
||||
// the program.
|
||||
auto evItr = previousEvents->cbegin();
|
||||
while (evItr != previousEvents->cend()) {
|
||||
G4Event* evt = *evItr;
|
||||
if (evt != nullptr)
|
||||
{
|
||||
ReportEventDeletion(evt);
|
||||
// remove evt from the event vector of G4Run as well
|
||||
if(currentRun!=nullptr)
|
||||
{
|
||||
auto eventVector = currentRun->GetEventVector();
|
||||
auto eItr = std::find(eventVector->cbegin(),eventVector->cend(),evt);
|
||||
if(eItr != eventVector->cend()) eventVector->erase(eItr);
|
||||
}
|
||||
delete evt;
|
||||
}
|
||||
evItr = previousEvents->erase(evItr);
|
||||
}
|
||||
if(currentRun!=nullptr)
|
||||
{
|
||||
auto eventVector = currentRun->GetEventVector();
|
||||
if(eventVector==nullptr || eventVector->empty()) return;
|
||||
auto eItr = eventVector->cbegin();
|
||||
while(eItr != eventVector->cend())
|
||||
{
|
||||
const G4Event* ev = *eItr;
|
||||
if(ev!=nullptr)
|
||||
{
|
||||
ReportEventDeletion(ev);
|
||||
delete ev;
|
||||
}
|
||||
eItr = eventVector->erase(eItr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::TerminateWorkers()
|
||||
{
|
||||
// Force workers to execute (if any) all UI commands left in the stack
|
||||
RequestWorkersProcessCommandsStack();
|
||||
|
||||
if (workTaskGroup != nullptr) {
|
||||
workTaskGroup->join();
|
||||
if (!fakeRun)
|
||||
threadPool->execute_on_all_threads([]() { G4TaskRunManagerKernel::TerminateWorker(); });
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::AbortRun(G4bool softAbort)
|
||||
{
|
||||
// This method is valid only for GeomClosed or EventProc state
|
||||
G4ApplicationState currentState = G4StateManager::GetStateManager()->GetCurrentState();
|
||||
if (currentState == G4State_GeomClosed || currentState == G4State_EventProc) {
|
||||
runAborted = true;
|
||||
MTkernel->BroadcastAbortRun(softAbort);
|
||||
}
|
||||
else {
|
||||
G4cerr << "Run is not in progress. AbortRun() ignored." << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::AbortEvent()
|
||||
{
|
||||
// nothing to do in the master thread
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::WaitForEndEventLoopWorkers()
|
||||
{
|
||||
if (workTaskGroup != nullptr) {
|
||||
workTaskGroup->join();
|
||||
if (!fakeRun)
|
||||
threadPool->execute_on_all_threads(
|
||||
[]() { G4TaskRunManagerKernel::TerminateWorkerRunEventLoop(); });
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::RequestWorkersProcessCommandsStack()
|
||||
{
|
||||
PrepareCommandsStack();
|
||||
|
||||
auto process_commands_stack = []() {
|
||||
G4MTRunManager* mrm = G4MTRunManager::GetMasterRunManager();
|
||||
if (mrm != nullptr) {
|
||||
auto cmds = mrm->GetCommandStack();
|
||||
for (const auto& itr : cmds)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand(itr); // TLS instance
|
||||
mrm->ThisWorkerProcessCommandsStackDone();
|
||||
}
|
||||
};
|
||||
|
||||
if (threadPool != nullptr) threadPool->execute_on_all_threads(process_commands_stack);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::ThisWorkerProcessCommandsStackDone() {}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4SubEvtRunManager::SetUserInitialization(G4UserWorkerInitialization* userInit)
|
||||
{
|
||||
userWorkerInitialization = userInit;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserInitialization(G4UserWorkerThreadInitialization* userInit)
|
||||
{
|
||||
userWorkerThreadInitialization = userInit;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserInitialization(G4VUserActionInitialization* userInit)
|
||||
{
|
||||
userActionInitialization = userInit;
|
||||
userActionInitialization->BuildForMaster();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserInitialization(G4VUserDetectorConstruction* userDC)
|
||||
{
|
||||
G4RunManager::SetUserInitialization(userDC);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserInitialization(G4VUserPhysicsList* pl)
|
||||
{
|
||||
pl->InitializeWorker();
|
||||
G4RunManager::SetUserInitialization(pl);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4UserRunAction* userAction)
|
||||
{
|
||||
G4RunManager::SetUserAction(userAction);
|
||||
if (userAction != nullptr) userAction->SetMaster(true);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4UserEventAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4VUserPrimaryGeneratorAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4UserStackingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4UserTrackingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4SubEvtRunManager::SetUserAction(G4UserSteppingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "G4ThreadLocalSingleton.hh"
|
||||
#include "G4ThreadPool.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
@@ -148,9 +147,6 @@ G4TaskRunManager::G4TaskRunManager(G4bool useTBB) : G4TaskRunManager(nullptr, us
|
||||
|
||||
G4TaskRunManager::~G4TaskRunManager()
|
||||
{
|
||||
// finalize profiler before shutting down the threads
|
||||
G4Profiler::Finalize();
|
||||
|
||||
// terminate all the workers
|
||||
G4TaskRunManager::TerminateWorkers();
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "G4Run.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4TaskManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UserWorkerInitialization.hh"
|
||||
#include "G4UserWorkerThreadInitialization.hh"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
|
||||
#include "G4UserSubEvtThreadInitialization.hh"
|
||||
#include "G4WorkerSubEvtRunManager.hh"
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4WorkerRunManager* G4UserSubEvtThreadInitialization::CreateWorkerRunManager() const
|
||||
{
|
||||
return new G4WorkerSubEvtRunManager();
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "G4Run.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4ScoringManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
@@ -56,6 +55,8 @@
|
||||
#include "G4WorkerRunManagerKernel.hh"
|
||||
#include "G4WorkerThread.hh"
|
||||
|
||||
#include "G4GeometryManager.hh" // For parallel geometry initialisation
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
@@ -137,10 +138,20 @@ void G4WorkerRunManager::InitializeGeometry()
|
||||
"G4VUserDetectorConstruction is not defined!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGeometryHasBeenDestroyed) {
|
||||
G4TransportationManager::GetTransportationManager()->ClearParallelWorlds();
|
||||
}
|
||||
|
||||
// Step 0: Contribute to the voxelisation of the geometry
|
||||
if( G4GeometryManager::IsParallelOptimisationConfigured() ) {
|
||||
G4cout << "G4RunManager::InitializeGeometry calling GeometryManager's UndertakeOptimisation"
|
||||
<< G4endl; // TODO - suppress / delete this in final version
|
||||
G4GeometryManager::GetInstance()->UndertakeOptimisation();
|
||||
}
|
||||
// A barrier must ensure that all that all threads have finished this work.
|
||||
// Currently we rely on the (later) barrier at the end of initialisation.
|
||||
|
||||
// Step1: Get pointer to the physiWorld (note: needs to get the "super
|
||||
// pointer, i.e. the one shared by all threads"
|
||||
G4RunManagerKernel* masterKernel = G4MTRunManager::GetMasterRunManagerKernel();
|
||||
@@ -217,10 +228,6 @@ void G4WorkerRunManager::RunInitialization()
|
||||
}
|
||||
if (userRunAction != nullptr) userRunAction->BeginOfRunAction(currentRun);
|
||||
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
workerRunProfiler.reset(new ProfilerConfig(currentRun));
|
||||
#endif
|
||||
|
||||
if (isScoreNtupleWriter) {
|
||||
G4VScoreNtupleWriter::Instance()->OpenFile();
|
||||
}
|
||||
@@ -408,22 +415,51 @@ G4Event* G4WorkerRunManager::GenerateEvent(G4int i_event)
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerRunManager::MergePartialResults()
|
||||
void G4WorkerRunManager::MergePartialResults(G4bool mergeEvents)
|
||||
{
|
||||
// Merge partial results into global run
|
||||
G4MTRunManager* mtRM = G4MTRunManager::GetMasterRunManager();
|
||||
G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
|
||||
if (ScM != nullptr) mtRM->MergeScores(ScM);
|
||||
mtRM->MergeRun(currentRun);
|
||||
/************************** MAMAMAMAMA
|
||||
if(mergeEvents) {
|
||||
G4int ctr = 0;
|
||||
G4int ctrD = 0;
|
||||
G4int ctrK = 0;
|
||||
G4int ctrG = 0;
|
||||
auto eventVector = currentRun->GetEventVector();
|
||||
if(eventVector!=nullptr || !(eventVector->empty())) {
|
||||
auto eItr = eventVector->cbegin();
|
||||
while(eItr != eventVector->cend())
|
||||
{
|
||||
ctr++;
|
||||
const G4Event* ev = *eItr;
|
||||
if(ev->ToBeKept()) { ctrD++; }
|
||||
if(ev->KeepTheEventFlag()) { ctrK++; }
|
||||
if(ev->GetNumberOfGrips()>0) { ctrG++; }
|
||||
eItr++;
|
||||
}
|
||||
// if(!(ev->ToBeKept()))
|
||||
// {
|
||||
// ReportEventDeletion(ev);
|
||||
// delete ev;
|
||||
// eItr = eventVector->erase(eItr);
|
||||
// ctrD++;
|
||||
// }
|
||||
// else
|
||||
// { eItr++; }
|
||||
// }
|
||||
}
|
||||
G4cout<<"MAMAMAMAMA ctr="<<ctr<<" - ctrD="<<ctrD<<" - ctrK="<<ctrK<<" - ctrG="<<ctrG<<G4endl;
|
||||
}
|
||||
********************************/
|
||||
if(mergeEvents) mtRM->MergeRun(currentRun);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerRunManager::RunTermination()
|
||||
{
|
||||
if (!fakeRun) {
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
workerRunProfiler.reset();
|
||||
#endif
|
||||
MergePartialResults();
|
||||
|
||||
// Call a user hook: note this is before the next barrier
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4WorkerSubEvtRunManager.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
#include "G4MTRunManager.hh"
|
||||
#include "G4ParallelWorldProcess.hh"
|
||||
#include "G4ParallelWorldProcessStore.hh"
|
||||
#include "G4RNGHelper.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4ScoringManager.hh"
|
||||
#include "G4SubEvtRunManager.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UserRunAction.hh"
|
||||
#include "G4UserWorkerInitialization.hh"
|
||||
#include "G4UserWorkerThreadInitialization.hh"
|
||||
#include "G4VScoreNtupleWriter.hh"
|
||||
#include "G4VScoringMesh.hh"
|
||||
#include "G4VUserActionInitialization.hh"
|
||||
#include "G4VUserDetectorConstruction.hh"
|
||||
#include "G4VUserPhysicsList.hh"
|
||||
#include "G4VUserPrimaryGeneratorAction.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
#include "G4WorkerTaskRunManagerKernel.hh"
|
||||
#include "G4WorkerThread.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4WorkerSubEvtRunManager* G4WorkerSubEvtRunManager::GetWorkerRunManager()
|
||||
{
|
||||
return static_cast<G4WorkerSubEvtRunManager*>(G4RunManager::GetRunManager());
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4WorkerSubEvtRunManagerKernel* G4WorkerSubEvtRunManager::GetWorkerRunManagerKernel()
|
||||
{
|
||||
return static_cast<G4WorkerSubEvtRunManagerKernel*>(GetWorkerRunManager()->kernel);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4WorkerSubEvtRunManager::G4WorkerSubEvtRunManager(G4int seType)
|
||||
: fSubEventType(seType)
|
||||
{ runManagerType = subEventWorkerRM; }
|
||||
|
||||
void G4WorkerSubEvtRunManager::RunInitialization()
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
if (!visIsSetUp) {
|
||||
G4VVisManager* pVVis = G4VVisManager::GetConcreteInstance();
|
||||
if (pVVis != nullptr) {
|
||||
pVVis->SetUpForAThread();
|
||||
visIsSetUp = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
runIsSeeded = false;
|
||||
|
||||
if (!(kernel->RunInitialization(fakeRun))) return;
|
||||
|
||||
// Signal this thread can start event loop.
|
||||
// Note this will return only when all threads reach this point
|
||||
G4MTRunManager::GetMasterRunManager()->ThisWorkerReady();
|
||||
if (fakeRun) return;
|
||||
|
||||
const G4UserWorkerInitialization* uwi =
|
||||
G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
|
||||
|
||||
CleanUpPreviousEvents();
|
||||
|
||||
delete currentRun;
|
||||
|
||||
currentRun = nullptr;
|
||||
|
||||
if (IfGeometryHasBeenDestroyed()) G4ParallelWorldProcessStore::GetInstance()->UpdateWorlds();
|
||||
|
||||
// Call a user hook: this is guaranteed all threads are "synchronized"
|
||||
if (uwi != nullptr) uwi->WorkerRunStart();
|
||||
|
||||
if (userRunAction != nullptr) currentRun = userRunAction->GenerateRun();
|
||||
if (currentRun == nullptr) currentRun = new G4Run();
|
||||
|
||||
currentRun->SetRunID(runIDCounter);
|
||||
G4TaskRunManager* mrm = G4TaskRunManager::GetMasterRunManager();
|
||||
numberOfEventToBeProcessed = mrm->GetNumberOfEventsToBeProcessed();
|
||||
currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
|
||||
|
||||
currentRun->SetDCtable(DCtable);
|
||||
G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
|
||||
if (fSDM != nullptr) {
|
||||
currentRun->SetHCtable(fSDM->GetHCtable());
|
||||
}
|
||||
|
||||
if (G4VScoreNtupleWriter::Instance() != nullptr) {
|
||||
auto hce = (fSDM != nullptr) ? fSDM->PrepareNewEvent() : nullptr;
|
||||
isScoreNtupleWriter = G4VScoreNtupleWriter::Instance()->Book(hce);
|
||||
delete hce;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
G4Random::saveFullState(oss);
|
||||
randomNumberStatusForThisRun = oss.str();
|
||||
currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
|
||||
|
||||
for (G4int i_prev = 0; i_prev < n_perviousEventsToBeStored; ++i_prev)
|
||||
previousEvents->push_back(nullptr);
|
||||
|
||||
if (printModulo > 0 || verboseLevel > 0) {
|
||||
G4cout << "### Run " << currentRun->GetRunID() << " starts on worker thread "
|
||||
<< G4Threading::G4GetThreadId() << "." << G4endl;
|
||||
}
|
||||
|
||||
if (userRunAction != nullptr) userRunAction->BeginOfRunAction(currentRun);
|
||||
|
||||
if (isScoreNtupleWriter) {
|
||||
G4VScoreNtupleWriter::Instance()->OpenFile();
|
||||
}
|
||||
|
||||
if (storeRandomNumberStatus) {
|
||||
G4String fileN = "currentRun";
|
||||
if (rngStatusEventsFlag) {
|
||||
std::ostringstream os;
|
||||
os << "run" << currentRun->GetRunID();
|
||||
fileN = os.str();
|
||||
}
|
||||
StoreRNGStatus(fileN);
|
||||
}
|
||||
|
||||
runAborted = false;
|
||||
numberOfEventProcessed = 0;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::DoEventLoop(G4int n_event, const char* macroFile, G4int n_select)
|
||||
{
|
||||
//MAMAMAMA
|
||||
G4Exception("G4WorkerSubEvtRunManager::DoEventLoop()","SuvEvtXXX001",FatalException,"We should not be here!");
|
||||
//MAMAMAMA
|
||||
if (userPrimaryGeneratorAction == nullptr) {
|
||||
G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
|
||||
"G4VUserPrimaryGeneratorAction is not defined!");
|
||||
}
|
||||
|
||||
// This is the same as in the sequential case, just the for-loop indexes are
|
||||
// different
|
||||
InitializeEventLoop(n_event, macroFile, n_select);
|
||||
|
||||
// Reset random number seeds queue
|
||||
while (!seedsQueue.empty())
|
||||
seedsQueue.pop();
|
||||
// for each run, worker should receive at least one set of random number
|
||||
// seeds.
|
||||
// runIsSeeded = false;
|
||||
|
||||
// Event loop
|
||||
eventLoopOnGoing = true;
|
||||
G4int i_event = -1;
|
||||
nevModulo = -1;
|
||||
currEvID = -1;
|
||||
|
||||
for (G4int evt = 0; evt < n_event; ++evt) {
|
||||
ProcessOneEvent(i_event);
|
||||
if (eventLoopOnGoing) {
|
||||
TerminateOneEvent();
|
||||
if (runAborted) eventLoopOnGoing = false;
|
||||
}
|
||||
if (!eventLoopOnGoing) break;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::ProcessOneEvent(G4int i_event)
|
||||
{
|
||||
//MAMAMAMA
|
||||
G4Exception("G4WorkerSubEvtRunManager::ProcessOneEvent()","SuvEvtXXX002",FatalException,"We should not be here!");
|
||||
//MAMAMAMA
|
||||
currentEvent = GenerateEvent(i_event);
|
||||
if (eventLoopOnGoing) {
|
||||
eventManager->ProcessOneEvent(currentEvent);
|
||||
AnalyzeEvent(currentEvent);
|
||||
UpdateScoring();
|
||||
if (currentEvent->GetEventID() < n_select_msg) {
|
||||
G4cout << "Applying command \"" << msgText << "\" @ " << __FUNCTION__ << ":" << __LINE__
|
||||
<< G4endl;
|
||||
G4UImanager::GetUIpointer()->ApplyCommand(msgText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
G4Event* G4WorkerSubEvtRunManager::GenerateEvent(G4int i_event)
|
||||
{
|
||||
//MAMAMAMA
|
||||
G4Exception("G4WorkerSubEvtRunManager::GenerateEvent()","SuvEvtXXX003",FatalException,"We should not be here!");
|
||||
//MAMAMAMA
|
||||
auto anEvent = new G4Event(i_event);
|
||||
G4long s1 = 0;
|
||||
G4long s2 = 0;
|
||||
G4long s3 = 0;
|
||||
G4bool eventHasToBeSeeded = true;
|
||||
if (G4MTRunManager::SeedOncePerCommunication() == 1 && runIsSeeded) eventHasToBeSeeded = false;
|
||||
|
||||
if (i_event < 0) {
|
||||
G4int nevM = G4MTRunManager::GetMasterRunManager()->GetEventModulo();
|
||||
if (nevM == 1) {
|
||||
eventLoopOnGoing = G4MTRunManager::GetMasterRunManager()->SetUpAnEvent(anEvent, s1, s2, s3,
|
||||
eventHasToBeSeeded);
|
||||
runIsSeeded = true;
|
||||
}
|
||||
else {
|
||||
if (nevModulo <= 0) {
|
||||
G4int nevToDo = G4MTRunManager::GetMasterRunManager()->SetUpNEvents(anEvent, &seedsQueue,
|
||||
eventHasToBeSeeded);
|
||||
if (nevToDo == 0)
|
||||
eventLoopOnGoing = false;
|
||||
else {
|
||||
currEvID = anEvent->GetEventID();
|
||||
nevModulo = nevToDo - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (G4MTRunManager::SeedOncePerCommunication() > 0) eventHasToBeSeeded = false;
|
||||
anEvent->SetEventID(++currEvID);
|
||||
nevModulo--;
|
||||
}
|
||||
if (eventLoopOnGoing && eventHasToBeSeeded) {
|
||||
s1 = seedsQueue.front();
|
||||
seedsQueue.pop();
|
||||
s2 = seedsQueue.front();
|
||||
seedsQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (!eventLoopOnGoing) {
|
||||
delete anEvent;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (eventHasToBeSeeded) {
|
||||
// Need to reseed random number generator
|
||||
G4RNGHelper* helper = G4RNGHelper::GetInstance();
|
||||
s1 = helper->GetSeed(i_event * 2);
|
||||
s2 = helper->GetSeed(i_event * 2 + 1);
|
||||
}
|
||||
|
||||
if (eventHasToBeSeeded) {
|
||||
G4long seeds[3] = {s1, s2, 0};
|
||||
G4Random::setTheSeeds(seeds, -1);
|
||||
runIsSeeded = true;
|
||||
}
|
||||
|
||||
// Read from file seed.
|
||||
// Andrea Dotti 4 November 2015
|
||||
// This is required for strong-reproducibility, in MT mode we have that each
|
||||
// thread produces, for each event a status file, we want to do that.
|
||||
// Search a random file with the format run{%d}evt{%d}.rndm
|
||||
|
||||
// This is the filename base constructed from run and event
|
||||
const auto filename = [&] {
|
||||
std::ostringstream os;
|
||||
os << "run" << currentRun->GetRunID() << "evt" << anEvent->GetEventID();
|
||||
return os.str();
|
||||
};
|
||||
|
||||
G4bool RNGstatusReadFromFile = false;
|
||||
if (readStatusFromFile) {
|
||||
// Build full path of RNG status file for this event
|
||||
std::ostringstream os;
|
||||
os << filename() << ".rndm";
|
||||
const G4String& randomStatusFile = os.str();
|
||||
std::ifstream ifile(randomStatusFile.c_str());
|
||||
if (ifile) {
|
||||
// File valid and readable
|
||||
RNGstatusReadFromFile = true;
|
||||
G4Random::restoreEngineStatus(randomStatusFile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (storeRandomNumberStatusToG4Event == 1 || storeRandomNumberStatusToG4Event == 3) {
|
||||
std::ostringstream oss;
|
||||
G4Random::saveFullState(oss);
|
||||
randomNumberStatusForThisEvent = oss.str();
|
||||
anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
|
||||
}
|
||||
|
||||
if (storeRandomNumberStatus && !RNGstatusReadFromFile) {
|
||||
// If reading from file, avoid to rewrite the same
|
||||
G4String fileN = "currentEvent";
|
||||
if (rngStatusEventsFlag) fileN = filename();
|
||||
StoreRNGStatus(fileN);
|
||||
}
|
||||
|
||||
if (printModulo > 0 && anEvent->GetEventID() % printModulo == 0) {
|
||||
G4cout << "--> Event " << anEvent->GetEventID() << " starts";
|
||||
if (eventHasToBeSeeded) G4cout << " with initial seeds (" << s1 << "," << s2 << ")";
|
||||
G4cout << "." << G4endl;
|
||||
}
|
||||
userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
|
||||
return anEvent;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::RunTermination()
|
||||
{
|
||||
if (!fakeRun && (currentRun != nullptr)) {
|
||||
MergePartialResults(true);
|
||||
|
||||
// Call a user hook: note this is before the next barrier
|
||||
// so threads execute this method asyncrhonouzly
|
||||
//(TerminateRun allows for synch via G4RunAction::EndOfRun)
|
||||
const G4UserWorkerInitialization* uwi =
|
||||
G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
|
||||
if (uwi != nullptr) uwi->WorkerRunEnd();
|
||||
}
|
||||
|
||||
if (currentRun != nullptr) {
|
||||
G4RunManager::RunTermination();
|
||||
}
|
||||
// Signal this thread has finished envent-loop.
|
||||
// Note this will return only whan all threads reach this point
|
||||
G4MTRunManager::GetMasterRunManager()->ThisWorkerEndEventLoop();
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::TerminateEventLoop()
|
||||
{
|
||||
if (verboseLevel > 0 && !fakeRun) {
|
||||
timer->Stop();
|
||||
// prefix with thread # info due to how TBB calls this function
|
||||
G4String prefix = "[thread " + std::to_string(workerContext->GetThreadId()) + "] ";
|
||||
G4cout << prefix << "Thread-local run terminated." << G4endl;
|
||||
G4cout << prefix << "Run Summary" << G4endl;
|
||||
if (runAborted)
|
||||
G4cout << prefix << " Run Aborted after " << numberOfEventProcessed << " events processed."
|
||||
<< G4endl;
|
||||
else
|
||||
G4cout << prefix << " Number of events processed : " << numberOfEventProcessed << G4endl;
|
||||
G4cout << prefix << " " << *timer << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::SetupDefaultRNGEngine()
|
||||
{
|
||||
const CLHEP::HepRandomEngine* mrnge =
|
||||
G4MTRunManager::GetMasterRunManager()->getMasterRandomEngine();
|
||||
assert(mrnge); // Master has created RNG
|
||||
const G4UserWorkerThreadInitialization* uwti =
|
||||
G4MTRunManager::GetMasterRunManager()->GetUserWorkerThreadInitialization();
|
||||
uwti->SetupRNGEngine(mrnge);
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::StoreRNGStatus(const G4String& fn)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << randomNumberStatusDir << "G4Worker" << workerContext->GetThreadId() << "_" << fn << ".rndm";
|
||||
G4Random::saveEngineStatus(os.str().c_str());
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::ProcessUI()
|
||||
{
|
||||
G4TaskRunManager* mrm = G4TaskRunManager::GetMasterRunManager();
|
||||
if (mrm == nullptr) return;
|
||||
|
||||
//------------------------------------------------------------------------//
|
||||
// Check UI commands not already processed
|
||||
auto command_stack = mrm->GetCommandStack();
|
||||
bool matching = (command_stack.size() == processedCommandStack.size());
|
||||
if (matching) {
|
||||
for (uintmax_t i = 0; i < command_stack.size(); ++i)
|
||||
if (processedCommandStack.at(i) != command_stack.at(i)) {
|
||||
matching = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------//
|
||||
// Execute UI commands stored in the master UI manager
|
||||
if (!matching) {
|
||||
for (const auto& itr : command_stack)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand(itr);
|
||||
processedCommandStack = command_stack;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::DoCleanup()
|
||||
{
|
||||
// Nothing to do for a run
|
||||
|
||||
//CleanUpPreviousEvents();
|
||||
//
|
||||
//delete currentRun;
|
||||
//currentRun = nullptr;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::DoWork()
|
||||
{
|
||||
if(verboseLevel>1) {
|
||||
G4cout << "G4WorkerSubEvtRunManager::DoWork() starts.........." << G4endl;
|
||||
}
|
||||
|
||||
//G4TaskRunManager* mrm = G4TaskRunManager::GetMasterRunManager();
|
||||
G4SubEvtRunManager* mrm = G4SubEvtRunManager::GetMasterRunManager();
|
||||
G4bool newRun = false;
|
||||
const G4Run* run = mrm->GetCurrentRun();
|
||||
G4ThreadLocalStatic G4int runId = -1;
|
||||
if ((run != nullptr) && run->GetRunID() != runId) {
|
||||
runId = run->GetRunID();
|
||||
newRun = true;
|
||||
if (runId > 0) { ProcessUI(); }
|
||||
}
|
||||
|
||||
G4bool reseedRequired = false;
|
||||
if (newRun) {
|
||||
G4bool cond = ConfirmBeamOnCondition();
|
||||
if (cond) {
|
||||
ConstructScoringWorlds();
|
||||
RunInitialization();
|
||||
}
|
||||
reseedRequired = true;
|
||||
}
|
||||
|
||||
assert(workerContext != nullptr);
|
||||
workerContext->UpdateGeometryAndPhysicsVectorFromMaster();
|
||||
|
||||
eventManager->UseSubEventParallelism(true);
|
||||
|
||||
G4bool needMoreWork = true;
|
||||
while(needMoreWork)
|
||||
{
|
||||
G4bool notReady = false;
|
||||
G4long s1, s2, s3;
|
||||
auto subEv = mrm->GetSubEvent(fSubEventType, notReady, s1, s2, s3, reseedRequired);
|
||||
if(subEv==nullptr && notReady)
|
||||
{
|
||||
// Master is not yet ready for tasking a sub-event.
|
||||
// Wait 1 second and retry.
|
||||
G4THREADSLEEP(1);
|
||||
}
|
||||
else if(subEv==nullptr)
|
||||
{
|
||||
// No more sub-event to process
|
||||
needMoreWork = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let's work for this sub-event.
|
||||
if(reseedRequired)
|
||||
{
|
||||
G4long seeds[3] = {s1, s2, s3};
|
||||
G4Random::setTheSeeds(seeds, -1);
|
||||
reseedRequired = false;
|
||||
}
|
||||
|
||||
// create a G4Event object for this sub-event. This G4Event object will contain output
|
||||
// to be merged into the master event.
|
||||
auto masterEvent = subEv->GetEvent();
|
||||
G4Event* ev = new G4Event(masterEvent->GetEventID());
|
||||
ev->FlagAsSubEvent(masterEvent,fSubEventType);
|
||||
|
||||
// Create a G4TrackVector as the input
|
||||
G4TrackVector* tv = new G4TrackVector();
|
||||
for(auto& stackedTrack : *subEv)
|
||||
{
|
||||
// tracks (and trajectories) stored in G4SubEvent object belong to the master thread
|
||||
// and thus they must not be deleted by the worker thread. They must be cloned.
|
||||
G4Track* tr = new G4Track();
|
||||
tr->CopyTrackInfo(*(stackedTrack.GetTrack()),false);
|
||||
|
||||
//MAMAMAMAMA cloning of trajectory object is not yet implemented.
|
||||
tv->push_back(tr);
|
||||
}
|
||||
|
||||
// Process this sub-event
|
||||
currentEvent = ev;
|
||||
eventManager->ProcessOneEvent(tv,ev);
|
||||
|
||||
// We don't need following two lines, as they are taken care by the master
|
||||
//////AnalyzeEvent(ev);
|
||||
//////UpdateScoring();
|
||||
|
||||
// Report the results to the master
|
||||
mrm->SubEventFinished(subEv,ev);
|
||||
|
||||
// clean up
|
||||
delete tv;
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
||||
if(verboseLevel>1) {
|
||||
G4cout << "G4WorkerSubEvtRunManager::DoWork() completed.........." << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerInitialization*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerInitialization*)", "RunSE0118",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "RunSE0119",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserActionInitialization*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserActionInitialization*)", "RunSE0120",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserDetectorConstruction*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "RunSE0121",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserInitialization(G4VUserPhysicsList* pl)
|
||||
{
|
||||
pl->InitializeWorker();
|
||||
G4RunManager::SetUserInitialization(pl);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4UserRunAction*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserAction(G4UserRunAction*)", "RunSE0221",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// Forward calls (avoid GCC compilation warnings)
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4UserEventAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4VUserPrimaryGeneratorAction*)
|
||||
{
|
||||
G4Exception("G4WorkerSubEvtRunManager::SetUserAction(G4VUserPrimaryGeneratorAction*)", "RunSE0223",
|
||||
FatalException, "This method should be used only with an instance of the master thread");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4UserStackingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4UserTrackingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4WorkerSubEvtRunManager::SetUserAction(G4UserSteppingAction* ua)
|
||||
{
|
||||
G4RunManager::SetUserAction(ua);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4ScoringManager.hh"
|
||||
#include "G4TaskRunManager.hh"
|
||||
#include "G4TiMemory.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
@@ -141,10 +140,6 @@ void G4WorkerTaskRunManager::RunInitialization()
|
||||
|
||||
if (userRunAction != nullptr) userRunAction->BeginOfRunAction(currentRun);
|
||||
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
workerRunProfiler.reset(new ProfilerConfig(currentRun));
|
||||
#endif
|
||||
|
||||
if (isScoreNtupleWriter) {
|
||||
G4VScoreNtupleWriter::Instance()->OpenFile();
|
||||
}
|
||||
@@ -259,6 +254,7 @@ G4Event* G4WorkerTaskRunManager::GenerateEvent(G4int i_event)
|
||||
}
|
||||
|
||||
if (!eventLoopOnGoing) {
|
||||
anEvent->ScoresRecorded();
|
||||
delete anEvent;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -331,9 +327,6 @@ G4Event* G4WorkerTaskRunManager::GenerateEvent(G4int i_event)
|
||||
void G4WorkerTaskRunManager::RunTermination()
|
||||
{
|
||||
if (!fakeRun && (currentRun != nullptr)) {
|
||||
#if defined(GEANT4_USE_TIMEMORY)
|
||||
workerRunProfiler.reset();
|
||||
#endif
|
||||
MergePartialResults();
|
||||
|
||||
// Call a user hook: note this is before the next barrier
|
||||
|
||||
Reference in New Issue
Block a user