Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
@@ -5,7 +5,7 @@
/*! \page ExampleThreadsafeScorers Example ThreadsafeScorers
This example demonstrates a very simple application where an energy
deposit and # of steps is accounted in thread-local (i.e. one instance per
deposit and # of steps is accounted in thread-local (i.e. one instance per
thread) hits maps with underlying types of plain-old data (POD) and global
(i.e. one instance) hits maps with underlying types of atomics.
The example uses a coarse mesh, extensive physics, and step limiters
@@ -14,16 +14,16 @@
classes and maximize the compounding of thread-local round-off error.
At the end of the simulation, the scorers are printed to
"mfd_<DATA_TYPE>_<SCORER_TYPE>.out", where DATA_TYPE is either
"mfd_<DATA_TYPE>_<SCORER_TYPE>.out", where DATA_TYPE is either
"tl" (thread-local) or "tg" (thread-global) and SCORER_TYPE is "EnergyDeposit"
or "NumberOfSteps". These values are then compared to a thread-global
sum of these scorers that were updated via mutex locking. If round-off
errors in thread-local EnergyDeposit are present, they can be viewed
in "mfd_diff.out" at the end of the simulation
This example also provides a demonstration of the TiMemory (timing and
memory analysis) package provided in Geant4 -- for documentation of TiMemory
see https://github.com/jrmadsen/TiMemory.
This example also provides a demonstration of the timemory (a performance
instrumentation toolkit) package provided in Geant4 -- for documentation of timemory
see https://github.com/NERSC/timemory and https://timemory.readthedocs.io.
\section ThreadsafeScorers_s1 ATOMICS and the ATOMIC SCORERS
@@ -36,37 +36,37 @@
in atomic.hh has limited copy-construction and still cannot be used in
STL containers. Use these copy-constructors with extreme caution. See
opening comments of G4atomic.hh for more details.
The newly provided classes in this example (G4atomic, G4TAtomicHitsMap, and
G4TAtomicHitsCollection) are intended for applications where memory is a
G4TAtomicHitsCollection) are intended for applications where memory is a
greater concern than performance. While atomics generally perform better than
mutex locking, the synchronization is not without a cost. However, since
the memory consumed by thread-local hits maps scales roughly linearly
with the number of threads, simulations with a large number of scoring
volumes can decrease simulation time by increasing the number of threads
volumes can decrease simulation time by increasing the number of threads
beyond what was previously allowed due to the increase in memory consumption.
***************************************************************************
*** These classes are intended to be included in the Geant4 source code ***
*** release next year ***
***************************************************************************
The G4TAtomicHitsMap and G4TAtomicHitsCollection work exactly the same way
as the standard G4THitsMap and G4THitsCollection, respectively, with the
exception(s) that you should only implement one instance and provide a
exception(s) that you should only implement one instance and provide a
pointer/reference of that instance to the threads instead of having the
threads create them. Additionally, there is no need to include them
in the G4Run::Merge().
\section ThreadsafeScorers_s2 GEOMETRY DEFINITION
The geometry is constructed in the TSDetectorConstruction class.
The setup consists of a box filling the world. The volume is divided into
subregions, where the outermost boxes are a different material. The materials
by default are water and boron as these have large scattering cross-sections
for neutrons (the default particle).
by default are water and boron as these have large scattering cross-sections
for neutrons (the default particle).
\section ThreadsafeScorers_s3 PHYSICS LIST
The particle's type and the physic processes which will be available
in this example are set are built from a variety of physics constructors.
The chosen physics lists are extensive, primarily
@@ -92,28 +92,28 @@
in multi-threading mode the same method is invoked for each thread worker
and so all user action classes are defined thread-local.
A run action class is instantiated both thread-local
A run action class is instantiated both thread-local
and global that's why its instance is created also in the method
TSActionInitialization::BuildForMaster()
TSActionInitialization::BuildForMaster()
which is invoked only in multi-threading mode.
\section ThreadsafeScorers_s5 PRIMARY GENERATOR
The primary generator is defined in the TSPrimaryGeneratorAction class.
The default kinematics is a 1 MeV neutron, randomly distributed in front
of the target across 100% of the transverse (X,Y) target size.
This default setting can be changed via the Geant4 built-in commands
This default setting can be changed via the Geant4 built-in commands
of the G4ParticleGun class.
\section ThreadsafeScorers_s6 DETECTOR RESPONSE
This example demonstrates a scoring implemented
in the user action classes and TSRun object.
The energy deposited is collected per event in the PrimitiveScorer
G4PSEnergyDeposit (as part of a MultiFunctionalDetector)
and the thread-local version are merged at the end of the run.
The number of steps is collected per event in the PrimativeScorer
G4PSNoOfSteps and the thread-local version are merged at the end of the run.
@@ -165,17 +165,17 @@
- Execute ts_scorers in the 'interactive mode' with visualization:
% ./ts_scorers
and type in the commands from run.mac line by line:
Idle> /control/verbose 2
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> /run/beamOn 10
Idle> ...
Idle> exit
or
Idle> /control/execute run.mac
....
Idle> exit
@@ -188,17 +188,15 @@
\section ThreadsafeScorers_s8 TIMEMORY USAGE
This example demonstrates timing and memory analysis with TiMemory
(https://github.com/jrmadsen/TiMemory).
This example demonstrates profiling analysis with timemory
(https://github.com/NERSC/timemory).
- Compile Geant4 with TiMemory (-DGEANT4_USE_TIMEMORY=ON)
- TiMemory auto-timer provide timing within the Geant4 source code
- Compile Geant4 with timemory (-DGEANT4_USE_TIMEMORY=ON)
- timemory provide timing within the Geant4 source code
and within the example (TSRun::RecordEvent)
- Analysis is echoed to stdout, recorded in ts_scorers.out, and
serialized in ts_scorers.json
- Generates plots:
"timemory-plotter -f ts_scorers.json -t "ThreadSafe Scorers" -o plots -e"
- Uploads plots to CDash if enabled
- Analysis is echoed to stdout and generates several output
files in a folder based on the name of the executable. In
general that folder will be "timemory-{name of executable}-output"
*/
@@ -1,4 +1,7 @@
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
cmake_minimum_required(VERSION 3.8...3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
set(name ts_scorers)
project(ThreadsafeScorers C CXX)
@@ -14,6 +14,9 @@ track of all tags.
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
12/11/20202 Jonathan Madsen (ThreadsafeScorers-V10-06-03)
- Replaced TIMEMORY_AUTO_TIMER usage with G4USER_SCOPED_PROFILE usage
23/6/2020 Jonathan Madsen (ThreadsafeScores-V10-06-02)
- Added example of user code leveraging tasking in TSRunAction.cc
- This example leverages tasks on the master thread at the end
@@ -9,7 +9,7 @@
----------------------------
This example demonstrates a very simple application where an energy
deposit and # of steps is accounted in thread-local (i.e. one instance per
deposit and # of steps is accounted in thread-local (i.e. one instance per
thread) hits maps with underlying types of plain-old data (POD) and global
(i.e. one instance) hits maps with underlying types of atomics.
The example uses a coarse mesh, extensive physics, and step limiters
@@ -17,15 +17,15 @@
when updating the scorers to test the robustness of the atomics
classes and maximize the compounding of thread-local round-off error.
At the end of the simulation, the scorers are printed to
"mfd_<DATA_TYPE>_<SCORER_TYPE>.out", where DATA_TYPE is either
"mfd_<DATA_TYPE>_<SCORER_TYPE>.out", where DATA_TYPE is either
"tl" (thread-local) or "tg" (thread-global) and SCORER_TYPE is "EnergyDeposit"
or "NumberOfSteps". These values are then compared to a thread-global
sum of these scorers that were updated via mutex locking. If round-off
errors in thread-local EnergyDeposit are present, they can be viewed
in "mfd_diff.out" at the end of the simulation
This example also provides a demonstration of the TiMemory (timing and
memory analysis) package provided in Geant4 -- for documentation of TiMemory
see https://github.com/jrmadsen/TiMemory.
This example also provides a demonstration of the timemory (a performance
instrumentation toolkit) package provided in Geant4 -- for documentation of timemory
see https://github.com/NERSC/timemory and https://timemory.readthedocs.io.
1- ATOMICS and the ATOMIC SCORERS
@@ -38,33 +38,33 @@
in atomic.hh has limited copy-construction and still cannot be used in
STL containers. Use these copy-constructors with extreme caution. See
opening comments of G4atomic.hh for more details.
The newly provided classes in this example (G4atomic, G4TAtomicHitsMap, and
G4TAtomicHitsCollection) are intended for applications where memory is a
G4TAtomicHitsCollection) are intended for applications where memory is a
greater concern than performance. While atomics generally perform better than
mutex locking, the synchronization is not without a cost. However, since
the memory consumed by thread-local hits maps scales roughly linearly
with the number of threads, simulations with a large number of scoring
volumes can decrease simulation time by increasing the number of threads
volumes can decrease simulation time by increasing the number of threads
beyond what was previously allowed due to the increase in memory consumption.
The G4TAtomicHitsMap and G4TAtomicHitsCollection work exactly the same way
as the standard G4THitsMap and G4THitsCollection, respectively, with the
exception(s) that you should only implement one instance and provide a
exception(s) that you should only implement one instance and provide a
pointer/reference of that instance to the threads instead of having the
threads create them. Additionally, there is no need to include them
in the G4Run::Merge().
2- GEOMETRY DEFINITION
The geometry is constructed in the TSDetectorConstruction class.
The setup consists of a box filling the world. The volume is divided into
subregions, where the outermost boxes are a different material. The materials
by default are water and boron as these have large scattering cross-sections
for neutrons (the default particle).
by default are water and boron as these have large scattering cross-sections
for neutrons (the default particle).
3- PHYSICS LIST
The particle's type and the physic processes which will be available
in this example are set are built from a variety of physics constructors.
The chosen physics lists are extensive, primarily
@@ -90,28 +90,28 @@
in multi-threading mode the same method is invoked for each thread worker
and so all user action classes are defined thread-local.
A run action class is instantiated both thread-local
A run action class is instantiated both thread-local
and global that's why its instance is created also in the method
TSActionInitialization::BuildForMaster()
TSActionInitialization::BuildForMaster()
which is invoked only in multi-threading mode.
5- PRIMARY GENERATOR
The primary generator is defined in the TSPrimaryGeneratorAction class.
The default kinematics is a 1 MeV neutron, randomly distributed in front
of the target across 100% of the transverse (X,Y) target size.
This default setting can be changed via the Geant4 built-in commands
This default setting can be changed via the Geant4 built-in commands
of the G4ParticleGun class.
6- DETECTOR RESPONSE
This example demonstrates a scoring implemented
in the user action classes and TSRun object.
The energy deposited is collected per event in the PrimitiveScorer
G4PSEnergyDeposit (as part of a MultiFunctionalDetector)
and the thread-local version are merged at the end of the run.
The number of steps is collected per event in the PrimativeScorer
G4PSNoOfSteps and the thread-local version are merged at the end of the run.
@@ -162,7 +162,7 @@
and type in the commands from run.mac line by line:
Idle> /control/verbose 2
Idle> /tracking/verbose 1
Idle> /run/beamOn 10
Idle> /run/beamOn 10
Idle> ...
Idle> exit
or
@@ -177,14 +177,12 @@
8- TIMEMORY USAGE
This example demonstrates timing and memory analysis with TiMemory
(https://github.com/jrmadsen/TiMemory).
This example demonstrates profiling analysis with timemory
(https://github.com/NERSC/timemory).
- Compile Geant4 with TiMemory (-DGEANT4_USE_TIMEMORY=ON)
- TiMemory auto-timer provide timing within the Geant4 source code
- Compile Geant4 with timemory (-DGEANT4_USE_TIMEMORY=ON)
- timemory provide timing within the Geant4 source code
and within the example (TSRun::RecordEvent)
- Analysis is echoed to stdout, recorded in ts_scorers.out, and
serialized in ts_scorers.json
- Generates plots:
"timemory-plotter -f ts_scorers.json -t "ThreadSafe Scorers" -o plots -e"
- Uploads plots to CDash if enabled
- Analysis is echoed to stdout and generates several output
files in a folder based on the name of the executable. In
general that folder will be "timemory-{name of executable}-output"
@@ -7,6 +7,30 @@
/run/verbose 1
/event/verbose 0
#########################
# Set profiler
#
/profiler/run/enable true
/profiler/event/enable true
/profiler/track/enable true
/profiler/step/enable false
/profiler/run/components wall_clock cpu_clock peak_rss
/profiler/event/components wall_clock cpu_clock peak_rss
/profiler/track/components wall_clock
/profiler/step/components wall_clock
/profiler/per_thread false
/profiler/per_event false
/profiler/output/dart true
/profiler/output/text true
/profiler/output/json false
/profiler/output/cout false
/profiler/tree true
/profiler/flat false
/profiler/timeline false
##########################
# Random
@@ -44,6 +44,7 @@
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4Profiler.hh"
#include "G4TiMemory.hh"
using namespace CLHEP;
@@ -71,7 +72,7 @@ TSPrimaryGeneratorAction::~TSPrimaryGeneratorAction() { delete fGun; }
void TSPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
TIMEMORY_AUTO_TIMER("");
G4USER_SCOPED_PROFILE(__FUNCTION__);
static TSDetectorConstruction* detector = TSDetectorConstruction::Instance();
G4ThreeVector dir(0., 0., 1.);
@@ -202,43 +202,42 @@ void TSRun::RecordEvent(const G4Event* aEvent)
else
G4cout << " Error EvtMap Not Found " << G4endl;
TIMEMORY_AUTO_TIMER("[" + fCollNames.at(i) + "]");
G4USER_SCOPED_PROFILE(fCollNames.at(i));
if(EvtMap)
{
//=== Sum up HitsMap of this event to HitsMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[standard_run_map]");
G4USER_SCOPED_PROFILE("ThreadLocal");
*fRunMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to atomic HitsMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[atomic_run_map]");
*fAtomicRunMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to StatMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[stat_analysis_map]");
G4USER_SCOPED_PROFILE("ThreadLocal/G4StatAnalysis");
// G4StatAnalysis map
*fStatMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to MutexMap of RUN.===
//=== Sum up HitsMap of this event to atomic HitsMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[convergence_test_map]");
// G4ConvergenceTester run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
G4AutoLock lock(&mtx);
*fConvMaps[fCollID] += *EvtMap;
G4USER_SCOPED_PROFILE("Global/Atomic");
*fAtomicRunMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to MutexMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[mutex_run_map]");
G4USER_SCOPED_PROFILE("Global/Mutex");
// mutex run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
G4AutoLock lock(&mtx);
for(const auto& itr : *EvtMap)
fMutexRunMaps[fCollNames[fCollID]][itr.first] += *itr.second;
}
//=== Sum up HitsMap of this event to MutexMap of RUN.===
{
G4USER_SCOPED_PROFILE("Global/Mutex/G4ConvergenceTester");
// G4ConvergenceTester run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
G4AutoLock lock(&mtx);
*fConvMaps[fCollID] += *EvtMap;
}
}
}
}
@@ -65,10 +65,10 @@ G4Run* TSRunAction::GenerateRun() { return new TSRun(fName); }
void TSRunAction::BeginOfRunAction(const G4Run* aRun)
{
G4int evts_to_process = aRun->GetNumberOfEventToBeProcessed();
G4RunManager::GetRunManager()->SetPrintProgress(
(evts_to_process > 100) ? evts_to_process / 100 : 1);
if(IsMaster())
// G4int evts_to_process = aRun->GetNumberOfEventToBeProcessed();
// G4RunManager::GetRunManager()->SetPrintProgress(
// (evts_to_process > 1000) ? evts_to_process / 1000 : 1);
if(IsMaster() && aRun != nullptr)
G4PrintEnv();
}
File diff suppressed because it is too large Load Diff
@@ -60,6 +60,8 @@
#include "G4UIExecutive.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "G4Track.hh"
#include "G4Step.hh"
// for std::system(const char*)
#include <cstdlib>
@@ -86,25 +88,68 @@ void message(G4RunManager* runmanager)
int main(int argc, char** argv)
{
TIMEMORY_INIT(argc, argv);
// initialize timemory
G4Profiler::Configure(argc, argv);
#if defined(GEANT4_USE_TIMEMORY)
// override environment settings
tim::settings::json_output() = true;
tim::settings::dart_output() = true;
tim::settings::dart_type() = "peak_rss";
tim::settings::dart_count() = 1;
#endif
G4String macro;
if(argc > 1)
macro = argv[argc - 1];
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = 0;
if(argc == 1)
if(macro.empty())
ui = new G4UIExecutive(argc, argv);
// Set the random seed
CLHEP::HepRandom::setTheSeed(1245214UL);
#if defined(GEANT4_USE_TIMEMORY)
// The following exists for:
// - G4ProfileType::Run
// - G4ProfileType::Event
// - G4ProfileType::Track
// - G4ProfileType::Step
// - G4ProfileType::User
//
using TrackProfilerConfig = G4ProfilerConfig<G4ProfileType::Track>;
using TrackTool = typename TrackProfilerConfig::type;
TrackProfilerConfig::GetQueryFunctor() = [](const G4Track* _track) {
// only profile if _track != nullptr and dynamic-profiler != nullptr
// and /profiler/track/enable is true
//
return G4Profiler::GetEnabled(G4ProfileType::Track) && _track &&
_track->GetDynamicParticle();
};
TrackProfilerConfig::GetLabelFunctor() = [](const G4Track* _track) {
// create a label for the profiling entry. This can be customized
// to include and information necessary in the returning string
auto pdef = _track->GetDynamicParticle()->GetParticleDefinition();
static std::string _prefix = "G4Track/";
return _prefix + pdef->GetParticleName();
};
// env option to display track profiles as a hierarchy
bool track_tree = tim::get_env<bool>("G4PROFILER_TRACK_TREE", true);
// env option to enable timeline entries (every entry is unique, HUGE amount
// of data!)
bool track_time = tim::get_env<bool>("G4PROFILER_TRACK_TIMELINE", false);
// default scope is tree
auto _scope = tim::scope::config{};
if(track_tree == false)
_scope += tim::scope::flat{};
if(track_time == true)
_scope += tim::scope::timeline{};
TrackProfilerConfig::GetToolFunctor() = [=](const std::string& _label) {
// Configure the profiling tool for a given label. By default,
// G4Track and G4Step tools are "flat profiles" but this can be disabled
// to include tree
return new TrackTool(_label, _scope);
};
#endif
G4RunManager* runmanager =
G4RunManagerFactory::CreateRunManager(G4RunManagerType::Tasking);
@@ -133,16 +178,12 @@ int main(int argc, char** argv)
if(!ui)
{
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[argc - 1];
UImanager->ApplyCommand(command + fileName);
G4String command = "/control/execute ";
UImanager->ApplyCommand(command + macro);
}
else
{
// interactive mode
UImanager->ApplyCommand("/control/execute vis.mac");
ui->SessionStart();
delete ui;
}
// Job termination