------------------------------------------------------------------- ========================================================= Geant4 - an Object-Oriented Toolkit for Simulation in HEP ========================================================= 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 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 to ensure that there is a higher degree of conflict between threads 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__.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 1- ATOMICS and the ATOMIC SCORERS atomics can ONLY handle plain-old data (POD) types, e.g. int, double, etc. The implementation of atomics in compiler-dependent. At the very worst, the performance of an atomic is the same mutex locking. Atomics, in general, are not copy-constructable. This has to do with thread safety (e.g. making a copy while another thread tries to update) This is why atomics cannot be used in STL containers. The implementation 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 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 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 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). 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 The constructors are: G4EmStandardPhysics_option4 G4DecayPhysics G4RadioactiveDecayPhysics G4HadronPhysicsQGSP_BERT_HP G4HadronElasticPhysicsHP G4StepLimiterPhysics G4IonElasticPhysics G4IonBinaryCascadePhysics 4- ACTION INITALIZATION TSActionInitialization, instantiates and registers to Geant4 kernel all user action classes. While in sequential mode the action classes are instatiated just once, via invoking the method: TSActionInitialization::Build() 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 and global that's why its instance is created also in the method 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 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. When the MFD is recording an event i.e. TSRun::RecordEvent(const G4Event*), the global atomic hits map adds the same hits collections 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 - 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> ... Idle> exit or Idle> /control/execute run.mac .... Idle> exit - Execute ts_scorers in the 'batch' mode from macro files (without visualization) % ./ts_scorers run.mac % ./ts_scorers run.mac > run.out