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
@@ -224,4 +224,15 @@ differences:
how to merge scorers
- MT is enabled.
\link exMPI04 exMPI04 (merging of ntuples via MPI) \endlink
This example is the same as exMPI03 with added ntuple.
- It uses g4tools for histogramming and ntuples.
- It shows how to merge, using g4tools, ntuples via MPI in sequential mode,
so that the entire statistics is accumulated in a single output file.
- If MT is enabled, the ntuples are merged from threads to
files per ranks.
- Combined MT + MPI merging is not yet supported.
- Merging ntuples is actually supported only with Root output format.
*/
+12
View File
@@ -9,6 +9,18 @@
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
23 November 2018 I. Hrivnacova (MPI-V10-04-01)
- Adapted g4mpi to allow to define an extra worker for collecting data
from processing workers (needed for merging ntuples)
- Added classes for ntuple merging (in source/analysis)
- Added exMPI04 demonstrating merging ntuples via MPI
(with Root output only)
- In exMPI03: fixed warning from analysis when opening the second output
file (dose-merged) within the same run
02 May 2018 J.Allison (MPI-V10-04-00)
- Removed G4VIS_USE and G4UI_USE.
28 November 2017 B.Morgan (MPI-V10-03-02)
- Repace ROOT_INCLUDE_DIR with ROOT_INCLUDE_DIRS
+12
View File
@@ -224,3 +224,15 @@ differences:
- It also shows how to merge G4Run objects from different ranks and
how to merge scorers
- MT is enabled.
exMPI04 (merging of ntuples via MPI)
---------------------------------------
This example is the same as exMPI03 with added ntuple.
- It uses g4tools for histogramming and ntuples.
- It shows how to merge, using g4tools, ntuples via MPI in sequential mode,
so that the entire statistics is accumulated in a single output file.
- If MT is enabled, the ntuples are merged from threads to
files per ranks.
- Combined MT + MPI merging is not yet supported.
- Merging ntuples is actually supported only with Root output format.
@@ -107,4 +107,28 @@ geant4_add_test(mpi-ex03
LABELS MPI
)
# - Build/Test exMPI04
# variable to simplify paths
set(G4MPI_EX04_BINDIR ${G4MPI_CTESTS_BASE_OUTPUT_DIR}/exMPI04)
geant4_add_test(mpi-ex04-sequential
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/examples/exMPI04
BINARY_DIR ${G4MPI_EX04_BINDIR}
PROJECT exMPI04
BUILD exMPI04
COMMAND ${G4MPI_EX04_BINDIR}/exMPI04 run.mac
WORKING_DIRECTORY ${G4MPI_EX04_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-libg4mpi
LABELS MPI
)
# Needs G4mpi
set_property(TEST mpi-ex04-sequential APPEND PROPERTY ENVIRONMENT G4mpi_DIR=${G4mpi_DIR})
geant4_add_test(mpi-ex04
COMMAND ${MPIEXEC} -n 3 ${G4MPI_EX04_BINDIR}/exMPI04 run.mac
WORKING_DIRECTORY ${G4MPI_EX04_BINDIR}
ENVIRONMENT ${GEANT4_TEST_ENVIRONMENT}
DEPENDS mpi-ex04-sequential
LABELS MPI
)
@@ -5,3 +5,4 @@ cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
add_subdirectory(exMPI01)
add_subdirectory(exMPI02)
add_subdirectory(exMPI03)
add_subdirectory(exMPI04)
@@ -41,6 +41,6 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
*/
@@ -34,4 +34,4 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
/// @file exMPI01.cc
// $Id: exMPI01.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @brief A MPI example code
@@ -38,9 +37,7 @@
#include "G4UImanager.hh"
#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
@@ -87,11 +84,9 @@ int main(int argc, char** argv)
runManager-> Initialize();
#ifdef G4VIS_USE
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
G4cout << G4endl;
#endif
// --------------------------------------------------------------------
// ready for go
@@ -103,9 +98,7 @@ int main(int argc, char** argv)
// --------------------------------------------------------------------
// termination
// --------------------------------------------------------------------
#ifdef G4VIS_USE
delete visManager;
#endif
delete g4MPI;
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.hh
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.hh 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Materials.hh 71843 2013-06-25 16:58:09Z gcosmo $
//
/// @file Materials.hh
/// @brief Define materials
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.hh 98250 2016-07-04 17:27:47Z gcosmo $
//
/// @file PrimaryGeneratorAction.hh
/// @brief Define primary generator action
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.cc 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.cc
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file DetectorConstruction.cc
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Materials.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file Materials.cc
/// @brief Define materials
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.cc 98250 2016-07-04 17:27:47Z gcosmo $
//
/// @file PrimaryGeneratorAction.cc
/// @brief Define primary generator action
@@ -45,6 +45,6 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
*/
@@ -41,4 +41,4 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
/// @file exMPI02.cc
// $Id: exMPI02.cc 88353 2015-02-16 08:54:08Z gcosmo $
//
/// @brief A MPI example code
@@ -38,9 +37,7 @@
#include "G4UImanager.hh"
#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
@@ -81,11 +78,9 @@ int main(int argc, char** argv)
runManager-> Initialize();
#ifdef G4VIS_USE
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
G4cout << G4endl;
#endif
// --------------------------------------------------------------------
// ready for go
@@ -97,9 +92,7 @@ int main(int argc, char** argv)
// --------------------------------------------------------------------
// termination
// --------------------------------------------------------------------
#ifdef G4VIS_USE
delete visManager;
#endif
delete g4MPI;
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.hh
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Analysis.hh 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file Analysis.hh
/// @brief Define histograms
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.hh 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: EventAction.hh 71843 2013-06-25 16:58:09Z gcosmo $
//
/// @file EventAction.hh
/// @brief Describe event actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: MedicalBeam.hh 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file MedicalBeam.hh
/// @brief Define beam profile as primary generator
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunAction.hh 71843 2013-06-25 16:58:09Z gcosmo $
//
/// @file RunAction.hh
/// @brief Describe run actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelParam.hh 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file VoxelParam.hh
/// @brief Define voxel parameterization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelSD.hh 71843 2013-06-25 16:58:09Z gcosmo $
//
/// @file VoxelSD.hh
/// @brief Define detector sensitivity on voxels
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.cc 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.cc
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Analysis.cc 88353 2015-02-16 08:54:08Z gcosmo $
//
/// @file Analysis.cc
/// @brief Define histograms
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: EventAction.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file EventAction.cc
/// @brief Describe event actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: MedicalBeam.cc 88353 2015-02-16 08:54:08Z gcosmo $
//
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunAction.cc 88353 2015-02-16 08:54:08Z gcosmo $
//
/// @file RunAction.cc
/// @brief Describe run actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelParam.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelSD.cc 78126 2013-12-03 17:43:56Z gcosmo $
//
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
@@ -54,6 +54,6 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
*/
@@ -5,7 +5,7 @@ Description
-----------
An example of dosimetry in a water phantom.
The example has same geometry and physics as exMPI02, only the analysis part
is diffenrent.
is different.
### Configuration:
- Geometry : water phantom
@@ -51,4 +51,4 @@ Follow these commands,
> make
> make install
Repalce mpicxx with your MPI-compiler wrapper
Replace mpicxx with your MPI-compiler wrapper.
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
/// @file exMPI03.cc
// $Id: exMPI03.cc 82310 2014-06-14 00:27:39Z adotti $
//
/// @brief A MPI example code
@@ -38,9 +37,7 @@
#include "G4UImanager.hh"
#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
@@ -82,11 +79,9 @@ G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
runManager-> Initialize();
#ifdef G4VIS_USE
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
G4cout << G4endl;
#endif
// --------------------------------------------------------------------
// ready for go
@@ -98,9 +93,7 @@ G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
// --------------------------------------------------------------------
// termination
// --------------------------------------------------------------------
#ifdef G4VIS_USE
delete visManager;
#endif
delete g4MPI;
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.hh
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Analysis.hh 76431 2013-11-10 20:28:49Z kmura $
//
/// @file Analysis.hh
/// @brief Define histograms
@@ -51,7 +50,7 @@ public:
void Update();
void Clear();
void Save(const G4String& fname);
void Close();
void Close(G4bool reset = true);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.hh 76431 2013-11-10 20:28:49Z kmura $
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: EventAction.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file EventAction.hh
/// @brief Describe event actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: MedicalBeam.hh 76431 2013-11-10 20:28:49Z kmura $
//
/// @file MedicalBeam.hh
/// @brief Define beam profile as primary generator
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunAction.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file RunAction.hh
/// @brief Describe run actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunActionMaster.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file RunActionMaster.hh
/// @brief Describe run actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelParam.hh 76431 2013-11-10 20:28:49Z kmura $
//
/// @file VoxelParam.hh
/// @brief Define voxel parameterization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelSD.hh 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file VoxelSD.hh
/// @brief Define detector sensitivity on voxels
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: PrimaryGeneratorAction.cc 66587 2012-12-21 11:06:44Z ihrivnac $
//
/// @file ActionInitialization.cc
/// @brief Define action initialization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: Analysis.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file Analysis.cc
/// @brief Define histograms
@@ -114,10 +113,10 @@ Analysis::Save(const G4String& fname)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Close()
Analysis::Close(G4bool reset)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->CloseFile();
mgr->CloseFile(reset);
return;
}
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: DetectorConstruction.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: EventAction.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file EventAction.cc
/// @brief Describe event actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: MedicalBeam.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunAction.cc 82310 2014-06-14 00:27:39Z adotti $
//
/// @file RunAction.cc
/// @brief Describe run actions
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: RunActionMaster.cc 82310 2014-06-14 00:27:39Z adotti $
//
/// @file RunActionMaster.cc
/// @brief Describe run actions
@@ -175,6 +174,7 @@ RunActionMaster::EndOfRunAction(const G4Run* arun)
G4String fname("dose-rank0");
Analysis* myana = Analysis::GetAnalysis();
myana-> Save(fname);
myana-> Close(false); // close file withour resetting data
}
//Merge of g4analysis objects
ver=0;
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelParam.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: VoxelSD.cc 76431 2013-11-10 20:28:49Z kmura $
//
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
@@ -0,0 +1,58 @@
/// @file "MPI/examples/exMPI04/.README.txt"
/// @brief Example exMPI04 README
/*! \page exMPI04 Example : exMPI04
Description
===========
An example of dosimetry in a water phantom.
The example is as exMPI03, but adds output in G4analysis ntuple
and demonstrates ntuple merging.
In difference from merging other data (G4Run, scorers, hitograms),
the ntuple data are not sent to the collecting rank(s) at the
end of run but during event processing. That's why (an) extra rank(s)
have to be reserved for this purpose. The number of extra workers requested
is set in G4MPImanager constructor in main(). While G4MPImanager
can be created with any number of extra workers (< total number),
the ntuple merging is at present supported only for one.
The extra worker is connected to the run action class via G4MPIextraWorker
object which is set to G4MPImanager in main().
The standard calls to G4AnalysisManager (creating ntuple, open, write and
close file) trigger creating all necessary analysis tools object
for merging ntuple data on flight.
MPI ntuple merging can be activated in sequential mode only;
this activation is perfomed by creating the G4MPIntupleMerger
object in the RunActionMaster constructor.
The merger must be created before creating G4AnalysisManager
(= the first call to G4AnalysisManager::Instance())
and deleted only at the end of program.
If multithreading mode is enabled, the ntuples are merged from
threads to files per ranks.
Combined MT + MPI merging is not yet supported.
Merging ntuples is actually supported only with Root output format.
How to build
============
Use CMake on Geant4 library installed with CMake build.
This example requires G4mpi library to be installed
(see examples/extended/parallel/MPI/source/REDME.md)
Follow these commands,
> mkdir build
> cd build
> cmake -DG4mpi_DIR=<where-G4mpi-wasintalled>/lib[64]/G4mpi -DCMAKE_CXX_COMPILER=mpicxx \
-DGeant4_DIR=<your Geant4 install path>/lib[64]/Geant4-V.m.n <path-to-source>
(V.m.n is the version of Geant4, eg. Geant4-9.6.0)
> make
> make install
Replace mpicxx with your MPI-compiler wrapper.
*/
@@ -0,0 +1,72 @@
# - CmakeLists.txt for building an application
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(exMPI04)
#------------------------------------------------------------------------------
# check MPI package...
#find_package(MPI REQUIRED)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
# to build a batch mode only executable
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
find_package(G4mpi REQUIRED)
#----------------------------------------------------------------------------
# Setup Geant4 include directories and compile definitions
#
include(${Geant4_USE_FILE})
#------------------------------------------------------------------------------
add_definitions(-DTOOLS_USE_NATIVE_MPI)
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include
${Geant4_INCLUDE_DIR}
${G4mpi_INCLUDE_DIR})
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(exMPI04 exMPI04.cc ${sources} ${headers})
target_link_libraries(exMPI04 ${G4mpi_LIBRARIES} ${Geant4_LIBRARIES})
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build exMPI04. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(exMPI04_SCRIPTS
run.mac
v.mac
)
foreach(_script ${exMPI04_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS exMPI04 DESTINATION bin)
@@ -0,0 +1,53 @@
MPI/Examples : exMPI04
======================
Description
-----------
An example of dosimetry in a water phantom.
The example is as exMPI03, but adds output in G4analysis ntuple
and demonstrates ntuple merging.
In difference from merging other data (G4Run, scorers, hitograms),
the ntuple data are not sent to the collecting rank(s) at the
end of run but during event processing. That's why (an) extra rank(s)
have to be reserved for this purpose. The number of extra workers requested
is set in G4MPImanager constructor in main(). While G4MPImanager
can be created with any number of extra workers (< total number),
the ntuple merging is at present supported only for one.
The extra worker is connected to the run action class via G4MPIextraWorker
object which is set to G4MPImanager in main().
The standard calls to G4AnalysisManager (creating ntuple, open, write and
close file) trigger creating all necessary analysis tools object
for merging ntuple data on flight.
MPI ntuple merging can be activated in sequential mode only;
this activation is perfomed by creating the G4MPIntupleMerger
object in the RunActionMaster constructor.
The merger must be created before creating G4AnalysisManager
(= the first call to G4AnalysisManager::Instance())
and deleted only at the end of program.
If multithreading mode is enabled, the ntuples are merged from
threads to files per ranks.
Combined MT + MPI merging is not yet supported.
Merging ntuples is actually supported only with Root output format.
How to build
------------
Use CMake on Geant4 library installed with CMake build.
This example requires G4mpi library to be installed
(see examples/extended/parallel/MPI/source/REDME.md)
Follow these commands,
> mkdir build
> cd build
> cmake -DG4mpi_DIR=<where-G4mpi-wasintalled>/lib[64]/G4mpi -DCMAKE_CXX_COMPILER=mpicxx \
-DGeant4_DIR=<your Geant4 install path>/lib[64]/Geant4-V.m.n <path-to-source>
(V.m.n is the version of Geant4, eg. Geant4-9.6.0)
> make
> make install
Replace mpicxx with your MPI-compiler wrapper.
@@ -0,0 +1,133 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
/// @file exMPI04.cc
//
/// @brief A MPI example code
#include "G4MPImanager.hh"
#include "G4MPIsession.hh"
#include "G4MPIextraWorker.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4UserRunAction.hh"
#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif
#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
#include "RunActionMaster.hh"
#include "FTFP_BERT.hh"
#include "G4ScoringManager.hh"
#include "globals.hh"
int main(int argc, char** argv)
{
// --------------------------------------------------------------------
// Application options
// --------------------------------------------------------------------
bool useNtuple = true;
bool mergeNtuple = true;
// --------------------------------------------------------------------
// MPI session
// --------------------------------------------------------------------
// At first, G4MPImanager/G4MPIsession should be created.
G4int nofExtraWorkers = 0;
#ifndef G4MULTITHREADED
if ( mergeNtuple ) nofExtraWorkers = 1;
#endif
G4MPImanager* g4MPI = new G4MPImanager(argc, argv, nofExtraWorkers);
g4MPI->SetVerbose(1);
// MPI session (G4MPIsession) instead of G4UIterminal
// Terminal availability depends on your MPI implementation.
G4MPIsession* session = g4MPI-> GetMPIsession();
// LAM/MPI users can use G4tcsh.
G4String prompt = "";
prompt += "G4MPI";
prompt += "(%s)[%/]:";
session-> SetPrompt(prompt);
// --------------------------------------------------------------------
// user application setting
// --------------------------------------------------------------------
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager();
runManager-> SetNumberOfThreads(4);
#else
G4RunManager* runManager = new G4RunManager();
#endif
G4ScoringManager * scManager = G4ScoringManager::GetScoringManager();
scManager->SetVerboseLevel(1);
// setup your application
runManager-> SetUserInitialization(new DetectorConstruction);
runManager-> SetUserInitialization(new FTFP_BERT);
runManager-> SetUserInitialization(
new ActionInitialization(useNtuple, mergeNtuple));
runManager-> Initialize();
// extra worker (for collecting ntuple data)
if ( g4MPI->IsExtraWorker() ) {
G4cout << "Set extra worker" << G4endl;
G4UserRunAction* runAction
= const_cast<G4UserRunAction*>(runManager->GetUserRunAction());
g4MPI->SetExtraWorker(new G4MPIextraWorker(runAction));
}
#ifdef G4VIS_USE
G4VisExecutive* visManager = new G4VisExecutive;
visManager-> Initialize();
G4cout << G4endl;
#endif
// --------------------------------------------------------------------
// ready for go
// MPIsession treats both interactive and batch modes.
// Just start your session as below.
// --------------------------------------------------------------------
session-> SessionStart();
// --------------------------------------------------------------------
// termination
// --------------------------------------------------------------------
#ifdef G4VIS_USE
delete visManager;
#endif
delete g4MPI;
delete runManager;
return EXIT_SUCCESS;
}
@@ -0,0 +1,48 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file ActionInitialization.hh
/// @brief Define action initialization
#ifndef ACTION_INITIALIZATION_H
#define ACTION_INITIALIZATION_H
#include "G4VUserActionInitialization.hh"
#include "globals.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization(G4bool useNtuple, G4bool mergeNtuple);
~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
private:
G4bool fUseNtuple;
G4bool fMergeNtuple;
};
#endif
@@ -0,0 +1,95 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file Analysis.hh
/// @brief Define histograms
#ifndef ANALYSIS_MANAGER_H
#define ANALYSIS_MANAGER_H
#include "G4ThreeVector.hh"
#include <tools/histo/h1d>
#include <tools/histo/h2d>
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
class Analysis {
public:
~Analysis();
static Analysis* GetAnalysis();
void Book();
void EndOfRun();
void OpenFile(const G4String& fname);
void Save();
void Close(G4bool reset = true);
void FillIncident(const G4ThreeVector& p);
void FillDose(const G4ThreeVector& p, G4double dedx);
void ClearIncidentFlag();
void SetUseNtuple(G4bool useNtuple) {
G4cout << "Set useNtuple: " << useNtuple << G4endl;
fUseNtuple = useNtuple;
}
void SetMergeNtuple(G4bool mergeNtuple) {
G4cout << "Set mergeNtuple: " << mergeNtuple << G4endl;
fMergeNtuple = mergeNtuple;
}
private:
Analysis();
DISALLOW_COPY_AND_ASSIGN(Analysis);
G4bool fUseNtuple;
G4bool fMergeNtuple;
//Histograms handlers
G4int fincident_x_hist;
G4int fincident_map;
G4int fdose_hist;
G4int fdose_map;
G4int fdose_prof;
G4int fdose_map_prof;
G4int fdose_map3d;
static G4ThreadLocal G4int fincidentFlag;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void Analysis::ClearIncidentFlag()
{
fincidentFlag = false;
}
#endif
@@ -0,0 +1,50 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
#ifndef DETECTOR_CONSTRUCTION_H
#define DETECTOR_CONSTRUCTION_H
#include "G4VUserDetectorConstruction.hh"
class G4LogicalVolume;
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
~DetectorConstruction();
virtual G4VPhysicalVolume* Construct();
virtual void ConstructSDandField();
private:
G4LogicalVolume* flv_voxel;
};
#endif
@@ -0,0 +1,44 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file EventAction.hh
/// @brief Describe event actions
#ifndef EVENT_ACTION_H
#define EVENT_ACTION_H
#include "G4UserEventAction.hh"
class EventAction : public G4UserEventAction {
public:
EventAction();
~EventAction();
virtual void BeginOfEventAction(const G4Event* aevent);
virtual void EndOfEventAction(const G4Event* aevent);
};
#endif
@@ -0,0 +1,164 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file MedicalBeam.hh
/// @brief Define beam profile as primary generator
#ifndef MEDICAL_BEAM_H
#define MEDICAL_BEAM_H
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
class G4ParticleDefinition;
class MedicalBeam : public G4VUserPrimaryGeneratorAction {
public:
enum FieldShape{ kSQUARE=0, kCIRCLE };
MedicalBeam();
~MedicalBeam();
// set/get functions...
void SetParticleDefinition(G4ParticleDefinition* pd);
const G4ParticleDefinition* GetParticleDefinition() const;
void SetKineticE(G4double e);
G4double GetKineticE() const;
void SetSourcePosition(const G4ThreeVector& pos);
G4ThreeVector GetSourcePosition() const;
void SetFieldShape(FieldShape shape);
FieldShape GetFieldShape() const;
void SetSSD(G4double ssd);
G4double GetSSD() const;
void SetFieldXY(G4double fx, G4double fy);
G4double GetFieldX() const;
G4double GetFieldY() const;
void SetFieldR(G4double r);
G4double GetFieldR() const;
// methods...
virtual void GeneratePrimaries(G4Event* anEvent);
private:
// local methods...
G4ThreeVector GenerateBeamDirection() const;
G4ParticleDefinition* fparticle;
G4double fkineticE;
G4ThreeVector fsourcePosition;
G4double fSSD; // (SSD= Source Skin Depth)
FieldShape ffieldShape;
G4double ffieldXY[2];
G4double ffieldR;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void MedicalBeam::SetParticleDefinition(G4ParticleDefinition* pd)
{
fparticle = pd;
}
inline const G4ParticleDefinition* MedicalBeam::GetParticleDefinition() const
{
return fparticle;
}
inline void MedicalBeam::SetKineticE(G4double e)
{
fkineticE = e;
}
inline G4double MedicalBeam::GetKineticE() const
{
return fkineticE;
}
inline void MedicalBeam::SetSourcePosition(const G4ThreeVector& pos)
{
fsourcePosition = pos;
}
inline G4ThreeVector MedicalBeam::GetSourcePosition() const
{
return fsourcePosition;
}
inline void MedicalBeam::SetFieldShape(MedicalBeam::FieldShape shape)
{
ffieldShape = shape;
}
inline MedicalBeam::FieldShape MedicalBeam::GetFieldShape() const
{
return ffieldShape;
}
inline void MedicalBeam::SetSSD(G4double ssd)
{
fSSD = ssd;
}
inline G4double MedicalBeam::GetSSD() const
{
return fSSD;
}
inline void MedicalBeam::SetFieldXY(G4double fx, G4double fy)
{
ffieldXY[0] = fx;
ffieldXY[1] = fy;
}
inline G4double MedicalBeam::GetFieldX() const
{
return ffieldXY[0];
}
inline G4double MedicalBeam::GetFieldY() const
{
return ffieldXY[1];
}
inline void MedicalBeam::SetFieldR(G4double r)
{
ffieldR = r;
}
inline G4double MedicalBeam::GetFieldR() const
{
return ffieldR;
}
#endif
@@ -0,0 +1,44 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef RUN_HH
#define RUN_HH
#include <G4Run.hh>
//Dummy class to show how to use MPI merging of
//user defined G4Run. The dummycounter it's a unique number among threads.
//Merge actually sums the dummyCounter so for the global run that is Sum(i, 0<i<Nt)
class Run : public G4Run {
friend class RunMerger;
public:
Run();
virtual ~Run() {}
void Merge(const G4Run*);
G4int GetCounter() const { return fDummyCounter; }
private:
G4int fDummyCounter;
};
#endif //RUN_HH
@@ -0,0 +1,45 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file RunAction.hh
/// @brief Describe run actions
#ifndef RUN_ACTION_H
#define RUN_ACTION_H
#include "G4UserRunAction.hh"
class RunAction : public G4UserRunAction {
public:
RunAction(G4bool useNtuple, G4bool mergeNtuple);
~RunAction();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
};
#endif
@@ -0,0 +1,50 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file RunActionMaster.hh
/// @brief Describe run actions
#ifndef RUN_ACTIONMASTER_H
#define RUN_ACTIONMASTER_H
#include "G4UserRunAction.hh"
class G4MPIntupleMerger;
class RunActionMaster : public G4UserRunAction {
public:
RunActionMaster(G4bool useNtuple, G4bool mergeNtuple);
~RunActionMaster();
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run* arun);
virtual void EndOfRunAction(const G4Run* arun);
private:
G4MPIntupleMerger* fMPIntupleMerger;
};
#endif
@@ -0,0 +1,44 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef MPIRUNMERGER_HH
#define MPIRUNMERGER_HH
#include <G4VUserMPIrunMerger.hh>
#include "Run.hh"
//Simple class showing how to reduce via MPI user defined run
class RunMerger : public G4VUserMPIrunMerger {
public:
RunMerger(const Run* arun,G4int destination=G4MPImanager::kRANK_MASTER,
G4int verb=0)
: G4VUserMPIrunMerger(arun,destination,verb ) , fMyRun(arun) {}
protected:
void Pack();
G4Run* UnPack();
private:
const Run* fMyRun;
};
#endif
@@ -0,0 +1,85 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file VoxelParam.hh
/// @brief Define voxel parameterization
#ifndef VOXEL_PARAM_H
#define VOXEL_PARAM_H
#include "G4VPVParameterisation.hh"
class VoxelParam : public G4VPVParameterisation {
public:
VoxelParam();
~VoxelParam();
virtual void ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions(G4Box& box, const G4int id,
const G4VPhysicalVolume* vol) const;
virtual void ComputeDimensions
(G4Trd&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Trap&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Cons&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Sphere&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Orb&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Ellipsoid&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Torus&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Para&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Hype&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Tubs&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polycone&,const G4int,const G4VPhysicalVolume*) const {}
virtual void ComputeDimensions
(G4Polyhedra&,const G4int,const G4VPhysicalVolume*) const {}
};
#endif
@@ -0,0 +1,46 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file VoxelSD.hh
/// @brief Define detector sensitivity on voxels
#ifndef VOXEL_SD_H
#define VOXEL_SD_H
#include "G4VSensitiveDetector.hh"
class VoxelSD : public G4VSensitiveDetector {
public:
VoxelSD(const G4String& name);
~VoxelSD();
// virtual methods
virtual G4bool ProcessHits(G4Step* astep, G4TouchableHistory* rohist);
virtual void Initialize(G4HCofThisEvent* HCTE);
virtual void EndOfEvent(G4HCofThisEvent* HCTE);
};
#endif
@@ -0,0 +1,16 @@
/score/create/boxMesh boxMesh
#
/score/mesh/boxSize 100. 100. 100. cm
/score/mesh/nBin 2 2 2
#
/score/quantity/energyDeposit eDep
/score/quantity/nOfStep nOfStep
/score/close
/score/list
/run/printProgress 1000
/run/beamOn 4000
/mpi/status
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file ActionInitialization.cc
/// @brief Define action initialization
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "MedicalBeam.hh"
#include "RunAction.hh"
#include "RunActionMaster.hh"
#include "G4Threading.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization(G4bool useNtuple, G4bool mergeNtuple)
: G4VUserActionInitialization(),
fUseNtuple(useNtuple),
fMergeNtuple(mergeNtuple)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
{
SetUserAction(new RunActionMaster(fUseNtuple, fMergeNtuple));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const
{
G4cout << "ActionInitialization::Build()" << G4endl;
SetUserAction(new MedicalBeam);
SetUserAction(new EventAction);
if ( G4Threading::IsMultithreadedApplication() )
SetUserAction(new RunAction(fUseNtuple, fMergeNtuple));
else
SetUserAction(new RunActionMaster(fUseNtuple, fMergeNtuple));//Use master version for sequential
}
@@ -0,0 +1,173 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file Analysis.cc
/// @brief Define histograms and ntuples
#include "G4AutoDelete.hh"
#include "G4SystemOfUnits.hh"
#include "Analysis.hh"
//Select format of output here
//Note: ntuple merging is supported only with Root format
#include "g4root.hh"
#include "G4RootAnalysisManager.hh"
G4ThreadLocal G4int Analysis::fincidentFlag = false;
G4ThreadLocal Analysis* the_analysis = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis*
Analysis::GetAnalysis()
{
if (!the_analysis)
{
the_analysis = new Analysis();
G4AutoDelete::Register(the_analysis);
}
return the_analysis;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::Analysis() :
fUseNtuple(true),
fMergeNtuple(true),
fincident_x_hist(0), fincident_map(0), fdose_hist(0), fdose_map(0),
fdose_prof(0), fdose_map_prof(0), fdose_map3d(0)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Book()
{
G4cout << "Analysis::Book start, fUseNtuple: " << fUseNtuple << G4endl;
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->SetVerboseLevel(1);
#ifdef G4MULTITHREADED
// MT ntuple merging
mgr->SetNtupleMerging(fMergeNtuple);
#endif
fincident_x_hist = mgr->CreateH1("incident_x", "Incident X", 100, -5 * cm,
5 * cm, "cm");
fincident_map = mgr->CreateH2("incident_map", "Incident Map", 50, -5 * cm,
5 * cm, 50, -5 * cm, 5 * cm, "cm", "cm");
fdose_hist
= mgr->CreateH1("dose", "Dose distribution", 500, 0, 50 * cm, "cm");
fdose_map = mgr->CreateH2("dose_map", "Dose distribution", 500, 0, 50 * cm,
200, -10 * cm, 10 * cm, "cm", "cm");
fdose_map3d = mgr->CreateH3("dose_map_3d", "Dose distribution", 30, 0,
50 * cm, 20, -10 * cm, 10 * cm, 20, -10 * cm, 10 * cm, "cm", "cm", "cm");
fdose_prof = mgr->CreateP1("dose_prof", "Dose distribution", 300, 0, 30 * cm,
0, 100 * MeV, "cm", "MeV");
fdose_map_prof = mgr->CreateP2("dose_map_prof", "Dose distribution", 300, 0,
30 * cm, 80, -4 * cm, 4 * cm, 0, 100 * MeV, "cm", "cm", "MeV");
if ( fUseNtuple) {
mgr->CreateNtuple("Dose", "Dose distribution"); // ntuple Id = 0
mgr->CreateNtupleDColumn("pz");
mgr->CreateNtupleDColumn("px");
mgr->CreateNtupleDColumn("dose");
mgr->FinishNtuple();
}
G4cout << "Analysis::Book finished " << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Analysis::~Analysis()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::OpenFile(const G4String& fname)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->OpenFile(fname.c_str());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Save()
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->Write();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::Close(G4bool reset)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->CloseFile(reset);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillIncident(const G4ThreeVector& p)
{
if (!fincidentFlag)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
mgr->FillH2(fincident_map, p.x(), p.y());
mgr->FillH1(fincident_x_hist, p.x());
fincidentFlag = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
Analysis::FillDose(const G4ThreeVector& p, G4double dedx)
{
const G4double dxy = 10. * mm;
if (std::abs(p.y()) < dxy)
{
G4AnalysisManager* mgr = G4AnalysisManager::Instance();
const G4double Z0 = 25. * cm;
mgr->FillH2(fdose_map, p.z() + Z0, p.x(), dedx / GeV);
mgr->FillP2(fdose_map_prof, p.z() + Z0, p.x(), dedx);
mgr->FillH3(fdose_map3d, p.z() + Z0, p.x(), p.y(), dedx / GeV);
if (std::abs(p.x()) < dxy)
{
mgr->FillH1(fdose_hist, p.z() + Z0, dedx / GeV);
mgr->FillP1(fdose_prof, p.z() + Z0, dedx);
}
if ( fUseNtuple ) {
// the same fill frequency as H2 "dose_map"
mgr->FillNtupleDColumn(0, p.z() + Z0);
mgr->FillNtupleDColumn(1, p.x());
mgr->FillNtupleDColumn(2, dedx / GeV);
mgr->AddNtupleRow();
}
}
}
@@ -0,0 +1,128 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file DetectorConstruction.hh
/// @brief Define geometry
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4NistManager.hh"
#include "G4PVParameterised.hh"
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisAttributes.hh"
#include "DetectorConstruction.hh"
#include "VoxelParam.hh"
#include "VoxelSD.hh"
typedef G4LogicalVolume G4LV;
typedef G4PVPlacement G4PVP;
typedef G4VisAttributes G4VA;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: flv_voxel(NULL)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
{
G4NistManager* nistManager = G4NistManager::Instance();
G4VisAttributes* va;
// world volume
const G4double DXYZ_WORLD = 200.*cm;
G4Box* sld_world = new G4Box("world",
DXYZ_WORLD/2., DXYZ_WORLD/2., DXYZ_WORLD/2.);
G4Material* vacuum = nistManager-> FindOrBuildMaterial("G4_Galactic");
G4LV* lv_world = new G4LogicalVolume(sld_world, vacuum, "world");
G4PVP* world = new G4PVPlacement(0, G4ThreeVector(), "AREA",
lv_world, 0, false, 0);
// vis. attributes
va = new G4VA(G4Color(1.,1.,1.));
va-> SetVisibility(false);
lv_world-> SetVisAttributes(va);
// water phantom
const G4double DXY_PHANTOM = 20.*cm;
const G4double DZ_PHANTOM = 50.*cm;
G4Box* sld_phantom = new G4Box("phantom",
DXY_PHANTOM/2., DXY_PHANTOM/2., DZ_PHANTOM/2.);
G4Material* water = nistManager-> FindOrBuildMaterial("G4_WATER");
G4LV* lv_phantom = new G4LogicalVolume(sld_phantom,
water, "phantom");
va = new G4VA(G4Color(0.,1.,1.));
lv_phantom-> SetVisAttributes(va);
new G4PVP(0, G4ThreeVector(), lv_phantom, "phantom", lv_world, false, 0);
// voxel planes
const G4double DXY_VXP = 20.*cm;
const G4double DZ_VXP = 1.*mm;
G4Box* sld_vxp = new G4Box("vxplane", DXY_VXP/2., DXY_VXP/2., DZ_VXP/2.);
G4LV* lv_vxp = new G4LV(sld_vxp, water, "vxplane");
va = new G4VA(G4Color(1.,0.,0.));
va-> SetVisibility(false);
lv_vxp-> SetVisAttributes(va);
for (G4int iz =0; iz < 500; iz++) {
G4double z0 = -DZ_PHANTOM/2. + (iz+0.5)*DZ_VXP;
new G4PVP(0, G4ThreeVector(0.,0.,z0),
lv_vxp, "vxplane", lv_phantom, false, 1000+iz);
}
// voxel parameterized
G4Box* sld_voxel = new G4Box("voxel",1.,1.,1.); // dummy
flv_voxel = new G4LV(sld_voxel, water, "voxel");
va = new G4VA(G4Color(0.,1.,1.));
va-> SetVisibility(false);
flv_voxel-> SetVisAttributes(va);
const G4int nvoxels = 100*100;
new G4PVParameterised("voxle", flv_voxel, lv_vxp, kUndefined, nvoxels,
new VoxelParam());
return world;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField()
{
flv_voxel-> SetSensitiveDetector(new VoxelSD("voxel"));
}
@@ -0,0 +1,54 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file EventAction.cc
/// @brief Describe event actions
#include "G4Event.hh"
#include "Analysis.hh"
#include "EventAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event*)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> ClearIncidentFlag();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event*)
{
}
@@ -0,0 +1,119 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file MedicalBeam.cc
/// @brief Define beam profile as primary generator
#include <cmath>
#include "G4Event.hh"
#include "G4ParticleTable.hh"
#include "G4PrimaryVertex.hh"
#include "Randomize.hh"
#include "MedicalBeam.hh"
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::MedicalBeam()
: fparticle(0), fkineticE(1.*MeV), fsourcePosition(G4ThreeVector()),
fSSD(1.*m), ffieldShape(MedicalBeam::kSQUARE), ffieldR(10.*cm)
{
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
fparticle = particleTable-> FindParticle("proton");
fkineticE = 200.*MeV;
fsourcePosition = G4ThreeVector(0.,0.,-125.*cm);
fSSD = 100.*cm;
ffieldXY[0] = ffieldXY[1] = 5.*cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
MedicalBeam::~MedicalBeam()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ThreeVector MedicalBeam::GenerateBeamDirection() const
{
// uniform distribution in a limitted solid angle
G4double dr;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
dr = std::sqrt(sqr(ffieldXY[0]/2.) + sqr(ffieldXY[1]/2.));
} else {
dr = ffieldR;
}
G4double sin0 = dr/fSSD;
G4double cos0 = std::sqrt(1.-sqr(sin0));
G4double dcos = 0.;
G4double dsin, dphi, z;
G4double x = DBL_MAX;
G4double y = DBL_MAX;
G4double xmax, ymax;
if ( ffieldShape == MedicalBeam::kSQUARE ) {
xmax = ffieldXY[0]/2./fSSD;
ymax = ffieldXY[1]/2./fSSD;
} else {
xmax = ymax = DBL_MAX-1.;
}
while(! (std::abs(x) < xmax && std::abs(y) < ymax) ) {
dcos = G4RandFlat::shoot(cos0, 1.);
dsin = std::sqrt(1.-sqr(dcos));
dphi = G4RandFlat::shoot(0., twopi);
x = std::cos(dphi)*dsin*dcos;
y = std::sin(dphi)*dsin*dcos;
}
z = dcos;
return G4ThreeVector(x,y,z);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void MedicalBeam::GeneratePrimaries(G4Event* anEvent)
{
if ( fparticle == NULL ) return;
// create a new vertex
G4PrimaryVertex* vertex = new G4PrimaryVertex(fsourcePosition, 0.*ns);
// momentum
G4double mass = fparticle-> GetPDGMass();
G4double p = std::sqrt(sqr(mass+fkineticE)-sqr(mass));
G4ThreeVector pmon = p*GenerateBeamDirection();
G4PrimaryParticle* primary =
new G4PrimaryParticle(fparticle, pmon.x(), pmon.y(), pmon.z());
// set primary to vertex
vertex-> SetPrimary(primary);
// set vertex to event
anEvent-> AddPrimaryVertex(vertex);
}
@@ -0,0 +1,43 @@
//
// ********************************************************************
// * 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 "Run.hh"
#include <atomic>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
namespace {
std::atomic_int g_ctr(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run() {
fDummyCounter = g_ctr++;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge(const G4Run* other ) {
G4Run::Merge(other);
fDummyCounter += static_cast<const Run*>(other)->fDummyCounter;
}
@@ -0,0 +1,87 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file RunAction.cc
/// @brief Describe run actions
#include <G4VUserMPIrunMerger.hh>
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunAction.hh"
#include "Run.hh"
#include "G4MPIscorerMerger.hh"
#include "tools/mpi/wrmpi"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(G4bool useNtuple, G4bool mergeNtuple)
: G4UserRunAction()
{
// Book analysis in ctor
Analysis* myana = Analysis::GetAnalysis();
myana->SetUseNtuple(useNtuple);
myana->SetMergeNtuple(mergeNtuple);
G4cout<<"Book analysis on rank: " << G4MPImanager::GetManager()-> GetRank() << G4endl;;
myana->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run*)
{
G4cout << "RunAction::BeginOfRunAction" << G4endl;
Analysis* myana = Analysis::GetAnalysis();
// ntuples will be written on each rank
G4int rank = G4MPImanager::GetManager()->GetRank();
std::ostringstream fname;
fname<<"dose-rank"<<rank;
myana->OpenFile(fname.str());
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run*)
{
G4cout << "RunAction::EndOfRunAction" << G4endl;
Analysis* myana = Analysis::GetAnalysis();
myana-> Save();
}
@@ -0,0 +1,241 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file RunActionMaster.cc
/// @brief Describe run actions
#include "G4MPImanager.hh"
#include <stdio.h>
#include "G4Threading.hh"
#include "Analysis.hh"
#include "RunActionMaster.hh"
#include "g4root.hh" //ROOT Format for output
#include "RunMerger.hh"
#include "G4MPIscorerMerger.hh"
#include "G4MPIhistoMerger.hh"
#include "G4MPIntupleMerger.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunActionMaster::RunActionMaster(G4bool useNtuple, G4bool mergeNtuple)
: G4UserRunAction(),
fMPIntupleMerger(nullptr)
{
#ifndef G4MULTITHREADED
if ( mergeNtuple &&
G4MPImanager::GetManager()->GetTotalSize() >= 2 ) {
// Activate MPI ntuple merging
// The merger must be created before creating G4AnalysisManager:
// (= the first call to G4AnalysisManager::Instance())
// and deleted only at the end of program
G4int nofReducedNtupleFiles = 0;
// Multiple reduced ntuple files are not yet supported
G4bool rowWise = true;
fMPIntupleMerger = new G4MPIntupleMerger(nofReducedNtupleFiles, rowWise);
}
#endif
// Book analysis in ctor
Analysis* myana = Analysis::GetAnalysis();
myana->SetUseNtuple(useNtuple);
myana->SetMergeNtuple(mergeNtuple);
myana->Book();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunActionMaster::GenerateRun()
{
return new Run;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunActionMaster::~RunActionMaster()
{
delete fMPIntupleMerger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::BeginOfRunAction(const G4Run*)
{
G4cout << "RunActionMaster::BeginOfRunAction" << G4endl;
Analysis* myana = Analysis::GetAnalysis();
G4int rank = G4MPImanager::GetManager()->GetRank();
std::ostringstream fname;
fname<<"dose-rank"<<rank;
myana->OpenFile(fname.str());
// OpenFile triggeres creating collecting/sending ntuples objects;
// must be called at BeginOfRunAction
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
RunActionMaster::EndOfRunAction(const G4Run* arun)
{
G4cout << "RunActionMaster::EndOfRunAction" << G4endl;
//This is executed by master thread only. Worker threads have already
//merged their results into this master threads.
//We are going to merge the results via MPI for:
// 1. User-defined "Run" object
// 2. Command line scorers, if exists
// 3. G4Analysis objects
// For debugging purposes in the following we write out results twice:
// BEFORE and AFTER the merging, so that rank 0 actually
// writes two files, the one called "*rank000*" will contain the partial
// results only from rank #0,
// the file *merged* contains the reduction from all ranks.
// It should be very easy to adapt this code
const G4int rank = G4MPImanager::GetManager()-> GetRank();
G4cout << "=====================================================" << G4endl;
G4cout << "Start EndOfRunAction for master thread in rank: " << rank<<G4endl;
G4cout << "=====================================================" << G4endl;
if ( ! G4MPImanager::GetManager()->IsExtraWorker() ) {
G4cout << "Go to merge on processing workers" << G4endl;
//Merging of G4Run object:
//All ranks > 0 merge to rank #0
RunMerger rm(static_cast<const Run*>(arun), G4MPImanager::kRANK_MASTER, 5);
G4int ver = 0 ; //Use 4 for lots of info
if ( rank == 0 && ver == 0) ver = 1;
if ( ver > 1 ) {
G4cout<<"Before merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()<<G4endl;
}
rm.SetVerbosity( ver );
rm.Merge();
if ( ver > 1 ) {
G4cout<<"After merge the Run object has test counter value: "
<<static_cast<const Run*>(arun)->GetCounter()
<<" (with 1 thread== number of ranks)"<<G4endl;
}
//Merge of scorers
ver = 0;
if (G4ScoringManager::GetScoringManagerIfExist()) {
const auto scor = G4ScoringManager::GetScoringManager();
G4MPIscorerMerger sm(scor);
sm.SetVerbosity(ver);
//Debug!
auto debugme = [&scor](){
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const MeshScoreMap& map = m->GetScoreMap();
std::for_each(map.begin(),map.end(),
[](const MeshScoreMap::value_type& e) {
G4cout<<e.first<<"("<<e.second<<"):"<<G4endl;
const auto data = e.second->GetMap();
for( auto it = data->begin() ; it != data->end() ; ++it ) {
G4cout<<it->first<<" => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): "
<<it->second->n()<<" "<<it->second->sum_w()<<" "
<<it->second->sum_w2()<<" "<<it->second->sum_wx()<<" "
<<it->second->sum_wx2()<<G4endl;
}
});
}
};
//Debug!
if ( ver > 4 ) {
G4cout<<"Before merging: Meshes dump"<<G4endl;
debugme();
}
//Write partial scorers from single ranks *before* merging
//Do not rely on UI command to write out scorers, because rank-specific
//files will have same file name: need to add rank # to file name
if ( true ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-rank"<<rank<<".csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
}
//Now reduce all scorers to rank #0
sm.Merge();
//Debug!
if ( ver > 4 ) {
G4cout<<"After merging: Meshes dump"<<G4endl;
debugme();
}
//For rank #0 write out the merged files
if ( rank == 0 ) {
for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
const auto m = scor->GetMesh(idx);
const auto& mn = m->GetWorldName();
std::ostringstream fname;
fname<<"scorer-"<<mn<<"-merged.csv";
scor->DumpAllQuantitiesToFile(mn,fname.str());
}
}
}
//Save histograms *before* MPI merging for rank #0
if (rank == 0)
{
Analysis* myana = Analysis::GetAnalysis();
myana-> Save();
myana-> Close(false); // close without resetting histograms
}
//Merge of g4analysis objects
G4cout << "Go to merge histograms " << G4endl;
ver=1;
G4MPIhistoMerger hm(G4AnalysisManager::Instance());
hm.SetVerbosity(ver);
hm.Merge();
G4cout << "Done merge histograms " << G4endl;
}
//Save g4analysis objects to a file
//NB: It is important that the save is done *after* MPI-merging of histograms
//One can save all ranks or just rank0, chane the if
if (true /*rank == 0*/)
// if (rank == 0)
{
Analysis* myana = Analysis::GetAnalysis();
if (rank == 0) {
myana->OpenFile("dose-merged");
}
myana-> Save();
myana-> Close();
}
G4cout << "===================================================" << G4endl;
G4cout << "End EndOfRunAction for master thread in rank: " << rank << G4endl;
G4cout << "===================================================" << G4endl;
}
@@ -0,0 +1,43 @@
//
// ********************************************************************
// * 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 "RunMerger.hh"
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunMerger::Pack() {
//Very imporant, here fMyRun is const!
//Register a user-data in the user Run class with MPI merger
InputUserData(const_cast<int*>(&(fMyRun->fDummyCounter)),MPI::INT,1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunMerger::UnPack() {
//Create a dummy user-Run, used to contain data received via MPI
Run* aDummyRun = new Run;
OutputUserData(&(aDummyRun->fDummyCounter),MPI::INT,1);
return aDummyRun;
}
@@ -0,0 +1,73 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file VoxelParam.cc
/// @brief Define voxel parameterization
#include "G4Box.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
#include "VoxelParam.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::VoxelParam()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelParam::~VoxelParam()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeTransformation(const G4int id,
G4VPhysicalVolume* vol) const
{
const G4int NX = 100;
G4int iy = id / NX;
G4int ix = id % NX;
const G4double dxyz = 1.*mm;
const G4double DXY = 10.*cm;
G4double x0 = -DXY/2. + ix*dxyz;
G4double y0 = -DXY/2. + iy*dxyz;
vol-> SetTranslation(G4ThreeVector(x0,y0,0.));
vol-> SetRotation(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelParam::ComputeDimensions(G4Box& box, const G4int,
const G4VPhysicalVolume*) const
{
const G4double dxyz = 0.5*mm;
box.SetXHalfLength(dxyz);
box.SetYHalfLength(dxyz);
box.SetZHalfLength(dxyz);
}
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
/// @file VoxelSD.cc
/// @brief Define detector sensitivity on voxels
//#include "G4MPImanager.hh"
#include "G4SDManager.hh"
#include "G4Step.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4VTouchable.hh"
#include "Randomize.hh"
#include "Analysis.hh"
#include "VoxelSD.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::VoxelSD(const G4String& name)
: G4VSensitiveDetector(name)
{
G4SDManager::GetSDMpointer()-> AddNewDetector(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
VoxelSD::~VoxelSD()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool VoxelSD::ProcessHits(G4Step* astep, G4TouchableHistory*)
{
G4ThreeVector x0 = astep-> GetPreStepPoint()-> GetPosition();
G4ThreeVector x1 = astep-> GetPostStepPoint()-> GetPosition();
G4int tid = astep-> GetTrack()-> GetTrackID();
G4int iz = astep-> GetPreStepPoint()-> GetTouchable()-> GetReplicaNumber(1);
Analysis* myana = Analysis::GetAnalysis();
// incident position
if ( tid == 1 && iz == 1000 ) { // scored @ first layer
myana-> FillIncident(x0);
}
// energy deposit
G4ThreeVector p = G4UniformRand()*(x1-x0) + x0; // position sampling
G4double edep = astep-> GetTotalEnergyDeposit();
myana-> FillDose(p, edep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::Initialize(G4HCofThisEvent*)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void VoxelSD::EndOfEvent(G4HCofThisEvent*)
{
}
@@ -0,0 +1,68 @@
# Use this open statement to create an OpenGL view:
/vis/open OGL 600x600-0+0
#
# Use this open statement to create a .prim file suitable for
# viewing in DAWN:
#/vis/open DAWNFILE
#
# Use this open statement to create a .heprep file suitable for
# viewing in HepRApp:
#/vis/open HepRepFile
#
# Use this open statement to create a .wrl file suitable for
# viewing in a VRML viewer:
#/vis/open VRML2FILE
#
# Disable auto refresh and quieten vis messages whilst scene and
# trajectories are established:
/vis/viewer/set/autoRefresh false
/vis/verbose errors
#
# Draw geometry:
/vis/drawVolume
#
# Specify view angle:
/vis/viewer/set/viewpointThetaPhi 90. 270.
#
# Specify zoom value:
#/vis/viewer/zoom 2.
#
# Specify style (surface or wireframe):
#/vis/viewer/set/style wireframe
#
# Draw coordinate axes:
#/vis/scene/add/axes 0 0 0 1 m
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/vis/scene/add/trajectories smooth
/vis/modeling/trajectories/create/drawByCharge
/vis/modeling/trajectories/drawByCharge-0/default/setDrawStepPts true
/vis/modeling/trajectories/drawByCharge-0/default/setStepPtsSize 2
# (if too many tracks cause core dump => /tracking/storeTrajectory 0)
#
# Draw hits at end of event:
#/vis/scene/add/hits
#
# To draw only gammas:
#/vis/filtering/trajectories/create/particleFilter
#/vis/filtering/trajectories/particleFilter-0/add gamma
#
# To invert the above, drawing all particles except gammas,
# keep the above two lines but also add:
#/vis/filtering/trajectories/particleFilter-0/invert true
#
# Many other options are available with /vis/modeling and /vis/filtering.
# For example, to select colour by particle ID:
#/vis/modeling/trajectories/create/drawByParticleID
#/vis/modeling/trajectories/drawByParticleID-0/set e- blue
#
# To superimpose all of the events from a given run:
/vis/scene/endOfEventAction accumulate
#
# Re-establish auto refreshing and verbosity:
/vis/viewer/set/autoRefresh true
/vis/verbose warnings
#
# For file-based drivers, use this to create an empty detector view:
#/vis/viewer/flush
@@ -64,12 +64,14 @@ endif()
#------------------------------------------------------------------------------
# Define library
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/analysis/include
${Geant4_INCLUDE_DIR}
${MPI_CXX_INCLUDE_PATH})
link_directories(${MPI_CXX_LIBRARY_DIRS})
set(_sources
src/G4MPIbatch.cc
src/G4MPIextraWorker.cc
src/G4MPImanager.cc
src/G4MPImessenger.cc
src/G4MPIrandomSeedGenerator.cc
@@ -80,8 +82,12 @@ set(_sources
src/G4VMPIsession.cc
src/G4MPIscorerMerger.cc
src/G4MPIhistoMerger.cc
src/G4MPIntupleMerger.cc
src/G4VUserMPIrunMerger.cc
src/G4MPIutils.cc
analysis/src/G4RootMpiAnalysisManager.cc
analysis/src/G4RootMpiNtupleManager.cc
analysis/src/G4RootMpiPNtupleManager.cc
)
#TODO: This works only if both BUILD_STATIC_LIBS=ON && BUILD_SHARED_LIBS=OFF
@@ -107,19 +113,27 @@ endif()
# headers
set(HEADERS
include/G4MPIbatch.hh
include/G4MPIextraWorker.hh
include/G4MPImanager.hh
include/G4MPImessenger.hh
include/G4MPIrandomSeedGenerator.hh
include/G4MPIsession.hh
include/G4MPIstatus.hh
include/G4UImpish.hh
include/G4VMPIextraWorker.hh
include/G4VMPIseedGenerator.hh
include/G4VMPIsession.hh
include/G4MPIscorerMerger.hh
include/G4MPIrunMerger.hh
include/G4MPIhistoMerger.hh
include/G4MPIntupleMerger.hh
include/G4VUserMPIrunMerger.hh
include/G4MPIutils.hh
analysis/include/G4RootMpiAnalysisManager.hh
analysis/include/G4RootMpiNtupleManager.hh
analysis/include/G4RootMpiPNtupleDescription.hh
analysis/include/G4RootMpiPNtupleManager.hh
)
#------------------------------------------------------------------------------
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The Root analysis manager extension for MPI
// This class is temporarily provided with g4mpi,
// it will be integrated in Geant4 analysis category in future.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4RootMpiAnalysisManager_h
#define G4RootMpiAnalysisManager_h 1
#include "G4RootAnalysisManager.hh"
enum class G4MpiNtupleMergeMode {
kNone,
kMain,
kSlave
};
class G4RootMpiPNtupleManager;
class G4RootMpiAnalysisManager : public G4RootAnalysisManager
{
public:
explicit G4RootMpiAnalysisManager(G4bool isMaster = true);
virtual ~G4RootMpiAnalysisManager();
// MPI
void SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
G4int nofReducedNtupleFiles = 0,
G4bool rowWise = false,
unsigned int basketSize = fgkDefaultBasketSize);
protected:
// virtual methods from base class
virtual G4bool OpenFileImpl(const G4String& fileName) final;
virtual G4bool CloseFileImpl(G4bool reset) final;
virtual G4bool WriteNtuple() final;
virtual G4bool Reset() final;
private:
// methods
void SetMpiNtupleMergingMode(G4int mpiRank, G4int mpiSize, G4int nofNtupleFiles);
void CreateMpiNtupleManagers(tools::impi* impi, G4int mpiRank, G4int mpiSize);
// data members
G4MpiNtupleMergeMode fMpiNtupleMergeMode;
G4RootMpiPNtupleManager* fMpiSlaveNtupleManager;
};
#endif
@@ -0,0 +1,69 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Extension of Root ntuple manager for MPI.
// The class handles ntuples on the collecting MPI ranks.
// This class is temporarily provided with g4mpi,
// it will be integrated in Geant4 analysis category in future.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4RootMpiNtupleManager_h
#define G4RootMpiNtupleManager_h 1
#include "G4RootNtupleManager.hh"
namespace tools {
class impi;
}
class G4RootMpiNtupleManager : public G4RootNtupleManager
{
friend class G4RootMpiAnalysisManager;
friend class G4RootMpiMainNtupleManager;
public:
G4RootMpiNtupleManager(const G4AnalysisManagerState& state, G4bool rowWise,
tools::impi* impi, G4int mpiSize);
virtual ~G4RootMpiNtupleManager();
virtual void CreateNtuplesFromBooking() final;
virtual G4bool Merge() final;
private:
// MPI
G4bool Send(G4int id, tools::wroot::ntuple* ntuple);
G4bool InitializeRanks();
G4bool WaitBuffer();
tools::impi* fImpi;
std::vector<G4int> fSlaveRanks;
G4int fMainRank;
};
#endif
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Structure containing the information related to Root MPI pntuple.
// This class is temporarily provided with g4mpi,
// it will be integrated in Geant4 analysis category in future.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4RootMpiPNtupleDescription_h
#define G4RootMpiPNtupleDescription_h 1
#include "globals.hh"
#include "tools/ntuple_booking"
#include "tools/impi"
#include "tools/wroot/impi_ntuple"
namespace tools {
namespace wroot {
class branch;
class base_pntuple;
}
}
struct G4RootMpiPNtupleDescription
{
G4RootMpiPNtupleDescription()
: fNtuple(nullptr),
fBasePNtuple(nullptr),
fMainBranches(),
fNtupleBooking(),
fMainNtupleRank(0),
fImpi(nullptr),
fActivation(true),
fIsNtupleOwner(true) {}
~G4RootMpiPNtupleDescription()
{
if ( fIsNtupleOwner ) delete fNtuple;
}
tools::wroot::impi_ntuple* fNtuple;
tools::wroot::base_pntuple* fBasePNtuple;
std::vector<tools::wroot::branch*> fMainBranches;
tools::ntuple_booking fNtupleBooking;
G4int fMainNtupleRank;
tools::impi* fImpi;
G4bool fActivation;
G4bool fIsNtupleOwner;
};
#endif
@@ -0,0 +1,323 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Class for Root MPI pntuple management.
// The class handles ntuples on the processing MPI ranks when MPI ntuple merging
// is activated.
// This class is temporarily provided with g4mpi,
// it will be integrated in Geant4 analysis category in future.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4RootMpiPNtupleManager_h
#define G4RootMpiPNtupleManager_h 1
#include "G4BaseNtupleManager.hh"
#include "G4RootMpiPNtupleDescription.hh"
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "globals.hh"
#include "tools/wroot/base_pntuple"
#include <vector>
class G4RootFileManager;
namespace tools {
namespace wroot {
class file;
class directory;
class impi_ntuple;
}
}
class G4RootMpiPNtupleManager : public G4BaseNtupleManager
{
friend class G4RootMpiAnalysisManager;
friend class G4RootAnalysisManager;
friend class G4RootNtupleManager;
public:
explicit G4RootMpiPNtupleManager(const G4AnalysisManagerState& state, G4bool rowWise,
tools::impi* impi, G4int mpiRank, G4int destinationRank);
~G4RootMpiPNtupleManager();
private:
enum class G4PNtupleCreateMode {
kSlaveBeforeOpen,
kSlaveAfterOpen,
kUndefined
};
// Functions specific to the output type
void SetNtupleDirectory(tools::wroot::directory* directory);
void SetFileManager(std::shared_ptr<G4RootFileManager> fileManager);
// Methods to manipulate ntuples
void CreateNtuple(G4RootMpiPNtupleDescription* ntupleDescription);
void CreateNtuplesFromBooking();
// Methods to create ntuples
//
virtual G4int CreateNtuple(const G4String& name, const G4String& title) final;
// Create columns in the ntuple with given id
virtual G4int CreateNtupleIColumn(G4int ntupleId,
const G4String& name, std::vector<int>* vector) final;
virtual G4int CreateNtupleFColumn(G4int ntupleId,
const G4String& name, std::vector<float>* vector) final;
virtual G4int CreateNtupleDColumn(G4int ntupleId,
const G4String& name, std::vector<double>* vector) final;
virtual G4int CreateNtupleSColumn(G4int ntupleId, const G4String& name) final;
virtual void FinishNtuple(G4int ntupleId) final;
// Methods to fill ntuples
// Methods for ntuple with id > FirstNtupleId (when more ntuples exist)
virtual G4bool FillNtupleIColumn(G4int ntupleId, G4int columnId, G4int value) final;
virtual G4bool FillNtupleFColumn(G4int ntupleId, G4int columnId, G4float value) final;
virtual G4bool FillNtupleDColumn(G4int ntupleId, G4int columnId, G4double value) final;
virtual G4bool FillNtupleSColumn(G4int ntupleId, G4int columnId,
const G4String& value) final;
virtual G4bool AddNtupleRow(G4int ntupleId) final;
virtual G4bool Merge() final;
// Reset
virtual G4bool Reset(G4bool deleteNtuple) final;
// Activation option
//
virtual void SetActivation(G4bool activation) final;
virtual void SetActivation(G4int ntupleId, G4bool activation) final;
virtual G4bool GetActivation(G4int ntupleId) const final;
virtual G4bool IsEmpty() const final;
// Access methods
virtual G4int GetNofNtuples() const final;
virtual G4int GetNofNtupleBookings() const final;
const std::vector<G4RootMpiPNtupleDescription*>& GetNtupleDescriptionVector() const;
unsigned int GetBasketSize() const;
private:
G4RootMpiPNtupleDescription*
GetNtupleDescriptionInFunction(G4int id, G4String function, G4bool warn = true) const;
tools::wroot::base_pntuple*
GetNtupleInFunction(G4int id, G4String function, G4bool warn = true) const;
template <typename T>
G4int CreateNtupleTColumn(G4int ntupleId,
const G4String& name, std::vector<T>* vector);
template <typename T>
G4int CreateNtupleTColumn(
const G4String& name, std::vector<T>* vector);
template <typename T>
G4bool FillNtupleTColumn(G4int ntupleId, G4int columnId, const T& value);
// Data members
// G4RootMpiMainNtupleManager* fMpiMainNtupleManager;
std::shared_ptr<G4RootFileManager> fFileManager;
tools::wroot::directory* fNtupleDirectory;
std::vector<G4RootMpiPNtupleDescription*> fNtupleDescriptionVector;
std::vector<tools::wroot::impi_ntuple*> fNtupleVector;
G4bool fRowWise;
tools::impi* fImpi;
G4int fMpiRank;
G4int fDestinationRank;
};
// inline functions
inline void
G4RootMpiPNtupleManager::SetNtupleDirectory(tools::wroot::directory* directory)
{ fNtupleDirectory = directory; }
inline void
G4RootMpiPNtupleManager::SetFileManager(std::shared_ptr<G4RootFileManager> fileManager)
{ fFileManager = fileManager; }
inline const std::vector<G4RootMpiPNtupleDescription*>&
G4RootMpiPNtupleManager::GetNtupleDescriptionVector() const
{ return fNtupleDescriptionVector; }
//_____________________________________________________________________________
template <typename T>
G4int G4RootMpiPNtupleManager::CreateNtupleTColumn(
G4int ntupleId, const G4String& name, std::vector<T>* vector)
{
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << name << " ntupleId " << ntupleId;
fState.GetVerboseL4()->Message("create", "pntuple T column", description);
}
#endif
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "CreateNtupleTColumn");
if ( ! ntupleDescription ) return G4Analysis::kInvalidId;
// Save column info in booking
auto& ntupleBooking = ntupleDescription->fNtupleBooking;
auto index = ntupleBooking.columns().size();
if ( ! vector )
ntupleBooking.template add_column<T>(name);
else
ntupleBooking.template add_column<T>(name, *vector);
fLockFirstNtupleColumnId = true;
#ifdef G4VERBOSE
if ( fState.GetVerboseL2() ) {
G4ExceptionDescription description;
description << name << " ntupleId " << ntupleId;
fState.GetVerboseL2()->Message("create", "pntuple T column", description);
}
#endif
return index + fFirstNtupleColumnId;
}
//_____________________________________________________________________________
template <>
inline G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(
G4int ntupleId, G4int columnId, const std::string& value)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
fState.GetVerboseL4()->Message("fill", "pntuple T column", description);
}
#endif
auto ntuple = GetNtupleInFunction(ntupleId, "FillNtupleTColumn");
if ( ! ntuple ) return false;
auto index = columnId - fFirstNtupleColumnId;
if ( index < 0 || index >= G4int(ntuple->columns().size()) ) {
G4ExceptionDescription description;
description << " " << "ntupleId " << ntupleId
<< " columnId " << columnId << " does not exist.";
G4Exception("G4RootNtupleManager::FillNtupleTColumn()",
"Analysis_W011", JustWarning, description);
return false;
}
auto icolumn = ntuple->columns()[index];
auto column = dynamic_cast<tools::wroot::base_pntuple::column_string* >(icolumn);
if ( ! column ) {
G4ExceptionDescription description;
description << " Column type does not match: "
<< " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
G4Exception("G4RootNtupleManager:FillNtupleColumn",
"Analysis_W011", JustWarning, description);
return false;
}
column->fill(value);
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
fState.GetVerboseL4()->Message("done fill", "pntuple T column", description);
}
#endif
return true;
}
//_____________________________________________________________________________
template <typename T>
G4bool G4RootMpiPNtupleManager::FillNtupleTColumn(
G4int ntupleId, G4int columnId, const T& value)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
G4cout << "Skipping FillNtupleIColumn for " << ntupleId << G4endl;
return false;
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
fState.GetVerboseL4()->Message("fill", "pntuple T column", description);
}
#endif
// get ntuple
auto ntuple = GetNtupleInFunction(ntupleId, "FillNtupleTColumn");
if ( ! ntuple ) return false;
// get generic column
auto index = columnId - fFirstNtupleColumnId;
if ( index < 0 || index >= G4int(ntuple->columns().size()) ) {
G4ExceptionDescription description;
description << " " << "ntupleId " << ntupleId
<< " columnId " << columnId << " does not exist.";
G4Exception("G4TNtupleManager::FillNtupleTColumn()",
"Analysis_W011", JustWarning, description);
return false;
}
auto icolumn = ntuple->columns()[index];
// get column and check its type
auto column = dynamic_cast<tools::wroot::base_pntuple::column<T>* >(icolumn);
if ( ! column ) {
G4ExceptionDescription description;
description << " Column type does not match: "
<< " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
G4Exception("G4TNtupleManager:FillNtupleTColumn",
"Analysis_W011", JustWarning, description);
return false;
}
column->fill(value);
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId
<< " columnId " << columnId << " value " << value;
fState.GetVerboseL4()->Message("done fill", "pntuple T column", description);
}
#endif
return true;
}
#endif
@@ -0,0 +1,334 @@
//
// ********************************************************************
// * 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: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiAnalysisManager.hh"
#include "G4RootMpiNtupleManager.hh"
#include "G4RootMpiPNtupleManager.hh"
#include <tools/impi>
//_____________________________________________________________________________
G4RootMpiAnalysisManager::G4RootMpiAnalysisManager(G4bool isMaster)
: G4RootAnalysisManager(isMaster)
{}
//_____________________________________________________________________________
G4RootMpiAnalysisManager::~G4RootMpiAnalysisManager()
{}
//
// private methods
//
//_____________________________________________________________________________
void G4RootMpiAnalysisManager::CreateMpiNtupleManagers(
tools::impi* impi, G4int mpiRank, G4int mpiSize)
{
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()->Message("create", "mpi ntuple managers", "");
#endif
switch ( fMpiNtupleMergeMode )
{
case G4MpiNtupleMergeMode::kNone:
fNtupleManager = new G4RootNtupleManager(fState, 0, fNtupleRowWise);
fNtupleManager->SetFileManager(fFileManager);
SetNtupleManager(fNtupleManager);
break;
case G4MpiNtupleMergeMode::kMain: {
fNtupleManager
= new G4RootMpiNtupleManager(fState, fNtupleRowWise, impi, mpiSize);
fNtupleManager->SetFileManager(fFileManager);
SetNtupleManager(fNtupleManager);
break;
}
case G4MpiNtupleMergeMode::kSlave: {
auto destinationRank = mpiSize;
fMpiSlaveNtupleManager
= new G4RootMpiPNtupleManager(fState, fNtupleRowWise, impi, mpiRank, destinationRank);
SetNtupleManager(fMpiSlaveNtupleManager);
break;
}
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL3() )
fState.GetVerboseL3()->Message("create", "mpi ntuple managers", "");
#endif
}
//_____________________________________________________________________________
void G4RootMpiAnalysisManager::SetMpiNtupleMergingMode(
G4int mpiRank, G4int mpiSize,
G4int nofNtupleFiles)
{
#ifdef G4VERBOSE
if ( fState.GetVerboseL1() )
fState.GetVerboseL1()
->Message("set", "mpi ntuple merging mode", "");
#endif
auto canMerge = true;
// Illegal situations
if ( mpiSize < 2 ) {
G4ExceptionDescription description;
description
<< " " << "Merging ntuples is not applicable on a single rank."
<< G4endl
<< " " << "Setting was ignored.";
G4Exception("G4RootMpiAnalysisManager::SetMpiNtupleMergingMode()",
"Analysis_W013", JustWarning, description);
canMerge = false;
}
G4String mergingMode;
if ( ! canMerge ) {
fMpiNtupleMergeMode = G4MpiNtupleMergeMode::kNone;
mergingMode = "G4MpiNtupleMergeMode::kNone";
}
else {
// Set the number of reduced ntuple files
// (multiple output files are not yet supported)
fNofNtupleFiles = nofNtupleFiles;
// Forced merging mode
// MPI
if ( mpiRank >= mpiSize ) {
// the extra worker
fMpiNtupleMergeMode = G4MpiNtupleMergeMode::kMain;
mergingMode = "G4MpiNtupleMergeMode::kMain";
} else {
// processing worker
fMpiNtupleMergeMode = G4MpiNtupleMergeMode::kSlave;
mergingMode = "G4MpiNtupleMergeMode::kSlave";
}
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL2() )
fState.GetVerboseL2()
->Message("set", "ntuple merging mode", mergingMode);
#endif
}
//_____________________________________________________________________________
void G4RootMpiAnalysisManager::SetMpiNtupleMerging(tools::impi* impi,
G4int mpiRank, G4int mpiSize,
G4int nofNtupleFiles,
G4bool rowWise,
unsigned int basketSize)
{
// G4cout << "SetMpiNtupleMerging: "
// << impi << ", "
// << mpiRank << ","
// << mpiSize << ","
// << nofNtupleFiles << ","
// << rowWise << ","
// << basketSize << G4endl;
// fImpi = impi;
// Keep basketSize in file manager
fFileManager->SetBasketSize(basketSize);
fNtupleRowWise = rowWise;
// Set ntuple merging mode
SetMpiNtupleMergingMode(mpiRank, mpiSize, nofNtupleFiles);
// Clear existing managers
ClearNtupleManagers();
// Re-create managers
CreateMpiNtupleManagers(impi, mpiRank, mpiSize);
}
//
// protected methods
//
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::OpenFileImpl(const G4String& fileName)
{
// No MPI merging, call base class
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kNone ) {
return G4RootAnalysisManager::OpenFileImpl(fileName);
}
auto finalResult = true;
auto result = fFileManager->SetFileName(fileName);
finalResult = finalResult && result;
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kMain ) {
#ifdef G4VERBOSE
G4String name = fFileManager->GetFullFileName();
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()->Message("open", "main ntuple file", name);
#endif
fFileManager->SetNofNtupleFiles(fNofNtupleFiles);
result = fFileManager->OpenFile(fileName);
finalResult = finalResult && result;
fNtupleManager->SetNtupleDirectory(fFileManager->GetNtupleDirectory());
G4cout << "Main: Go to create ntuples from booking " << G4endl;
fNtupleManager->CreateNtuplesFromBooking();
#ifdef G4VERBOSE
if ( fState.GetVerboseL1() )
fState.GetVerboseL1()->Message("open", "main ntuple file", name, finalResult);
#endif
}
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kSlave ) {
#ifdef G4VERBOSE
G4String name = fFileManager->GetFullFileName();
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()->Message("open", "file", name);
#endif
result = fFileManager->OpenFile(fileName);
finalResult = finalResult && result;
// fNtupleManager->SetNtupleDirectory(fFileManager->GetNtupleDirectory());
G4cout << "Slave: Go to create ntuples from booking" << G4endl;
// No file is open by Slave manager
fMpiSlaveNtupleManager->CreateNtuplesFromBooking();
#ifdef G4VERBOSE
if ( fState.GetVerboseL1() )
fState.GetVerboseL1()->Message("open", "file", name, finalResult);
#endif
}
return finalResult;
}
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::CloseFileImpl(G4bool reset)
{
// No MPI merging, call base class
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kNone ) {
return G4RootAnalysisManager::CloseFileImpl(reset);
}
auto finalResult = true;
// reset data
if ( reset ) {
auto result = Reset();
if ( ! result ) {
G4ExceptionDescription description;
description << " " << "Resetting data failed";
G4Exception("G4RootAnalysisManager::Write()",
"Analysis_W021", JustWarning, description);
}
finalResult = finalResult && result;
}
// close file
fFileManager->CloseFile();
// MT not yet supported - no files clean-up
return finalResult;
}
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::WriteNtuple()
{
// No MPI merging, call base class
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kNone ) {
return G4RootAnalysisManager::WriteNtuple();
}
auto finalResult = true;
G4String ntupleType;
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kMain ) ntupleType = "main ntuples";
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kSlave ) ntupleType = "slave ntuples";
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()->Message("merge", ntupleType, "");
#endif
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kMain ) {
auto result = fNtupleManager->Merge();
finalResult = result && finalResult;
}
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kSlave ) {
auto result = fMpiSlaveNtupleManager->Merge();
finalResult = result && finalResult;
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL1() )
fState.GetVerboseL1()->Message("merge", ntupleType, "");
#endif
return finalResult;
}
//_____________________________________________________________________________
G4bool G4RootMpiAnalysisManager::Reset()
{
// Reset histograms and ntuple
// No MPI merging, call base class
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kNone ) {
return G4RootAnalysisManager::Reset();
}
auto finalResult = true;
auto result = G4ToolsAnalysisManager::Reset();
finalResult = finalResult && result;
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kMain ) {
result = fNtupleManager->Reset(false);
finalResult = result && finalResult;
}
if ( fMpiNtupleMergeMode == G4MpiNtupleMergeMode::kSlave ) {
result = fMpiSlaveNtupleManager->Reset(false);
finalResult = result && finalResult;
}
return finalResult;
}
@@ -0,0 +1,289 @@
//
// ********************************************************************
// * 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: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiNtupleManager.hh"
#include "G4RootMainNtupleManager.hh"
#include "G4RootFileManager.hh"
#include "G4AnalysisManagerState.hh"
#include "G4AnalysisUtilities.hh"
#include "tools/wroot/file"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "tools/wroot/mpi_ntuple_column_wise"
using namespace G4Analysis;
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
//_____________________________________________________________________________
G4RootMpiNtupleManager::G4RootMpiNtupleManager(
const G4AnalysisManagerState& state, G4bool rowWise,
tools::impi* impi, G4int mpiSize)
: G4RootNtupleManager(state, 0, rowWise),
fImpi(impi),
fSlaveRanks(),
fMainRank(0)
{
for ( G4int rank = 0; rank < mpiSize; rank++ ) {
fSlaveRanks.push_back(rank);
}
fMainRank = mpiSize;
}
//_____________________________________________________________________________
G4RootMpiNtupleManager::~G4RootMpiNtupleManager()
{}
//
// private methods
//
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::Send(G4int id, tools::wroot::ntuple* ntuple)
{
// Pack and send the main ntuple data to the slave ranks
// G4cout << "Going to send main ntuple data " << G4endl;
// Get basket sizes
std::vector<tools::wroot::branch*> mainBranches;
ntuple->get_branches(mainBranches);
std::vector<tools::uint32> basketSizes;
tools_vforcit(tools::wroot::branch*, mainBranches, it) {
basketSizes.push_back((*it)->basket_size());
}
auto ntupleFile = fFileManager->GetNtupleFile(id);
tools::uint32 basketSize = fFileManager->GetBasketSize();
for ( auto slaveRank : fSlaveRanks ) {
G4cout << "Going to send main ntuple data to slave rank " << slaveRank << G4endl;
fImpi->pack_reset();
if ( ! fImpi->pack(id)) {
G4cerr << "pack(id) failed." << G4endl;
return false;
}
if ( ! fImpi->bpack(ntupleFile->byte_swap())) {
G4cerr << "bpack(byte_swap) failed." << G4endl;
return false;
}
if ( ! fImpi->pack(ntupleFile->compression()) ) {
G4cerr << "pack(compression) failed." << G4endl;
return false;
}
if ( ! fImpi->pack(ntupleFile->dir().seek_directory())) {
// Should be used fNtupleDirectory ??
G4cerr << "pack(seek) failed." << G4endl;
return false;
}
if ( fRowWise ) {
if ( ! fImpi->pack(basketSize) ) {
G4cerr << "pack(basket_sizes) failed." << G4endl;
return false;
}
} else {
if ( ! fImpi->vpack(basketSizes) ) {
G4cerr << "vpack(basket_sizes) failed." << G4endl;
return false;
}
}
if ( ! fImpi->send_buffer(slaveRank, kTAG_NTUPLE )) {
G4cerr << "send_buffer() failed." << G4endl;
return false;
}
fImpi->pack_reset();
G4cout << "Sent ntuple description to slave on rank " << slaveRank << G4endl;
}
// G4cout << "Done: send main ntuple data " << G4endl;
return true;
}
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::InitializeRanks()
{
// G4cout << "G4RootMpiNtupleManager::InitializeRanks" << G4endl;
auto finalResult = true;
auto counter = 0;
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->fActivation ) ) continue;
auto result = Send(counter++, ntupleDescription->fNtuple);
finalResult = finalResult && result;
}
return finalResult;
}
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::WaitBuffer()
{
// Receive the pntuple data from the slave ranks
// For the time being only one ntuple
G4cout << "G4RootMpiNtupleManager::WaitBuffer" << G4endl;
unsigned long numberOfEndFill = 0;
G4bool verbose = ( fState.GetVerboseL2() );
while ( true ) {
fImpi->pack_reset();
// loop until receiving end_fill from all ranks
// G4cout << "G4RootMpiNtupleManager::WaitBuffer entering loop" << G4endl;
int probe_src;
if ( ! fImpi->wait_buffer(fMainRank, kTAG_NTUPLE, probe_src, verbose)) {
G4cerr << "!!! wait_buffer() failed." << std::endl;
return EXIT_FAILURE;
}
tools::uint32 protocol;
if ( ! fImpi->unpack(protocol)) {
G4cerr << "sunpack(protocol) failed."<< G4endl;
return false;
}
if ( protocol == tools::wroot::mpi_protocol_basket() ) {
// G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_basket" << G4endl;
// get ntuple Id
tools::uint32 ntupleId;
if ( ! fImpi->unpack(ntupleId) ) {
G4cerr << "unpack(ntuple_id) failed."<< std::endl;
return false;
}
if ( ntupleId >= fNtupleVector.size() ) {
std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
return false;
}
// Main ntuple
auto mainNtuple = fNtupleVector[ntupleId];
// add basket to main ntuple
if ( ! mainNtuple->mpi_add_basket(*fImpi)) {
std::cerr << "mainNtuple->mpi_add_basket() failed." << std::endl;
return EXIT_FAILURE;
}
}
else if ( protocol==tools::wroot::mpi_protocol_end_fill() ) {
// G4cout << "G4RootMpiNtupleManager::WaitBuffer got protocol_end_fill" << G4endl;
// get ntuple Id
tools::uint32 ntupleId;
if ( ! fImpi->unpack(ntupleId) ) {
G4cerr << "unpack(ntuple_id) failed."<< std::endl;
return false;
}
if ( ntupleId >= fNtupleVector.size() ) {
std::cerr << "!!! unknown ntupleId " << ntupleId << std::endl;
return false;
}
// Main ntuple
auto mainNtuple = fNtupleVector[ntupleId];
// end_fill in main ntuple
if ( ! mainNtuple->mpi_end_fill(*fImpi) ) {
G4cerr << "main_ntuple->mpi_end_fill() failed." << std::endl;
return false;
}
numberOfEndFill++;
if ( numberOfEndFill == fSlaveRanks.size() ) break;
}
else {
G4cerr << "unknown protocol " << protocol << G4endl;
return false;
}
}
return true;
}
//
// public methods
//
//_____________________________________________________________________________
void G4RootMpiNtupleManager::CreateNtuplesFromBooking()
{
// Base class actions
// G4cout << "Going to call CreateNtuplesFromBooking from base class" << G4endl;
G4TNtupleManager<tools::wroot::ntuple>::CreateNtuplesFromBooking();
// Initialize ranks
if ( ! InitializeRanks() ) {
G4cerr << "InitializeRanks failed." << G4endl;
}
// Go to wait buffer mode
if ( ! WaitBuffer() ) {
G4cerr << "WaitBuffer failed." << G4endl;
}
}
//_____________________________________________________________________________
G4bool G4RootMpiNtupleManager::Merge()
{
G4cout << "G4RootMpiNtupleManager::Merge()" << G4endl;
auto finalResult = true;
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->fActivation ) ) continue;
// G4cout << "Go to call merge_number_of_entries" << G4endl;
ntupleDescription->fNtuple->merge_number_of_entries();
}
return finalResult;
}
@@ -0,0 +1,525 @@
//
// ********************************************************************
// * 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: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4RootMpiPNtupleManager.hh"
#include "G4RootFileManager.hh"
#include "G4AnalysisUtilities.hh"
#include "tools/wroot/file"
#include "tools/wroot/mpi_ntuple_row_wise"
#include "tools/wroot/mpi_ntuple_column_wise"
const int kTAG_NTUPLE = 1004; // This constant is defined in G4MPImanager
// (should be passed from the application)
//_____________________________________________________________________________
G4RootMpiPNtupleManager::G4RootMpiPNtupleManager(
const G4AnalysisManagerState& state, G4bool rowWise,
tools::impi* impi, G4int mpiRank, G4int destinationRank)
: G4BaseNtupleManager(state),
fNtupleVector(),
fRowWise(rowWise),
fImpi(impi),
fMpiRank(mpiRank),
fDestinationRank(destinationRank)
{
}
//_____________________________________________________________________________
G4RootMpiPNtupleManager::~G4RootMpiPNtupleManager()
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
delete ntupleDescription;
}
}
//
// private functions
//
//_____________________________________________________________________________
G4RootMpiPNtupleDescription*
G4RootMpiPNtupleManager::GetNtupleDescriptionInFunction(
G4int id, G4String functionName, G4bool warn) const
{
auto index = id - fFirstId;
if ( index < 0 || index >= G4int(fNtupleDescriptionVector.size()) ) {
if ( warn) {
G4String inFunction = "G4RootMpiPNtupleManager::";
inFunction += functionName;
G4ExceptionDescription description;
description << " " << "ntuple " << id << " does not exist.";
G4Exception(inFunction, "Analysis_W011", JustWarning, description);
}
return nullptr;
}
return fNtupleDescriptionVector[index];
}
//_____________________________________________________________________________
tools::wroot::base_pntuple* G4RootMpiPNtupleManager::GetNtupleInFunction(
G4int id, G4String functionName, G4bool warn) const
{
auto ntupleDescription = GetNtupleDescriptionInFunction(id, functionName);
if ( ! ntupleDescription ) return nullptr;
if ( ! ntupleDescription->fBasePNtuple ) {
if ( warn ) {
G4String inFunction = "G4RootMpiPNtupleManager::";
inFunction += functionName;
G4ExceptionDescription description;
description << " " << "ntupleId " << id << " does not exist.";
G4Exception(inFunction, "Analysis_W011", JustWarning, description);
}
return nullptr;
}
return ntupleDescription->fBasePNtuple;
}
//
// protected functions
//
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::CreateNtuple(G4RootMpiPNtupleDescription* ntupleDescription)
{
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()
->Message("create from booking", "mpi pntuple", ntupleDescription->fNtupleBooking.name());
#endif
// Wait for the ntuple data from main
G4bool verbose = ( fState.GetVerboseL2() );
G4cout << "Go to wait_buffer from " << fDestinationRank << G4endl;
fImpi->pack_reset();
int probe_src;
if ( ! fImpi->wait_buffer(fMpiRank, fDestinationRank, kTAG_NTUPLE, probe_src, verbose)) {
G4cerr << "G4RootMpiPNtupleManager::CreateNtuple: wait_buffer() failed."<< G4endl;
return;
}
G4cout << "After wait_buffer with " << fImpi << G4endl;
tools::uint32 mainNtupleId;
bool byteSwap;
unsigned int compression;
tools::wroot::seek seekDirectory;
tools::uint32 basketSize;
std::vector<tools::uint32> basketSizes;
if ( ! fImpi->unpack(mainNtupleId) ) {
G4cerr << "bunpack(byteSwap) failed."<< G4endl;
return;
}
// G4cout << "unpack 1" << G4endl;
if ( ! fImpi->bunpack(byteSwap) ) {
G4cerr << "bunpack(byteSwap) failed."<< G4endl;
return;
}
// G4cout << "unpack 2" << G4endl;
if ( ! fImpi->unpack(compression) ) {
G4cerr << "unpack(compression) failed."<< G4endl;
return;
}
// G4cout << "unpack 3" << G4endl;
if ( ! fImpi->unpack(seekDirectory) ) {
G4cerr << "unpack(seek) failed."<< G4endl;
return;
}
// G4cout << "unpack 4" << G4endl;
if(fRowWise) {
if ( ! fImpi->unpack(basketSize) ) {
G4cerr << "unpack(basketSize) failed."<< G4endl;
return;
}
} else {
if ( ! fImpi->vunpack(basketSizes) ) {
G4cerr << "vunpack(basketSizes) failed."<< G4endl;
return;
}
}
// G4cout << "unpack 5" << G4endl;
// G4cout << "rank = " << fMpiRank
// << ", verbose = " << verbose
// << ", mainNtupleId = " << mainNtupleId
// << ", byteSwap = " << byteSwap
// << ", compression = " << compression
// << ", seekDirectory = " << seekDirectory
// << ", basketSizes.size() = " << basketSizes.size()
// << G4endl;
// Create MPI pntuple
if ( fRowWise ) {
tools::wroot::mpi_ntuple_row_wise* ntuple
= new tools::wroot::mpi_ntuple_row_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory,
basketSize, ntupleDescription->fNtupleBooking, verbose);
ntupleDescription->fNtuple = ntuple;
ntupleDescription->fBasePNtuple = ntuple;
} else {
tools::wroot::mpi_ntuple_column_wise* ntuple
= new tools::wroot::mpi_ntuple_column_wise(
mainNtupleId, G4cout, byteSwap, compression, seekDirectory,
basketSizes, ntupleDescription->fNtupleBooking, verbose);
ntupleDescription->fNtuple = ntuple;
ntupleDescription->fBasePNtuple = ntuple;
}
ntupleDescription->fIsNtupleOwner = true;
ntupleDescription->fImpi = fImpi;
// should be not needed
// pntuple object is not deleted automatically
fNtupleVector.push_back(ntupleDescription->fNtuple);
#ifdef G4VERBOSE
if ( fState.GetVerboseL3() )
fState.GetVerboseL3()
->Message("create from booking", "mpi pntuple", ntupleDescription->fNtupleBooking.name());
#endif
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::CreateNtuplesFromBooking()
{
// Create ntuple from ntuple_booking & the buffer from main rank
// G4cout << "Start G4RootMpiPNtupleManager::CreateNtuplesFromBooking" << G4endl;
// Do not create ntuples if NtupleVector is not empty
if ( fNtupleVector.size() ) return;
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
// Do not create ntuple if it is inactivated
if ( fState.GetIsActivation() && ( ! ntupleDescription->fActivation ) ) continue;
// Do not create ntuple if it already exists
if ( ntupleDescription->fNtuple ) continue;
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()
->Message("create from booking", "mpi pntuple",
ntupleDescription->fNtupleBooking.name());
#endif
// create ntuple
CreateNtuple(ntupleDescription);
// finish created ntuple
// (nothing to be done ?)
// FinishTNtuple(ntupleDescription);
#ifdef G4VERBOSE
if ( fState.GetVerboseL3() )
fState.GetVerboseL3()
->Message("create from booking", "mpi pntuple",
ntupleDescription->fNtupleBooking.name());
#endif
}
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtuple(
const G4String& name, const G4String& title)
{
// Create pntuple description with ntuple_booking
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() )
fState.GetVerboseL4()->Message("create", "pntuple booking", name);
#endif
// Create ntuple description
auto index = fNtupleDescriptionVector.size();
auto ntupleDescription = new G4RootMpiPNtupleDescription();
ntupleDescription->fMainNtupleRank = fDestinationRank;
// make this flexible
fNtupleDescriptionVector.push_back(ntupleDescription);
// Save name & title in ntuple booking
ntupleDescription->fNtupleBooking.set_name(name);
ntupleDescription->fNtupleBooking.set_title(title);
fLockFirstId = true;
#ifdef G4VERBOSE
if ( fState.GetVerboseL2() ) {
G4ExceptionDescription description;
description << name << " ntupleId " << index + fFirstId;
fState.GetVerboseL2()->Message("create", "pntuple booking", description);
}
#endif
return index + fFirstId;
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtupleIColumn(
G4int ntupleId, const G4String& name, std::vector<int>* vector)
{
return CreateNtupleTColumn<int>(ntupleId, name, vector);
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtupleFColumn(
G4int ntupleId, const G4String& name, std::vector<float>* vector)
{
return CreateNtupleTColumn<float>(ntupleId, name, vector);
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtupleDColumn(
G4int ntupleId, const G4String& name, std::vector<double>* vector)
{
return CreateNtupleTColumn<double>(ntupleId, name, vector);
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::CreateNtupleSColumn(
G4int ntupleId, const G4String& name)
{
return CreateNtupleTColumn<std::string>(ntupleId, name, nullptr);
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::FinishNtuple(G4int /*ntupleId*/)
{}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleIColumn(
G4int ntupleId, G4int columnId, G4int value)
{
return FillNtupleTColumn<int>(ntupleId, columnId, value);
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleFColumn(
G4int ntupleId, G4int columnId, G4float value)
{
return FillNtupleTColumn<float>(ntupleId, columnId, value);
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleDColumn(
G4int ntupleId, G4int columnId, G4double value)
{
return FillNtupleTColumn<double>(ntupleId, columnId, value);
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::FillNtupleSColumn(
G4int ntupleId, G4int columnId, const G4String& value)
{
return FillNtupleTColumn<std::string>(ntupleId, columnId, value);
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::AddNtupleRow(G4int ntupleId)
{
if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
//G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl;
return false;
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId;
fState.GetVerboseL4()->Message("add", "pntuple row", description);
}
#endif
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "AddNtupleRow");
if ( ! ntupleDescription ) return false;
// if(!_ntuple->add_row(_impi,rank_src,tag)) {
auto result
= ntupleDescription->fNtuple
->add_row(*fImpi, ntupleDescription->fMainNtupleRank, kTAG_NTUPLE );
if ( ! result ) {
G4ExceptionDescription description;
description << " " << " ntupleId " << ntupleId
<< "adding row has failed.";
G4Exception("G4RootMpiPNtupleManager::AddNtupleRow()",
"Analysis_W002", JustWarning, description);
}
#ifdef G4VERBOSE
if ( fState.GetVerboseL3() ) {
G4ExceptionDescription description;
description << " ntupleId " << ntupleId;
fState.GetVerboseL3()->Message("add", "pntuple row", description);
}
#endif
return true;
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::Merge()
{
// G4cout << "Start G4RootMpiPNtupleManager::Merge" << G4endl;
auto finalResult = true;
for ( auto ntupleDescription : fNtupleDescriptionVector) {
// skip inactivated ntuples
if ( ! ntupleDescription->fActivation ) continue;
// skip if ntuple was already merged and deleted
// (this happend when the main rank re-opens a new file for merged data)
if ( ! ntupleDescription->fNtuple ) continue;
#ifdef G4VERBOSE
if ( fState.GetVerboseL4() ) {
fState.GetVerboseL4()
->Message("end_fill", "pntuple", ntupleDescription->fNtupleBooking.name());
}
#endif
// if(!_ntuple->end_fill(_impi,rank_src,tag)) {} //important.
G4cout << "call end_fill " << fImpi
<< " to rank " << ntupleDescription->fMainNtupleRank
<< " pntuple: " << ntupleDescription->fNtuple << G4endl;
auto result
= ntupleDescription->fNtuple
->end_fill(*fImpi, ntupleDescription->fMainNtupleRank, kTAG_NTUPLE);
if ( ! result ) {
G4ExceptionDescription description;
description << " " << " ntuple " << ntupleDescription->fNtupleBooking.name()
<< "end fill has failed.";
G4Exception("G4RootMpiPNtupleManager::Merge()",
"Analysis_W002", JustWarning, description);
}
delete ntupleDescription->fNtuple;
ntupleDescription->fNtuple = nullptr;
#ifdef G4VERBOSE
if ( fState.GetVerboseL3() ) {
fState.GetVerboseL3()
->Message("end_fill", "pntuple", ntupleDescription->fNtupleBooking.name());
}
#endif
}
return finalResult;
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::Reset(G4bool deleteNtuple)
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
if ( deleteNtuple ) {
delete ntupleDescription->fNtuple;
}
ntupleDescription->fNtuple = nullptr;
}
fNtupleVector.clear();
return true;
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::SetActivation(
G4bool activation)
{
for ( auto ntupleDescription : fNtupleDescriptionVector ) {
ntupleDescription->fActivation = activation;
}
}
//_____________________________________________________________________________
void G4RootMpiPNtupleManager::SetActivation(
G4int ntupleId, G4bool activation)
{
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "SetActivation");
if ( ! ntupleDescription ) return;
ntupleDescription->fActivation = activation;
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::GetActivation(
G4int ntupleId) const
{
auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "GetActivation");
if ( ! ntupleDescription ) return false;
return ntupleDescription->fActivation;
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::GetNofNtuples() const
{
return fNtupleVector.size();
}
//_____________________________________________________________________________
G4int G4RootMpiPNtupleManager::GetNofNtupleBookings() const
{
return fNtupleDescriptionVector.size();
}
//_____________________________________________________________________________
G4bool G4RootMpiPNtupleManager::IsEmpty() const
{
return ! fNtupleDescriptionVector.size();
}
//_____________________________________________________________________________
unsigned int G4RootMpiPNtupleManager::GetBasketSize() const
{
if ( ! fFileManager ) {
G4String inFunction = "G4RootMpiPNtupleManager::::GetBasketSize";
G4ExceptionDescription description;
description << " " << "File manager must be defined first.";
G4Exception(inFunction, "Analysis_W011", JustWarning, description);
return 0;
}
return fFileManager->GetBasketSize();
}
@@ -0,0 +1,52 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The extra MPI worker class defines actions on an extra MPI worker
// which does not perform event processing.
// It calls the BeginOfRunAction() and EndOfRunAction().
// Currently used only for ntuple merging.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4MPIEXTRAWORKER_HH
#include "G4VMPIextraWorker.hh"
class G4UserRunAction;
class G4MPIextraWorker : public G4VMPIextraWorker
{
public:
G4MPIextraWorker(G4UserRunAction* runAction) : fRunAction(runAction) {}
virtual ~G4MPIextraWorker() {}
virtual void BeamOn();
private:
G4UserRunAction* fRunAction;
};
#endif //G4MPIEXTRAWORKER_HH
@@ -41,6 +41,7 @@ class G4MPImessenger;
class G4MPIsession;
class G4MPIstatus;
class G4VMPIseedGenerator;
class G4VMPIextraWorker;
class G4MPImanager {
public:
@@ -54,11 +55,12 @@ public:
kTAG_DATA = 1000,
kTAG_HISTO = 1001,
kTAG_RUN = 1002,
kTAG_CMDSCR = 1003
kTAG_CMDSCR = 1003,
kTAG_NTUPLE = 1004
};
G4MPImanager();
G4MPImanager(int argc, char** argv);
G4MPImanager(int nof_extra_workers = 0);
G4MPImanager(int argc, char** argv, int nof_extra_workers = 0);
~G4MPImanager();
static G4MPImanager* GetManager();
@@ -69,11 +71,13 @@ public:
G4int GetVerbose() const;
void SetVerbose(G4int iverbose);
G4int GetSize() const;
G4int GetTotalSize() const; // get size of all ranks
G4int GetActiveSize() const; // get size of ranks wher RunBeamOn is called
G4int GetRank() const;
G4bool IsMaster() const;
G4bool IsSlave() const;
G4bool IsExtraWorker() const;
G4bool IsInitMacro() const;
const G4String& GetInitFileName() const;
@@ -84,6 +88,9 @@ public:
void SetMasterWeight(G4double aweight);
G4double GetMasterWeight() const;
void SetExtraWorker(G4VMPIextraWorker* extraWorker);
G4VMPIextraWorker* GetExtraWorker() const;
G4VMPIseedGenerator* GetSeedGenerator() const;
// MPI methods
@@ -107,7 +114,10 @@ public:
// misc
void ShowHelp() const;
//MPI::Intracomm* GetComm() const { return &COMM_G4COMMAND_; }
const MPI::Intracomm* GetComm() const { return &COMM_G4COMMAND_; }
const MPI_Comm* GetProcessingComm() const { return &processing_comm_; }
const MPI_Comm* GetCollectingComm() const { return &collecting_comm_; }
const MPI_Comm* GetAllComm() const { return &all_comm_; }
private:
DISALLOW_COPY_AND_ASSIGN(G4MPImanager);
@@ -119,6 +129,7 @@ private:
static G4MPImanager* g4mpi_;
G4MPImessenger* messenger_;
G4MPIsession* session_;
G4VMPIextraWorker* extra_worker_;
// seed generator
G4VMPIseedGenerator* seed_generator_;
@@ -130,11 +141,24 @@ private:
// MPI rank
G4bool is_master_;
G4bool is_slave_;
G4bool is_extra_worker_;
G4int rank_;
G4int size_;
G4int size_; // processing comm size
G4int world_size_; // world comm size
// MPI communicator
// MPI communicator (when no extra ranks)
MPI::Intracomm COMM_G4COMMAND_;
// MPI communicator (processing ranks - if ntuple merging)
MPI_Comm processing_comm_;
// MPI communicator (collecting ranks - if ntuple merging)
MPI_Comm collecting_comm_;
// MPI communicator (all ranks - if ntuple mergins)
MPI_Comm all_comm_;
// Interim data - need to be freed
MPI_Group world_group_;
MPI_Group processing_group_;
MPI_Group collecting_group_;
MPI_Group all_group_;
// cout/cerr control
G4bool qfcout_;
@@ -151,6 +175,7 @@ private:
// parallel parameters
G4double master_weight_;
G4int nof_extra_workers_;
};
// ====================================================================
@@ -179,7 +204,12 @@ inline G4int G4MPImanager::GetRank() const
return rank_;
}
inline G4int G4MPImanager::GetSize() const
inline G4int G4MPImanager::GetTotalSize() const
{
return world_size_;
}
inline G4int G4MPImanager::GetActiveSize() const
{
return size_;
}
@@ -194,6 +224,11 @@ inline G4bool G4MPImanager::IsSlave() const
return is_slave_;
}
inline G4bool G4MPImanager::IsExtraWorker() const
{
return is_extra_worker_;
}
inline G4bool G4MPImanager::IsInitMacro() const
{
return qinitmacro_;
@@ -229,6 +264,11 @@ inline G4double G4MPImanager::GetMasterWeight() const
return master_weight_;
}
inline G4VMPIextraWorker* G4MPImanager::GetExtraWorker() const
{
return extra_worker_;
}
inline G4VMPIseedGenerator* G4MPImanager::GetSeedGenerator() const
{
return seed_generator_;
@@ -0,0 +1,55 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Class for configuring G4analysis for merging ntuples via MPI
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4MPINTUPLEMERGER_HH
#define G4MPINTUPLEMERGER_HH
#include "G4MPImanager.hh"
#include "G4VMPIextraWorker.hh"
namespace tools {
namespace mpi {
class wrmpi;
}
}
class G4RootMpiAnalysisManager;
class G4MPIntupleMerger
{
public:
G4MPIntupleMerger(G4int nofReducedNtupleFiles = 0,
G4bool rowWise = false);
~G4MPIntupleMerger();
private:
tools::mpi::wrmpi* fWrmpi;
};
#endif //G4MPINTUPLEMERGER_HH
@@ -0,0 +1,42 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The interface class for an extra MPI worker
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#ifndef G4MVPIEXTRAWORKER_HH
class G4VMPIextraWorker {
public:
G4VMPIextraWorker() {}
virtual ~G4VMPIextraWorker() {}
virtual void BeamOn() = 0;
};
#endif //G4MPIVEXTRAWORKER_HH
@@ -0,0 +1,48 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The extra MPI worker class defines actions on an extra MPI worker
// which does not perform event processing.
// It calls the BeginOfRunAction() and EndOfRunAction().
// Currently used only for ntuple merging.
//
// Author: Ivana Hrivnacova, 21/11/2018 (ivana@ipno.in2p3.fr)
#include "G4MPIextraWorker.hh"
#include "G4UserRunAction.hh"
#include "G4Run.hh"
#include "g4ios.hh"
void G4MPIextraWorker::BeamOn()
{
G4Run dummyRun;
G4cout << "G4MPIextraWorker: call BeginOfRunAction()" << G4endl;
fRunAction->BeginOfRunAction(&dummyRun);
G4cout << "G4MPIextraWorker: call EndOfRunAction()" << G4endl;
fRunAction->EndOfRunAction(&dummyRun);
}
@@ -29,6 +29,7 @@
// Jun 27, 2015 : Ivana Hrivnacova - new implementation using g4analysis
#include "G4MPIhistoMerger.hh"
#include "G4MPImanager.hh"
#include "G4ios.hh"
#include "tools/mpi/hmpi"
#include <mpi.h>
@@ -47,13 +48,14 @@ void G4MPIhistoMerger::Merge()
G4cout << "Starting merging of histograms" << G4endl;
}
MPI::Intracomm comm = MPI::COMM_WORLD.Dup();
const MPI::Intracomm* parentComm = G4MPImanager::GetManager()->GetComm();
MPI::Intracomm comm = parentComm->Dup();
G4bool verbose = ( verboseLevel > 1 );
G4int tag = G4MPImanager::kTAG_HISTO;
//const MPI::Intracomm* comm = &COMM_G4COMMAND_;
tools::mpi::hmpi* hmpi = new tools::mpi::hmpi(G4cout, destination, tag,
comm, verbose);
tools::mpi::hmpi* hmpi
= new tools::mpi::hmpi(G4cout, destination, tag, comm, verbose);
if ( ! manager->Merge(hmpi) ) {
G4cout<<" Merge FAILED"<<G4endl;
}
@@ -40,6 +40,7 @@
#include "G4MPIrandomSeedGenerator.hh"
#include "G4MPIsession.hh"
#include "G4MPIstatus.hh"
#include "G4MPIextraWorker.hh"
G4MPImanager* G4MPImanager::g4mpi_ = NULL;
@@ -65,9 +66,12 @@ void Wait(G4int ausec)
} // end of namespace
// --------------------------------------------------------------------------
G4MPImanager::G4MPImanager()
: verbose_(0), qfcout_(false), qinitmacro_(false), qbatchmode_(false),
thread_id_(0), master_weight_(1.)
G4MPImanager::G4MPImanager(int nof_extra_workers)
: verbose_(0),
COMM_G4COMMAND_(MPI_COMM_NULL), processing_comm_(MPI_COMM_NULL),
collecting_comm_(MPI_COMM_NULL), all_comm_(MPI_COMM_NULL),
qfcout_(false), qinitmacro_(false), qbatchmode_(false),
thread_id_(0), master_weight_(1.), nof_extra_workers_(nof_extra_workers)
{
//MPI::Init();
MPI::Init_thread(MPI::THREAD_SERIALIZED);
@@ -75,9 +79,12 @@ G4MPImanager::G4MPImanager()
}
// --------------------------------------------------------------------------
G4MPImanager::G4MPImanager(int argc, char** argv)
: verbose_(0), qfcout_(false), qinitmacro_(false), qbatchmode_(false),
thread_id_(0), master_weight_(1.)
G4MPImanager::G4MPImanager(int argc, char** argv, int nof_extra_workers)
: verbose_(0),
COMM_G4COMMAND_(MPI_COMM_NULL), processing_comm_(MPI_COMM_NULL),
collecting_comm_(MPI_COMM_NULL), all_comm_(MPI_COMM_NULL),
qfcout_(false), qinitmacro_(false), qbatchmode_(false),
thread_id_(0), master_weight_(1.), nof_extra_workers_(nof_extra_workers)
{
//MPI::Init(argc, argv);
MPI::Init_thread(argc, argv, MPI::THREAD_SERIALIZED);
@@ -94,7 +101,24 @@ G4MPImanager::~G4MPImanager()
delete messenger_;
delete session_;
COMM_G4COMMAND_.Free();
if ( nof_extra_workers_ ) {
MPI_Group_free(&world_group_);
MPI_Group_free(&processing_group_);
MPI_Group_free(&collecting_group_);
MPI_Group_free(&all_group_);
if (processing_comm_ != MPI_COMM_NULL) {
MPI_Comm_free(&processing_comm_);
}
if (collecting_comm_ != MPI_COMM_NULL) {
MPI_Comm_free(&collecting_comm_);
}
if (all_comm_ != MPI_COMM_NULL) {
MPI_Comm_free(&all_comm_);
}
}
else {
COMM_G4COMMAND_.Free();
}
MPI::Finalize();
}
@@ -109,9 +133,22 @@ G4MPImanager* G4MPImanager::GetManager()
return g4mpi_;
}
// --------------------------------------------------------------------------
void G4MPImanager::SetExtraWorker(G4VMPIextraWorker* extraWorker)
{
if ( ! nof_extra_workers_ ) {
G4Exception("G4MPImanager::SetExtraWorker()", "MPI001",
FatalException, "Number of extra workers >0 must be set first.");
}
extra_worker_ = extraWorker;
}
// --------------------------------------------------------------------------
void G4MPImanager::Initialize()
{
// G4cout << "G4MPImanager::Initialize" << G4endl;
if ( g4mpi_ != NULL ) {
G4Exception("G4MPImanager::Initialize()", "MPI002",
FatalException, "G4MPImanager is already instantiated.");
@@ -120,13 +157,60 @@ void G4MPImanager::Initialize()
g4mpi_ = this;
// get rank information
size_ = MPI::COMM_WORLD.Get_size();
world_size_ = MPI::COMM_WORLD.Get_size();
if ( world_size_ - nof_extra_workers_ <= 0 ) {
G4Exception("G4MPImanager::SetExtraWorker()", "MPI001",
JustWarning, "Cannot reserve extra ranks: the MPI size is not sufficient.");
nof_extra_workers_ = 0;
}
size_ = world_size_ - nof_extra_workers_;
rank_ = MPI::COMM_WORLD.Get_rank();
is_master_ = (rank_ == kRANK_MASTER);
is_slave_ = (rank_ != kRANK_MASTER);
is_extra_worker_ = false;
// initialize MPI communicator
COMM_G4COMMAND_ = MPI::COMM_WORLD.Dup();
if ( nof_extra_workers_ ) {
// G4cout << "Extra workers requested" << G4endl;
// Define three groups of workers: processing, collecting and all;
// if no extra workers are declared, all world ranks are processing ranks
// MPI_Group world_group;
MPI_Comm_group(MPI_COMM_WORLD, &world_group_);
// Group 1 - processing ranks
int* ranks1 = new int[size_];
for (int i=0; i<size_; i++) ranks1[i] = i;
// Construct a group containing all of the processing ranks in world_group
MPI_Group_incl(world_group_, size_, ranks1, &processing_group_);
// Group 2 - collecting ranks
int* ranks2 = new int[nof_extra_workers_];
for (int i=0; i<nof_extra_workers_; i++) ranks2[i] = (world_size_ - nof_extra_workers_) + i;
// Construct a group containing all of the collecting ranks in world_group
MPI_Group_incl(world_group_, nof_extra_workers_, ranks2, &collecting_group_);
// Group 3 - all ranks
int* ranks3 = new int[world_size_];
for (int i=0; i<world_size_; i++) ranks3[i] = i;
// Construct a group containing all of the processing ranks in world_group
MPI_Group_incl(world_group_, world_size_, ranks3, &all_group_);
// Create new communicators based on the groups
MPI_Comm_create_group(MPI_COMM_WORLD, processing_group_, 0, &processing_comm_);
MPI_Comm_create_group(MPI_COMM_WORLD, collecting_group_, 0, &collecting_comm_);
MPI_Comm_create_group(MPI_COMM_WORLD, all_group_, 0, &all_comm_);
// COMM_G4COMMAND_ = processing_comm_ copy
COMM_G4COMMAND_ = MPI::Intracomm(processing_comm_);
} else {
// G4cout << "No extra workers requested" << G4endl;
// initialize MPI communicator
COMM_G4COMMAND_ = MPI::COMM_WORLD.Dup();
}
is_extra_worker_ = (collecting_comm_ != MPI_COMM_NULL);
// new G4MPI stuffs
messenger_ = new G4MPImessenger();
@@ -134,9 +218,21 @@ void G4MPImanager::Initialize()
session_ = new G4MPIsession;
status_ = new G4MPIstatus;
// default seed generator is random generator.
seed_generator_ = new G4MPIrandomSeedGenerator;
DistributeSeeds();
if ( ! is_extra_worker_ ) {
// default seed generator is random generator.
seed_generator_ = new G4MPIrandomSeedGenerator;
DistributeSeeds();
}
// print status of this worker
// G4cout << this << " world_size_ " << world_size_ << G4endl;
// G4cout << this << " size_ " << size_ << G4endl;
// G4cout << this << " nof_extra_workers_ " << nof_extra_workers_ << G4endl;
// G4cout << this << " is_master_ " << is_master_ << G4endl;
// G4cout << this << " is_slave_ " << is_slave_ << G4endl;
// G4cout << this << " is_extra_worker_ " << is_extra_worker_ << G4endl;
// G4cout << this << " is_processing_worker_ "
// << (processing_comm_ != MPI_COMM_NULL) << G4endl;
}
// --------------------------------------------------------------------------
@@ -286,6 +382,9 @@ void G4MPImanager::ShowStatus()
// ====================================================================
void G4MPImanager::DistributeSeeds()
{
// Do nothing if not processing worker
if ( is_extra_worker_ ) return;
std::vector<G4long> seed_list = seed_generator_-> GetSeedList();
G4Random::setTheSeed(seed_list[rank_]);
}
@@ -415,6 +514,9 @@ void G4MPImanager::JoinBeamOnThread()
// ====================================================================
G4String G4MPImanager::BcastCommand(const G4String& command)
{
// Do nothing if not processing worker
if (is_extra_worker_) return G4String("exit");
enum { kBUFF_SIZE = 512 };
static char sbuff[kBUFF_SIZE];
command.copy(sbuff, kBUFF_SIZE);
@@ -459,6 +561,8 @@ void G4MPImanager::ExecuteMacroFile(const G4String& fname, G4bool qbatch)
// --------------------------------------------------------------------------
void G4MPImanager::BeamOn(G4int nevent, G4bool qdivide)
{
// G4cout << "G4MPImanager::BeamOn " << nevent << G4endl;
#ifndef G4MULTITHREADED
G4RunManager* runManager = G4RunManager::GetRunManager();
#endif
@@ -466,7 +570,7 @@ void G4MPImanager::BeamOn(G4int nevent, G4bool qdivide)
if ( qdivide ) { // events are divided
G4double ntot = master_weight_ + size_ - 1.;
G4int nproc = G4int(nevent/ntot);
G4int nproc0 = nevent - nproc*(size_-1);
G4int nproc0 = nevent - nproc*(size_ - 1);
if ( verbose_ > 0 && is_master_ ) {
G4cout << "#events in master=" << nproc0 << " / "
@@ -510,11 +614,25 @@ void G4MPImanager::BeamOn(G4int nevent, G4bool qdivide)
// --------------------------------------------------------------------------
void G4MPImanager::WaitBeamOn()
{
// G4cout << "G4MPImanager::WaitBeamOn" << G4endl;
// Extra worker
if (is_extra_worker_) {
if ( extra_worker_ ) {
G4cout << "Calling extra_worker " << G4endl;
extra_worker_->BeamOn();
} else {
G4cout << " !!!! extra_worker_ is not defined " << G4endl;
}
return;
}
G4int buff = 0;
if ( qbatchmode_ ) { // valid only in batch mode
if ( is_master_ ) {
// receive from each slave
for (G4int islave = 1; islave < size_; islave++) {
// G4cout << "calling Irecv for islave " << islave << G4endl;
MPI::Request request = COMM_G4COMMAND_.Irecv(&buff, 1, MPI::INT,
islave, kTAG_G4STATUS);
while(! request.Test()) {
@@ -523,6 +641,7 @@ void G4MPImanager::WaitBeamOn()
}
} else {
buff = 1;
// G4cout << "calling send for i " << kRANK_MASTER << G4endl;
COMM_G4COMMAND_.Send(&buff, 1, MPI::INT, kRANK_MASTER, kTAG_G4STATUS);
}
}
@@ -88,7 +88,7 @@ G4MPImessenger::G4MPImessenger()
p2-> SetDefaultValue(true);
dot_beam_on_-> SetParameter(p2);
// /mpi/weightForMaster
// /mpi/masterWeight
master_weight_ = new G4UIcmdWithADouble("/mpi/masterWeight", this);
master_weight_-> SetGuidance("Set weight for master node.");
master_weight_-> SetParameterName("weight", false, false);

Some files were not shown because too many files have changed in this diff Show More