Geant4  10.01.p02
G4MPIScorerMerger.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 #include "G4MPIScorerMerger.hh"
27 #include <map>
28 #include <strstream>
29 
31  G4int destination,
32  G4int verbosity ) :
33 scoringManager(mgr),commSize(0),destinationRank(destination),verbose(verbosity)
34 {}
35 
36 #define DMSG( LVL , MSG ) { if ( verbose > LVL ) { G4cout << MSG << G4endl; } }
37 
38 std::ostream& operator<<(std::ostream& os ,
39  const G4MPIScorerMerger::convMap_t& cnv ) {
40  static const G4int maxelems = 10;
41  os<<" Name: "<<cnv.name<<" with : "<<cnv.numElems<<" elements\n";
42  os<<"\tIndexes :";
43  for ( G4int i = 0 ;
44  i < ((cnv.numElems<maxelems) ? cnv.numElems : maxelems) ;
45  ++i ) os<<" "<<(cnv.indexes)[i];
46  if ( cnv.numElems>maxelems ) os<<" ...";
47  for ( G4int i = ( (cnv.numElems-maxelems > 0) ? cnv.numElems-maxelems : cnv.numElems );
48  i < cnv.numElems ; ++i ) os<<" "<<(cnv.indexes)[i];
49  os<<"\n\tValues :";
50  for ( G4int i = 0 ;
51  i < ((cnv.numElems<maxelems) ? cnv.numElems : maxelems) ;
52  ++i ) os<<" "<<(cnv.values)[i];
53  if ( cnv.numElems>maxelems ) os<<" ...";
54  for ( G4int i = ( (cnv.numElems-maxelems > 0) ? cnv.numElems-maxelems : cnv.numElems );
55  i < cnv.numElems ; ++i ) os<<" "<<(cnv.values)[i];
56  return os;
57 }
58 
59 std::ostream& operator<<(std::ostream& os,
60  G4THitsMap<double>& map)
61 {
62  os<<map.GetName()<<" "<<map.GetSDname()<<" "<<map.GetSize()<<"\n";
63  for ( std::map<G4int,G4double*>::const_iterator it =
64  map.GetMap()->begin(); it != map.GetMap()->end() ;
65  ++it)
66  os<<it->first<<" "<<*(it->second)<<"\n";
67  return os;
68 }
69 
72  G4THitsMap<double>* map ) const
73 {
74  DMSG( 2 , "Converting G4THitsMap<double> "<<map<<
75  " with name "<<mapName);
76  convMap_t* converted = new convMap_t;
77  converted->name = mapName;
78  DMSG(2,converted->name);
79  converted->numElems = map->GetSize();
80  DMSG(2,converted->numElems);
81  converted->indexes = new G4int[converted->numElems];
82  converted->values = new G4double[converted->numElems];
83  std::map<G4int,double*>* mm = map->GetMap();
84  G4int counter=0;
85  for ( std::map<G4int,G4double*>::const_iterator it = mm->begin();
86  it != mm->end() ; ++it ) {
87  //DMSG(2,it->first<<" "<<*(it->second)<<" "<<counter);
88  (converted->indexes)[counter] = it->first;
89  (converted->values)[counter++] = *(it->second);
90  }
91  DMSG( 2 , "Converted to: "<<*converted );
92  return converted;
93 }
94 
95 void
97 {
98  DMSG(2,"Coverting G4VScoringMesh: "<<mesh);
99  clear();
100  const MeshScoreMap& map = mesh->GetScoreMap();
101  DMSG(2,"Converting "<<map.size()<<" score maps");
102  for ( MeshScoreMap::const_iterator it = map.begin() ;
103  it != map.end() ; ++it )
104  {
105  convertedMesh.push_back( convertMap(it->first,it->second) );
106  }
107  DMSG(2,"Conversion of G4VScoringMesh: "<<mesh<<" done");
108 }
109 
110 void
112 {
113  for ( std::vector<convMap_t*>::iterator it = convertedMesh.begin() ;
114  it != convertedMesh.end() ; ++it )
115  {
116  delete[] (*it)->indexes;
117  delete[] (*it)->values;
118  delete *it;
119  *it = 0;
120  }
121  convertedMesh.erase(convertedMesh.begin(),convertedMesh.end());
122 }
123 
124 
126 {
127  DMSG(0,"G4MPIScorerMerger::Merge() called");
128  G4int myrank = MPI::COMM_WORLD.Get_rank();
129  commSize = MPI::COMM_WORLD.Get_size();
130  COMM_G4COMMAND_ = MPI::COMM_WORLD.Dup();
131  DMSG(0,"Comm world size: "<<commSize<<" this rank is: "
132  <<myrank<<" sending to rank "<<destinationRank
133  <<" Number of mesh: "<< scoringManager->GetNumberOfMesh() );
134  for ( size_t i = 0 ; i < scoringManager->GetNumberOfMesh() ; ++i )
135  {
136  if ( myrank != destinationRank ) {
137  meshID = static_cast<G4int>(i);
138  SendOneMesh();
139  } else {
140  ReceiveOneMesh();
141  }
142  }
143  DMSG(0,"G4MPIScorerMerger::Merge done");
144 }
145 
147 {
148  DMSG(1,"Sending mesh with ID: "<<meshID);
150  convertMesh( mesh );
153  G4int numelems=convertedMesh.size();
154  DMSG(2,"Sending "<<numelems<<" maps");
155  COMM_G4COMMAND_.Send(&numelems,1,MPI::INT,
157  for ( std::vector<convMap_t*>::const_iterator it = convertedMesh.begin() ;
158  it != convertedMesh.end() ; ++it ) {
159  const convMap_t* elem = *it;
160  DMSG(2,"Sending map: "<<elem);
161  COMM_G4COMMAND_.Send(elem->name.c_str(),elem->name.length(),MPI::CHAR,
163  COMM_G4COMMAND_.Send(&(elem->numElems),1,MPI::INT,
164  destinationRank,G4MPImanager::kTAG_DATA);
165  COMM_G4COMMAND_.Send(elem->indexes,elem->numElems,MPI::INT,
166  destinationRank,G4MPImanager::kTAG_DATA);
167  COMM_G4COMMAND_.Send(elem->values,elem->numElems,MPI::DOUBLE,
168  destinationRank,G4MPImanager::kTAG_DATA);
169  }
170  DMSG(1,"Sending of mesh with ID: "<<meshID<<" Done.");
171 }
172 
174 {
175  DMSG(1,"Receiving of mesh");
176  clear();
177  for ( G4int rank = 0 ; rank<commSize; ++rank ) {
178  if ( rank == destinationRank ) continue; // Do not receive from myself
180  G4int numElems = 0;
181  COMM_G4COMMAND_.Recv(&numElems,1,MPI::INT,rank,G4MPImanager::kTAG_DATA);
182  for ( G4int i = 0 ; i<numElems ; ++i ) {
183  convMap_t* elem = new convMap_t;
184  //G4int strlen = 0;
185  MPI::Status status;
186  COMM_G4COMMAND_.Probe(rank,G4MPImanager::kTAG_DATA,status);
187  G4int strlen = status.Get_count(MPI::CHAR);
188  char* buf = new char[strlen];
189  COMM_G4COMMAND_.Recv(buf,strlen,MPI::CHAR,rank,
190  G4MPImanager::kTAG_DATA,status);
191  elem->name = G4String(buf,strlen);
192  delete[] buf;
193  COMM_G4COMMAND_.Recv(&(elem->numElems),1,MPI::INT,rank,
195  elem->indexes = new G4int[elem->numElems];
196  elem->values = new G4double[elem->numElems];
197  COMM_G4COMMAND_.Recv(elem->indexes,elem->numElems,MPI::INT,rank,
199  COMM_G4COMMAND_.Recv(elem->values,elem->numElems,MPI::DOUBLE,rank,
201  convertedMesh.push_back(elem);
202  DMSG(2,"Received one mesh map: "<<*elem);
203  }
204  DMSG(2,"Received one mesh, with "<<convertedMesh.size()<<" maps");
205  //Received from Rank number rank
206  MergeOneMesh();
207  }
208  DMSG(1,"Receiving of mesh done");
209 }
210 
212 {
213  DMSG(2,"Merging one mesh");
215  if ( ! mesh ) {
217  msg<<"Cannot find mesh with id: "<<meshID;
218  G4Exception("G4MPIScorerMerger::MergeOneMesh()","G4MPI001",FatalException,
219  msg);
220  }
221  for ( std::vector<convMap_t*>::const_iterator it = convertedMesh.begin() ;
222  it != convertedMesh.end() ; ++it )
223  {
224  //Create a hits-collection from this convMap_t object
225  const convMap_t* const elem = *it;
226  G4THitsMap<G4double> hc(mesh->GetWorldName(),elem->name);
227  for ( G4int i = 0 ; i < elem->numElems; ++i )
228  hc.set( elem->indexes[i] , elem->values[i] );
229  DMSG(3,"Original mesh: "<<*(mesh->GetScoreMap().find(elem->name)->second));
230  DMSG(3,"Received mesh: "<<hc);
231  mesh->Accumulate(&hc);
232  DMSG(3,"Original mesh after accumulation: "
233  <<*(mesh->GetScoreMap().find(elem->name)->second));
234  }
235  DMSG(2,"Merging one mesh done");
236 }
237 
std::vector< convMap_t * > convertedMesh
const G4String & GetWorldName() const
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
std::map< G4String, G4THitsMap< G4double > * > MeshScoreMap
const G4double hc
[MeV*fm]
void Accumulate(G4THitsMap< G4double > *map)
int G4int
Definition: G4Types.hh:78
virtual convMap_t * convertMap(const G4String &mapName, G4THitsMap< double > *map) const
virtual void SendOneMesh()
virtual void ReceiveOneMesh()
virtual size_t GetSize() const
Definition: G4THitsMap.hh:86
G4MPIScorerMerger(G4ScoringManager *mgr, G4int destination=G4MPImanager::kRANK_MASTER, G4int verbosity=0)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define DMSG(LVL, MSG)
virtual void MergeOneMesh()
virtual void Merge()
MPI::Intracomm COMM_G4COMMAND_
MeshScoreMap GetScoreMap() const
virtual void convertMesh(const G4VScoringMesh *mesh)
std::map< G4int, T * > * GetMap() const
Definition: G4THitsMap.hh:68
std::ostream & operator<<(std::ostream &os, const G4MPIScorerMerger::convMap_t &cnv)
static G4String Status(G4StepStatus stps)
size_t GetNumberOfMesh() const
double G4double
Definition: G4Types.hh:76
G4VScoringMesh * GetMesh(G4int i) const
static const double mm
Definition: G4SIunits.hh:102
G4ScoringManager * scoringManager