Geant4  10.03
RunActionMaster.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: RunActionMaster.cc 82310 2014-06-14 00:27:39Z adotti $
27 //
30 
31 #include "G4MPImanager.hh"
32 #include <stdio.h>
33 #include "G4Threading.hh"
34 #include "Analysis.hh"
35 #include "RunActionMaster.hh"
36 #include "g4root.hh" //ROOT Format for output
37 #include "RunMerger.hh"
38 #include "G4MPIscorerMerger.hh"
39 #include "G4MPIhistoMerger.hh" // New code with use of g4analysis
40 #include "Run.hh"
41 
42 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
44 {
45 }
46 
47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
49 {
50  return new Run;
51 }
52 
53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
55 {
56 }
57 
58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
59 void
61 {
63  myana-> Clear();
64  myana->Book();
65 }
66 
67 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
68 void
70 {
71  //This is executed by master thread only. Worker threads have already
72  //merged their results into this master threads.
73 
74  //We are going to merge the results via MPI for:
75  // 1. User-defined "Run" object
76  // 2. Command line scorers, if exists
77  // 3. G4Analysis objects
78 
79  // For debugging purposes in the following we write out results twice:
80  // BEFORE and AFTER the merging, so that rank 0 actually
81  // writes two files, the one called "*rank000*" will contain the partial
82  // results only from rank #0,
83  // the file *merged* contains the reduction from all ranks.
84  // It should be very easy to adapt this code
85 
86  const G4int rank = G4MPImanager::GetManager()-> GetRank();
87 
88  G4cout << "=====================================================" << G4endl;
89  G4cout << "Start EndOfRunAction for master thread in rank: " << rank<<G4endl;
90  G4cout << "=====================================================" << G4endl;
91 
92  //Merging of G4Run object:
93  //All ranks > 0 merge to rank #0
94  RunMerger rm(static_cast<const Run*>(arun));
95  G4int ver = 0 ; //Use 4 for lots of info
96  if ( rank == 0 && ver == 0) ver = 1;
97 
98  if ( ver > 1 ) {
99  G4cout<<"Before merge the Run object has test counter value: "
100  <<static_cast<const Run*>(arun)->GetCounter()<<G4endl;
101  }
102  rm.SetVerbosity( ver );
103  rm.Merge();
104  if ( ver > 1 ) {
105  G4cout<<"After merge the Run object has test counter value: "
106  <<static_cast<const Run*>(arun)->GetCounter()
107  <<" (with 1 thread== number of ranks)"<<G4endl;
108  }
109 
110  //Merge of scorers
111  ver = 0;
113  const auto scor = G4ScoringManager::GetScoringManager();
114  G4MPIscorerMerger sm(scor);
115  sm.SetVerbosity(ver);
116  //Debug!
117  auto debugme = [&scor](){
118  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
119  const auto m = scor->GetMesh(idx);
120  const MeshScoreMap& map = m->GetScoreMap();
121  std::for_each(map.begin(),map.end(),
122  [](const MeshScoreMap::value_type& e) {
123  G4cout<<e.first<<"("<<e.second<<"):"<<G4endl;
124  const auto data = e.second->GetMap();
125  for( auto it = data->begin() ; it != data->end() ; ++it ) {
126  G4cout<<it->first<<" => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): "
127  <<it->second->n()<<" "<<it->second->sum_w()<<" "
128  <<it->second->sum_w2()<<" "<<it->second->sum_wx()<<" "
129  <<it->second->sum_wx2()<<G4endl;
130  }
131  });
132  }
133  };
134  //Debug!
135  if ( ver > 4 ) {
136  G4cout<<"Before merging: Meshes dump"<<G4endl;
137  debugme();
138  }
139  //Write partial scorers from single ranks *before* merging
140  //Do not rely on UI command to write out scorers, because rank-specific
141  //files will have same file name: need to add rank # to file name
142  if ( true ) {
143  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
144  const auto m = scor->GetMesh(idx);
145  const auto& mn = m->GetWorldName();
146  std::ostringstream fname;
147  fname<<"scorer-"<<mn<<"-rank"<<rank<<".csv";
148  scor->DumpAllQuantitiesToFile(mn,fname.str());
149  }
150  }
151 
152  //Now reduce all scorers to rank #0
153  sm.Merge();
154 
155  //Debug!
156  if ( ver > 4 ) {
157  G4cout<<"After merging: Meshes dump"<<G4endl;
158  debugme();
159  }
160  //For rank #0 write out the merged files
161  if ( rank == 0 ) {
162  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
163  const auto m = scor->GetMesh(idx);
164  const auto& mn = m->GetWorldName();
165  std::ostringstream fname;
166  fname<<"scorer-"<<mn<<"-merged.csv";
167  scor->DumpAllQuantitiesToFile(mn,fname.str());
168  }
169  }
170  }
171 
172  //Save histograms *before* MPI merging for rank #0
173  if (rank == 0)
174  {
175  G4String fname("dose-rank0");
176  Analysis* myana = Analysis::GetAnalysis();
177  myana-> Save(fname);
178  }
179  //Merge of g4analysis objects
180  ver=0;
181  G4MPIhistoMerger hm(G4AnalysisManager::Instance());
182  hm.SetVerbosity(ver);
183  hm.Merge();
184 
185  //Save g4analysis objects to a file
186  //NB: It is important that the save is done *after* MPI-merging of histograms
187 
188  //One can save all ranks or just rank0, chane the if
189  if (true /*rank == 0*/)
190  {
191  std::ostringstream fname;
192  fname<<"dose-rank"<<rank;
193  if (rank == 0) {
194  fname.str("dose-merged");
195  }
196  Analysis* myana = Analysis::GetAnalysis();
197  myana-> Save(fname.str());
198  }
199  Analysis* myana = Analysis::GetAnalysis();
200  myana-> Close();
201 
202  G4cout << "===================================================" << G4endl;
203  G4cout << "End EndOfRunAction for master thread in rank: " << rank << G4endl;
204  G4cout << "===================================================" << G4endl;
205 
206 }
virtual void EndOfRunAction(const G4Run *arun)
void Clear(Node *)
int G4int
Definition: G4Types.hh:78
void SetVerbosity(G4int ver)
G4GLOB_DLL std::ostream G4cout
static G4ScoringManager * GetScoringManagerIfExist()
static constexpr double m
Definition: G4SIunits.hh:129
MPI manager class.
static Analysis * GetAnalysis()
Definition: Analysis.cc:45
Describe run actions.
Definition: G4Run.hh:46
void Book()
Definition: Analysis.cc:65
static G4MPImanager * GetManager()
virtual G4Run * GenerateRun()
void SetVerbosity(G4int ver)
virtual void BeginOfRunAction(const G4Run *arun)
#define G4endl
Definition: G4ios.hh:61
static G4ScoringManager * GetScoringManager()
void SetVerbosity(G4int ver)
Definition: Run.hh:46
std::map< G4String, RunScore * > MeshScoreMap