Import Geant4 10.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2018-12-07 15:15:39 +01:00
parent 6aa23be517
commit db49709b53
11370 changed files with 187480 additions and 160142 deletions
@@ -1,4 +1,3 @@
//$Id: README,v 1.1 2015-11-05 01:10:10 jmadsen $
///\file "parallel/ThreadsafeScorers/.README.txt"
///\brief Threadsafe Scorers README page
@@ -22,6 +21,10 @@
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.
\section ThreadsafeScorers_s1 ATOMICS and the ATOMIC SCORERS
atomics can ONLY handle plain-old data (POD) types, e.g. int, double, etc.
@@ -120,6 +123,43 @@
In multi-threading mode the energy accumulated in TSRun MFD object per
workers is merged to the master in TSRun::Merge().
Scoring is accumulated with thread-local doubles, thread-global atomics,
mutex-locking, G4StatAnalysis, and G4ConvergenceTester
TSRun contains five hits collections types:
1) a thread-local hits map,
2) a global atomic hits map
3) a global "mutex" hits map
4) a global G4StatAnalysis hits deque
5) a global G4ConvergenceTester hits deque
The thread-local hits map is the same as you will find in many other
examples.
The atomics hits map is the purpose of this example. Code-wise, the
implementation looks extremely similar to the thread-local version with
3 primary exceptions:
(1) construction - there should only be one instance so it should be a
static member variable or a pointer/reference to a single instance
(2) It does not need to, nor should be, summed in G4Run::Merge()
(3) destruction -- it should only be cleared by the master thread since
there is only one instance.
The "mutex" hits map is also included as reference for checking the results
accumulated by the thread-local hits maps and atomic hits maps. The
differences w.r.t. this hits maps are computed in
TSRunAction::EndOfRunAction
The "G4StatAnalysis" and "G4ConvergenceTester" hits deques are
memory-efficient version of the standard G4THitsMap. While maps are
ideal for scoring at the G4Event-level, where sparsity w.r.t. indices
is common; at the G4Run-level, these data structures require much
less memory overhead. Due to a lack of
G4ConvergenceTester::operator+=(G4ConvergenceTester), the static version
of G4ConvergenceTester is the only valid way to use G4ConvergenceTester
in a scoring container. This is not the case for G4StatAnalysis, which
can be used in lieu of G4double.
\section ThreadsafeScorers_s7 HOW TO RUN
- Execute ts_scorers in the 'interactive mode' with visualization:
@@ -146,5 +186,19 @@
% ./ts_scorers run.mac
% ./ts_scorers run.mac > run.out
\section ThreadsafeScorers_s8 TIMEMORY USAGE
This example demonstrates timing and memory analysis with TiMemory
(https://github.com/jrmadsen/TiMemory).
- Compile Geant4 with TiMemory (-DGEANT4_USE_TIMEMORY=ON)
- TiMemory auto-timer 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
*/
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
cmake_minimum_required(VERSION 3.1.3 FATAL_ERROR)
set(name ts_scorers)
project(ThreadsafeScorers)
project(ThreadsafeScorers C CXX)
find_package(Geant4 REQUIRED ui_all vis_all)
include(${Geant4_USE_FILE})
@@ -34,3 +34,7 @@ foreach(_macro ${macros})
COPYONLY)
endforeach()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS ${name} DESTINATION bin)
@@ -1,4 +1,3 @@
$Id: History 93110 2015-11-05 08:37:42Z jmadsen $
-------------------------------------------------------------------
=========================================================
@@ -15,6 +14,22 @@ track of all tags.
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
13/11/2018 Jonathan Madsen (ThreadsafeScorers-V10-04-06)
- Fixed shadowing warnings in G4atomic.hh header (recommit of ThreadsafeScorers-V10-04-03)
11/11/2018 Jonathan Madsen (ThreadsafeScorers-V10-04-05)
- Replaced TIMEMORY_AUTO_TIMER_BASIC with TIMEMORY_BASIC_AUTO_TIMER as the
latter is defined in G4TiMemory.hh and the former is deprecated by TiMemory
- Included plot generation in main
- Added plots/ts_scorers_{timing,memory}.jpeg
- Updated threadsafe_scorers.out
- Updated documentation
09/11/2018 Jonathan Madsen (ThreadsafeScorers-V10-04-04)
- Added scorers with G4StatAnalysis and G4ConvergenceTester
- Improved scheme for using TiMemory to time how long the
scoring takes w.r.t. storage container and PS
15/6/2018 Gabriele Cosmo (ThreadsafeScorers-V10-04-03)
- Fixed shadowing warnings in G4atomic.hh header.
@@ -58,9 +73,9 @@ track of all tags.
- Removed preprocessor checks for C++11
- Removed _HAS_ATOMICS_ preprocessor definition/conditions
- Changed G4atomic to only be defined if G4MULTITHREADED,
otherwise, G4atomic<_Tp> is aliased to _Tp
otherwise, G4atomic<_Tp> is aliased to _Tp
- Included *.in files in macros to be copied to build directory
05/11/15 J. Madsen
- Prefixed classes with "TS" for "Thread-safe"
- Renamed all data members with f + uppercase
@@ -23,6 +23,9 @@
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.
1- ATOMICS and the ATOMIC SCORERS
@@ -44,10 +47,6 @@
with the number of threads, simulations with a large number of scoring
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
@@ -122,7 +121,41 @@
In multi-threading mode the energy accumulated in TSRun MFD object per
workers is merged to the master in TSRun::Merge().
7- HOW TO RUN
TSRun contains five hits collections types:
1) a thread-local hits map,
2) a global atomic hits map
3) a global "mutex" hits map
4) a global G4StatAnalysis hits deque
5) a global G4ConvergenceTester hits deque
The thread-local hits map is the same as you will find in many other
examples.
The atomics hits map is the purpose of this example. Code-wise, the
implementation looks extremely similar to the thread-local version with
3 primary exceptions:
(1) construction - there should only be one instance so it should be a
static member variable or a pointer/reference to a single instance
(2) It does not need to, nor should be, summed in G4Run::Merge()
(3) destruction -- it should only be cleared by the master thread since
there is only one instance.
The "mutex" hits map is also included as reference for checking the results
accumulated by the thread-local hits maps and atomic hits maps. The
differences w.r.t. this hits maps are computed in
TSRunAction::EndOfRunAction
The "G4StatAnalysis" and "G4ConvergenceTester" hits deques are
memory-efficient version of the standard G4THitsMap. While maps are
ideal for scoring at the G4Event-level, where sparsity w.r.t. indices
is common; at the G4Run-level, these data structures require much
less memory overhead. Due to a lack of
G4ConvergenceTester::operator+=(G4ConvergenceTester), the static version
of G4ConvergenceTester is the only valid way to use G4ConvergenceTester
in a scoring container. This is not the case for G4StatAnalysis, which
can be used in lieu of G4double.
7- HOW TO RUN
- Execute ts_scorers in the 'interactive mode' with visualization:
% ./ts_scorers
@@ -142,4 +175,16 @@
% ./ts_scorers run.mac
% ./ts_scorers run.mac > run.out
8- TIMEMORY USAGE
This example demonstrates timing and memory analysis with TiMemory
(https://github.com/jrmadsen/TiMemory).
- Compile Geant4 with TiMemory (-DGEANT4_USE_TIMEMORY=ON)
- TiMemory auto-timer 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
@@ -27,7 +27,6 @@
/// \brief Definition of the G4TAtomicHitsCollection class
//
//
// $Id: G4TAtomicHitsCollection.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is an implementation of G4THitsCollection<T> where the underlying
@@ -27,7 +27,6 @@
/// \brief Definition of the G4TAtomicHitsMap class
//
//
// $Id: G4TAtomicHitsMap.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is an implementation of G4THitsMap<T> where the underlying
@@ -131,6 +130,8 @@ public:
return theCollection->size();
}
virtual size_t size() const { return theCollection->size(); }
public:
iterator begin() { return theCollection->begin(); }
iterator end() { return theCollection->end(); }
@@ -27,7 +27,6 @@
/// \brief Definition of the G4atomic class
//
//
// $Id: G4atomic.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is an friendly implementation of the STL atomic class.
@@ -27,7 +27,6 @@
/// \brief Definition of the G4atomic_defines class
//
//
// $Id: G4atomic_defines.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is a functional class for G4atomic. The functions in this
@@ -27,7 +27,6 @@
/// \brief Definition of the TSActionInitialization class
//
//
// $Id: TSActionInitialization.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Standard ActionInitialization class creating a RunAction instance for the
@@ -27,7 +27,6 @@
/// \brief Definition of the TSDetectorConstruction class
//
//
// $Id: TSDetectorConstruction.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Construction of a target material (default = boron) surrounded by a
@@ -89,6 +88,8 @@ public:
inline const ScoringVolumes_t& GetScoringVolumes() const
{ return fScoringVolumes; }
inline const G4String& GetMFDName() const { return fMfdName; }
inline G4int GetTotalTargets() const
{ return fTargetSections.x() * fTargetSections.y() * fTargetSections.z(); }
protected:
virtual MaterialCollection_t ConstructMaterials();
@@ -27,7 +27,6 @@
/// \brief Definition of the TSPhysicsList class
//
//
// $Id: TSPhysicsList.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is a very, very extensive physics list and step-limiters are applied
@@ -27,7 +27,6 @@
/// \brief Definition of the TSPrimaryGeneratorAction class
//
//
// $Id: TSPrimaryGeneratorAction.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Simple PrimaryGeneratorAction that produces a -Z surface flux of 1 MeV
@@ -27,7 +27,6 @@
/// \brief Definition of the TSRun class
//
//
// $Id: TSRun.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// TSRun contains three collections of hits maps: a thread-local hits map,
@@ -62,11 +61,18 @@
#include "G4Event.hh"
#include "G4THitsMap.hh"
#include "G4TAtomicHitsMap.hh"
#include "G4THitsVector.hh"
#include "G4StatAnalysis.hh"
#include "G4ConvergenceTester.hh"
#include <vector>
class G4Event;
//template <typename _Tp> using G4StatContainer = G4THitsMap<_Tp>;
//template <typename _Tp> using G4StatContainer = G4THitsVector<_Tp>;
template <typename _Tp> using G4StatContainer = G4THitsDeque<_Tp>;
class TSRun : public G4Run
{
public:
@@ -85,6 +91,8 @@ public:
G4THitsMap<G4double>* GetHitsMap(const G4String& collname) const;
G4TAtomicHitsMap<G4double>* GetAtomicHitsMap(const G4String&) const;
MutexHitsMap_t* GetMutexHitsMap(const G4String&) const;
G4StatContainer<G4StatAnalysis>* GetStatMap(const G4String& collname) const;
G4StatContainer<G4ConvergenceTester>* GetConvMap(const G4String&) const;
void ConstructMFD(const G4String&);
@@ -94,8 +102,10 @@ private:
std::vector<G4String> fCollNames;
std::vector<G4int> fCollIDs;
std::vector<G4THitsMap<G4double>*> fRunMaps;
std::vector<G4StatContainer<G4StatAnalysis>*> fStatMaps;
static std::vector<G4TAtomicHitsMap<G4double>*> fAtomicRunMaps;
static std::map<G4String, MutexHitsMap_t> fMutexRunMaps;
static std::vector<G4StatContainer<G4ConvergenceTester>*> fConvMaps;
};
@@ -27,7 +27,6 @@
/// \brief Definition of the TSRunAction class
//
//
// $Id: TSRunAction.hh 93110 2015-11-05 08:37:42Z jmadsen $
//
//
//
Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

@@ -27,7 +27,6 @@
/// \brief Implementation of the TSActionInitialization class
//
//
// $Id: TSActionInitialization.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Standard ActionInitialization class creating a RunAction instance for the
@@ -27,7 +27,6 @@
/// \brief Implementation of the TSDetectorConstruction class
//
//
// $Id: TSDetectorConstruction.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Construction of a target material (default = boron) surrounded by a
@@ -138,7 +137,7 @@ TSDetectorConstruction::ConstructWorld(const MaterialCollection_t& materials)
{
G4UserLimits* steplimit = new G4UserLimits(0.1*(fTargetDim.z()
/fTargetSections.z()));
G4bool check_overlap = true;
G4bool check_overlap = false;
G4Box* world_solid = new G4Box("World",
0.5*fWorldDim.x(),
@@ -27,7 +27,6 @@
/// \brief Implementation of the TSPhysicsList class
//
//
// $Id: TSPhysicsList.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// This is a very, very extensive physics list and step-limiters are applied
@@ -27,7 +27,6 @@
/// \brief Implementation of the TSPrimaryGeneratorAction class
//
//
// $Id: TSPrimaryGeneratorAction.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// Simple PrimaryGeneratorAction that produces a -Z surface flux of 1 MeV
@@ -27,26 +27,42 @@
/// \brief Implementation of the TSRun class
//
//
// $Id: TSRun.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// TSRun contains three collections of hits maps: a thread-local hits map,
/// a global atomic hits map (implemented as a static since TSRun is
/// implemented as a thread-local instance), and a global "mutex" hits map
/// (also implemented as a static). The thread-local hits map is the
/// same as you will find in many other examples. The atomics hits map
/// is the purpose of this example. Code-wise, the implementation looks
/// extremely similar to the thread-local version with the 3 primary
/// exceptions: (1) construction - there should only be one instance so
/// it should be a static member variable or a pointer/reference to a
/// single instance elsewhere in the code (stored in ActionInitialization,
/// for instance); (2) It does not need to, nor should be, summed in
/// G4Run::Merge(); and (3) destruction -- it should only be cleared by
/// the master thread since there is only one instance.
/// A "mutex" hits map is also included as reference for checking the results
/// TSRun contains five hits collections types:
/// 1) a thread-local hits map,
/// 2) a global atomic hits map
/// 3) a global "mutex" hits map
/// 4) a global G4StatAnalysis hits deque
/// 5) a global G4ConvergenceTester hits deque
///
/// The thread-local hits map is the same as you will find in many other
/// examples.
///
/// The atomics hits map is the purpose of this example. Code-wise, the
/// implementation looks extremely similar to the thread-local version with
/// 3 primary exceptions:
/// (1) construction - there should only be one instance so it should be a
/// static member variable or a pointer/reference to a single instance
/// (2) It does not need to, nor should be, summed in G4Run::Merge()
/// (3) destruction -- it should only be cleared by the master thread since
/// there is only one instance.
///
/// The "mutex" hits map is also included as reference for checking the results
/// accumulated by the thread-local hits maps and atomic hits maps. The
/// differences w.r.t. this hits maps are computed in
/// TSRunAction::EndOfRunAction
///
/// The "G4StatAnalysis" and "G4ConvergenceTester" hits deques are
/// memory-efficient version of the standard G4THitsMap. While maps are
/// ideal for scoring at the G4Event-level, where sparsity w.r.t. indices
/// is common; at the G4Run-level, these data structures require much
/// less memory overhead. Due to a lack of
/// G4ConvergenceTester::operator+=(G4ConvergenceTester), the static version
/// of G4ConvergenceTester is the only valid way to use G4ConvergenceTester
/// in a scoring container. This is not the case for G4StatAnalysis, which
/// can be used in lieu of G4double.
///
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -59,6 +75,7 @@
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4TiMemory.hh"
#include "TSDetectorConstruction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -66,6 +83,8 @@ std::vector<G4TAtomicHitsMap<G4double>*> TSRun::fAtomicRunMaps;
std::map<G4String, TSRun::MutexHitsMap_t> TSRun::fMutexRunMaps;
std::vector<G4StatContainer<G4ConvergenceTester>*> TSRun::fConvMaps;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TSRun::TSRun(const G4String& mfd_name)
@@ -87,8 +106,12 @@ TSRun::~TSRun()
for(unsigned i = 0; i < fAtomicRunMaps.size(); ++i)
delete fAtomicRunMaps[i];
for(auto& itr: fConvMaps)
delete itr;
fAtomicRunMaps.clear();
fMutexRunMaps.clear();
fConvMaps.clear();
}
}
@@ -130,11 +153,19 @@ void TSRun::ConstructMFD(const G4String& mfdName)
fCollIDs.push_back(collectionID);
fRunMaps.push_back(new G4THitsMap<G4double>(mfdName,
collectionName));
fStatMaps.push_back(new G4StatContainer<G4StatAnalysis>(
mfdName,
collectionName,
TSDetectorConstruction::Instance()->GetTotalTargets()));
if(!G4Threading::IsWorkerThread())
{
fAtomicRunMaps.push_back(new G4TAtomicHitsMap<G4double>
(mfdName, collectionName));
fMutexRunMaps[fCollNames[collectionID]].clear();
fConvMaps.push_back(new G4StatContainer<G4ConvergenceTester>(
mfdName,
collectionName,
TSDetectorConstruction::Instance()->GetTotalTargets()));
}
} else {
G4cout << "** collection " << fullCollectionName << " not found. "
@@ -158,7 +189,8 @@ void TSRun::RecordEvent(const G4Event* aEvent)
// HitsCollection of This Event
//============================
G4HCofThisEvent* HCE = aEvent->GetHCofThisEvent();
if (!HCE) return;
if (!HCE)
return;
for(unsigned i = 0; i < fCollIDs.size(); ++i)
{
@@ -172,33 +204,46 @@ void TSRun::RecordEvent(const G4Event* aEvent)
else
G4cout <<" Error EvtMap Not Found " << G4endl;
TIMEMORY_AUTO_TIMER("[" + fCollNames.at(i) + "]");
if ( EvtMap )
{
//=== Sum up HitsMap of this event to HitsMap of RUN.===
{
TIMEMORY_AUTO_TIMER("[standard_run_map]");
TIMEMORY_BASIC_AUTO_TIMER("[standard_run_map]");
*fRunMaps[fCollID] += *EvtMap;
}
// atomic run map
//=== Sum up HitsMap of this event to atomic HitsMap of RUN.===
{
TIMEMORY_AUTO_TIMER("[atomic_run_map]");
TIMEMORY_BASIC_AUTO_TIMER("[atomic_run_map]");
*fAtomicRunMaps[fCollID] += *EvtMap;
}
TIMEMORY_AUTO_TIMER("[mutex_run_map]");
// mutex run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
//=== Sum up HitsMap of this event to StatMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[stat_analysis_map]");
// G4StatAnalysis map
*fStatMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to MutexMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[convergence_test_map]");
// G4ConvergenceTester run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
G4AutoLock lock(&mtx);
*fConvMaps[fCollID] += *EvtMap;
}
//=== Sum up HitsMap of this event to MutexMap of RUN.===
{
TIMEMORY_BASIC_AUTO_TIMER("[mutex_run_map]");
// mutex run map
static G4Mutex mtx = G4MUTEX_INITIALIZER;
G4AutoLock lock(&mtx);
for(const auto& itr : *EvtMap)
{
fMutexRunMaps[fCollNames[fCollID]][itr.first]
+= *itr.second;
}
}
//----------------------------------------------------------------//
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -209,7 +254,10 @@ void TSRun::Merge(const G4Run* aTSRun)
const TSRun* localTSRun = static_cast<const TSRun*>(aTSRun);
for(unsigned i = 0; i < fRunMaps.size(); ++i)
*fRunMaps[i] += *localTSRun->fRunMaps[i];
{
*fRunMaps[i] += *localTSRun->fRunMaps[i];
*fStatMaps[i] += *localTSRun->fStatMaps[i];
}
G4Run::Merge(aTSRun);
}
@@ -268,3 +316,36 @@ TSRun::GetMutexHitsMap(const G4String& collName) const
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Access StatMap.
// by full description of collection name, that is
// <MultiFunctional Detector Name>/<Primitive Scorer Name>
G4StatContainer<G4StatAnalysis>*
TSRun::GetStatMap(const G4String& collName) const
{
for(unsigned i = 0; i < fCollNames.size(); ++i)
{
if(collName == fCollNames[i])
return fStatMaps[i];
}
G4Exception("TSRun", collName.c_str(), JustWarning,
"GetStatMap failed to locate the requested StatMap");
return nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StatContainer<G4ConvergenceTester>*
TSRun::GetConvMap(const G4String& collName) const
{
for(unsigned i = 0; i < fCollNames.size(); ++i)
{
if(collName == fCollNames[i])
return fConvMaps[i];
}
G4Exception("TSRun", collName.c_str(), JustWarning,
"GetHitsMap failed to locate the requested AtomicHitsMap");
return nullptr;
}
@@ -27,7 +27,6 @@
/// \brief Implementation of the TSRunAction class
//
//
// $Id: TSRunAction.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
//
@@ -45,6 +44,7 @@
#include "TSRun.hh"
#include "TSDetectorConstruction.hh"
#include "G4StatAnalysis.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -73,6 +73,8 @@ void TSRunAction::BeginOfRunAction(const G4Run* aRun)
G4RunManager::GetRunManager()->SetPrintProgress((evts_to_process > 100)
? evts_to_process/100
: 1);
if(IsMaster())
G4PrintEnv();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -108,105 +110,174 @@ void TSRunAction::EndOfRunAction(const G4Run* aRun)
std::vector<G4double> units { CLHEP::eV, CLHEP::keV, 1, 1 };
std::vector<G4String> unitstr { "keV", "steps" };
for(unsigned i = 0; i < primScorerNames.size(); ++i)
{
for(unsigned j = 0; j < fnames.size(); ++j)
{
//----------------------------------------------------------------//
auto print = [] (std::ostream& fout,
//----------------------------------------------------------------------//
// lambda to print double value
auto print = [] (std::ostream& fout,
G4int first, G4double second,
G4double unit1, G4double unit2, G4String unit2str)
{
if(fout)
{
if(fout)
fout << first
<< " " << second/unit1
<< G4endl;
G4cout
<< " " << std::setw(10) << first
<< " " << std::setw(15) << std::setprecision(6)
<< std::fixed << second/unit2 << " " << unit2str
<< G4endl;
G4cout.unsetf(std::ios::fixed);
};
//----------------------------------------------------------------//
fname = fnames.at(j) + "_" + primScorerNames.at(i) + ".out";
fileout.open(fname);
G4cout << separator.str() << G4endl;
G4cout << " opened file " << fname << " for output" << G4endl;
G4cout << separator.str() << G4endl;
G4bool valid = true;
if(j == 0)
G4cout
<< " " << std::setw(10) << first
<< " " << std::setw(15) << std::setprecision(6)
<< std::fixed << second/unit2 << " " << unit2str
<< G4endl;
G4cout.unsetf(std::ios::fixed);
};
//----------------------------------------------------------------------//
// lambda to print statistics
auto stat_print = [] (std::ostream& fout,
G4int first, G4StatAnalysis* stat, G4ConvergenceTester* conv,
G4double unit1, G4double unit2, G4String unit2str)
{
if(!stat || !conv)
return;
auto fsecond = (*stat);
auto psecond = (*stat);
fsecond /= unit1;
psecond /= unit2;
if(fout)
{
G4THitsMap<G4double>* hitmap
= tsRun->GetHitsMap(fName + "/" + primScorerNames.at(i));
if(hitmap && hitmap->GetMap()->size() != 0)
{
for(auto itr = hitmap->GetMap()->begin();
itr != hitmap->GetMap()->end(); itr++)
{
IDs.insert(itr->first);
std::get<0>(fTypeCompare[primScorerNames.at(i)][itr->first])
= *itr->second/units.at(i);
print(fileout, itr->first, *itr->second,
units.at(i), units.at(i+1), unitstr.at(i));
}
} else {
valid = false;
}
if(!valid)
{
G4Exception("TSRunAction", "000", JustWarning,
G4String(primScorerNames.at(i) +
" HitsMap is either not "
"created or the HitsMap was empty").c_str());
}
} else {
G4TAtomicHitsMap<G4double>* hitmap
= tsRun->GetAtomicHitsMap(fName + "/" +
primScorerNames.at(i));
if(hitmap && hitmap->GetMap()->size() != 0)
{
for(auto itr = hitmap->GetMap()->begin();
itr != hitmap->GetMap()->end(); itr++)
{
IDs.insert(itr->first);
std::get<1>(fTypeCompare[primScorerNames.at(i)][itr->first])
= *itr->second/units.at(i);
print(fileout, itr->first, *itr->second,
units.at(i), units.at(i+1), unitstr.at(i));
}
} else {
valid = false;
}
if(!valid)
{
G4Exception("TSRunAction", "001", JustWarning,
G4String(primScorerNames.at(i) +
" HitsMap is either not "
"created or the HitsMap was empty").c_str());
}
fout << first << " " << fsecond << G4endl;
conv->ShowResult(fout);
}
std::stringstream ss;
ss << " " << std::setw(10) << first
<< " " << std::setw(15) << std::setprecision(6)
<< std::fixed << psecond << " " << unit2str;
// skip print of ConvergenceTester to stdout
G4cout << ss.str() << G4endl;
};
//----------------------------------------------------------------------//
fileout.close();
G4cout << separator.str() << G4endl;
G4cout << " closed file " << fname << " for output" << G4endl;
for(unsigned i = 0; i < primScorerNames.size(); ++i)
{
for(unsigned j = 0; j < fnames.size(); ++j)
{
fname = fnames.at(j) + "_" + primScorerNames.at(i) + ".out";
fileout.open(fname);
G4cout << separator.str() << G4endl;
G4cout << " opened file " << fname << " for output" << G4endl;
G4cout << separator.str() << G4endl;
G4bool valid = true;
if(j == 0)
{
G4THitsMap<G4double>* hitmap
= tsRun->GetHitsMap(fName + "/" + primScorerNames.at(i));
G4StatContainer<G4StatAnalysis>* statmap
= tsRun->GetStatMap(fName + "/" + primScorerNames.at(i));
G4StatContainer<G4ConvergenceTester>* convmap
= tsRun->GetConvMap(fName + "/" + primScorerNames.at(i));
if(hitmap && hitmap->size() != 0)
{
for(auto itr = hitmap->begin(); itr != hitmap->end(); itr++)
{
if(!hitmap->GetObject(itr))
continue;
IDs.insert(itr->first);
std::get<0>(fTypeCompare[primScorerNames.at(i)][itr->first])
= *itr->second/units.at(i);
print(fileout, itr->first, *itr->second,
units.at(i), units.at(i+1), unitstr.at(i));
}
}
else
{
valid = false;
}
if(statmap && statmap->size() != 0 &&
convmap && convmap->size() != 0)
{
auto stat_fname = "stat_" + fname;
std::ofstream statout;
statout.open(stat_fname);
for(auto itr = statmap->begin(); itr != statmap->end(); itr++)
{
G4int _f = statmap->GetIndex(itr);
G4StatAnalysis* _s = statmap->GetObject(itr);
G4ConvergenceTester* _c = convmap->GetObject(_f);
stat_print(statout, _f, _s, _c,
units.at(i), units.at(i+1), unitstr.at(i));
}
statout.close();
}
else
{
std::stringstream ss;
ss << " StatMap/ConvMap is either not "
<< "created or the StatMap/ConvMap was empty";
if(statmap)
ss << " (StatMap size == " << statmap->size() << ")";
if(convmap)
ss << " (ConvMap size == " << convmap->size() << ")";
G4Exception("TSRunAction", "002", JustWarning,
G4String(primScorerNames.at(i) +
ss.str()).c_str());
}
if(!valid)
{
G4Exception("TSRunAction", "000", JustWarning,
G4String(primScorerNames.at(i) +
" HitsMap is either not "
"created or the HitsMap was empty").c_str());
}
}
else
{
G4TAtomicHitsMap<G4double>* hitmap
= tsRun->GetAtomicHitsMap(fName + "/" +
primScorerNames.at(i));
if(hitmap && hitmap->size() != 0)
{
for(auto itr = hitmap->begin(); itr != hitmap->end(); itr++)
{
IDs.insert(itr->first);
std::get<1>(fTypeCompare[primScorerNames.at(i)][itr->first])
= *itr->second/units.at(i);
print(fileout, itr->first, *itr->second,
units.at(i), units.at(i+1), unitstr.at(i));
}
}
else
{
valid = false;
}
if(!valid)
{
G4Exception("TSRunAction", "001", JustWarning,
G4String(primScorerNames.at(i) +
" HitsMap is either not "
"created or the HitsMap was empty").c_str());
}
}
fileout.close();
G4cout << separator.str() << G4endl;
G4cout << " closed file " << fname << " for output" << G4endl;
}
// add the mutex data
TSRun::MutexHitsMap_t* hitmap
= tsRun->GetMutexHitsMap(fName + "/" +
primScorerNames.at(i));
= tsRun->GetMutexHitsMap(fName + "/" +
primScorerNames.at(i));
if(hitmap && hitmap->size() != 0)
{
for(auto itr = hitmap->begin();
itr != hitmap->end(); itr++)
{
IDs.insert(itr->first);
std::get<2>(fTypeCompare[primScorerNames.at(i)][itr->first])
= itr->second/units.at(i);
}
for(auto itr = hitmap->begin();
itr != hitmap->end(); itr++)
{
IDs.insert(itr->first);
std::get<2>(fTypeCompare[primScorerNames.at(i)][itr->first])
= itr->second/units.at(i);
}
}
}
@@ -223,70 +294,69 @@ void TSRunAction::EndOfRunAction(const G4Run* aRun)
G4cout << " opened file " << fname << " for difference output" << G4endl;
G4cout << separator.str() << G4endl;
fileout
<< " " << std::setw(10) << "ID"
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< "MFD value"
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< "Atomic Hits Map value"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Difference"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Diff (MFD - MUTEXED)"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Diff (ATOM_HIT_MAP - MUTEXED)"
<< G4endl << G4endl;
fileout << " " << std::setw(10) << "ID"
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< "MFD value"
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< "Atomic Hits Map value"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Difference"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Diff (MFD - MUTEXED)"
<< " "
<< std::setw(30) << std::setprecision(8) << std::scientific
<< "Diff (ATOM_HIT_MAP - MUTEXED)"
<< G4endl << G4endl;
for(auto itr1 = fTypeCompare.begin();
itr1 != fTypeCompare.end(); ++itr1)
{
fileout << "\n\nType = " << itr1->first << "\n" << G4endl;
for(auto itr2 = itr1->second.begin();
itr2 != itr1->second.end(); ++itr2)
{
G4double d01
= std::fabs(std::get<0>(itr2->second) -
std::get<1>(itr2->second));
G4double d02
= std::fabs(std::get<0>(itr2->second) -
std::get<2>(itr2->second));
G4double d03
= std::fabs(std::get<1>(itr2->second) -
std::get<2>(itr2->second));
auto _print_diff = [&] (const G4double& _dval)
fileout << "\n\nType = " << itr1->first << "\n" << G4endl;
for(auto itr2 = itr1->second.begin();
itr2 != itr1->second.end(); ++itr2)
{
if(_dval > 0.0)
fileout << std::setprecision(8) << std::scientific
<< std::setw(30) << _dval << " ";
else
fileout << std::setprecision(1) << std::fixed
<< std::setw(30) << _dval << " ";
};
G4double d01
= std::fabs(std::get<0>(itr2->second) -
std::get<1>(itr2->second));
G4double d02
= std::fabs(std::get<0>(itr2->second) -
std::get<2>(itr2->second));
G4double d03
= std::fabs(std::get<1>(itr2->second) -
std::get<2>(itr2->second));
fileout
<< " " << std::setw(10) << itr2->first
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< std::get<0>(itr2->second)
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< std::get<1>(itr2->second)
<< " ";
_print_diff(d01);
_print_diff(d02);
_print_diff(d03);
auto _print_diff = [&] (const G4double& _dval)
{
if(_dval > 0.0)
fileout << std::setprecision(8) << std::scientific
<< std::setw(30) << _dval << " ";
else
fileout << std::setprecision(1) << std::fixed
<< std::setw(30) << _dval << " ";
};
fileout << G4endl;
fileout
<< " " << std::setw(10) << itr2->first
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< std::get<0>(itr2->second)
<< " "
<< std::setw(30) << std::setprecision(12) << std::fixed
<< std::get<1>(itr2->second)
<< " ";
}
_print_diff(d01);
_print_diff(d02);
_print_diff(d03);
fileout << G4endl;
}
}
fileout.close();
File diff suppressed because it is too large Load Diff
@@ -27,7 +27,6 @@
/// \brief Main of the ThreadsafeScorers example
//
//
// $Id: ts_scorers.cc 93110 2015-11-05 08:37:42Z jmadsen $
//
//
/// ts_scorers example shows how to use global scorers. The benefit of using
@@ -67,6 +66,9 @@
#include "G4UIExecutive.hh"
#include "G4TiMemory.hh"
// for std::system(const char*)
#include <cstdlib>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void message(RunManager* runmanager)
@@ -139,12 +141,31 @@ int main(int argc, char** argv)
#ifdef GEANT4_USE_TIMEMORY
G4cout << "\nOutputting TiMemory results...\n" << G4endl;
tim::manager* manager = tim::manager::instance();
# if defined(G4MULTITHREADED)
// TiMemory by default will report master + workers
manager->set_get_num_threads_func(
[=]() { return runmanager->GetNumberOfThreads(); });
# endif
manager->write_report(std::cout, true);
std::string fname = argv[0];
std::string rfname = fname + ".txt";
std::string sfname = fname + ".json";
manager->write_report(rfname);
manager->write_serialization(sfname);
if(std::system(nullptr))
{
std::stringstream ss;
ss << "timemory-plotter -f " << sfname << " -t \"ThreadSafe Scorers\" "
<< "-o plots -e --timing-fields cpu wall sys";
int ret = std::system(ss.str().c_str());
if(ret != 0)
{
G4ExceptionDescription desc;
desc << "Error generating plots with command: '"
<< ss.str() << "'";
G4Exception("ThreadsafeScorers::main", "0001", JustWarning, desc);
}
}
#endif
// Job termination