Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4FastPathHadronicCrossSection.hh
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 #ifndef G4FastPathHadronicCrossSection_hh
27 #define G4FastPathHadronicCrossSection_hh
28 
29 #include "G4PhysicsFreeVector.hh"
30 #include "G4ParticleDefinition.hh"
31 #include "G4Material.hh"
32 #include <functional>
33 #include <utility>
34 #include <unordered_map>
35 #include <iostream>
36 #include <set>
37 #include <stdint.h>
38 
39 class G4DynamicParticle;
40 class G4Material;
42 
43 //To measure performances and debug info on fast cross-section enable this
44 //#define FPDEBUG
45 
46 //TODO: Move all logging and debug functionality to separate header
47 namespace G4FastPathHadronicCrossSection {
48  //This data type contains the simplified representation of the
49  //cross-section, by default it is a G4PhysicsVector type
51  //The key used to search in the cache.
52  using G4CrossSectionDataStore_Key=std::pair<const G4ParticleDefinition*,const G4Material*>;
53  //This represents the fast XS implementation.
54  struct fastPathEntry{
55  //fastPathEntry();
58  inline G4double GetCrossSection(G4double ene) const { return physicsVector->Value(ene); }
61  const G4Material * const material;
63 
65 # ifdef FPDEBUG
66  //stats for debug
67  G4int count;
68  G4double slowpath_sum; //sum of all slowpath xs
69  G4double max_delta;
70  G4double min_delta;
71  G4double sum_delta;
72  G4double sum_delta_square;
73 # endif
74  };
75 
76  //A cache entry.
78  cycleCountEntry(const G4String& pname , const G4Material* mat);
81  const G4Material * const material;
82 
83  //optional fastPathEntry
85 
86  //cache per element of material test
89 # ifdef FPDEBUG
90  uint64_t cacheHitCount;//
91  uint64_t initCyclesFastPath;
92  uint64_t invocationCountSlowPath;
93  uint64_t totalCyclesSlowPath;
94  uint64_t invocationCountFastPath;
95  uint64_t totalCyclesFastPath;
96  uint64_t invocationCountTriedOneLineCache;//
97  uint64_t invocationCountOneLineCache;//
98 # endif
99  };
100 
101  struct timing {
102  unsigned long long rdtsc_start;
103  unsigned long long rdtsc_stop;
104  };
105 
108  inline void MethodCalled();
109  inline void HitOneLine();
110  inline void FastPath();
111  inline void SlowPath();
112  inline void SampleZandA();
113 #ifdef FPDEBUG
114  uint64_t methodCalled;
115  uint64_t hitOneLineCache;
116  uint64_t fastPath;
117  uint64_t slowPath;
118  uint64_t sampleZandA;
119 #endif
120  };
121 
122  //Hashing the key
124  std::hash<uint64_t> hash_uint64_t;
125  inline size_t operator()(const G4CrossSectionDataStore_Key& x) const throw() {
126  return hash_uint64_t(hash_uint64_t( ((uint64_t)(x.first)) ) + hash_uint64_t(((uint64_t)(x.second))));
127  }
128  };
129  //Equality for two key elements
131  inline bool operator()(const G4CrossSectionDataStore_Key& lhs, const G4CrossSectionDataStore_Key& rhs ) const {
132  //TODO: Verify this: particles are singletons, materials use operator==
133  //TODO: in ref-10, G4Material::operator== becomes deleted, investigating why
134  return (lhs.first==rhs.first)&&(lhs.second == rhs.second);
135  }
136  };
137 // The cache itself
138  using G4CrossSectionDataStore_Cache=std::unordered_map<G4CrossSectionDataStore_Key,cycleCountEntry*,
140 
144  };
145  //Two of the elements are identical if the part_mat part is
147  std::less<G4CrossSectionDataStore_Key> less;
148  inline bool operator()(const fastPathRequestConfig_t& lhs,const fastPathRequestConfig_t& rhs ) const {
149  return less(lhs.part_mat,rhs.part_mat);
150  }
151  };
152  using G4CrossSectionDataStore_Requests=std::set<fastPathRequestConfig_t,fastPathRequestConfig_Less>;
153 
154  //Configure the caching mechanism
155  struct controlFlag {
160  };
161  //Parameters to control sampling
164  //default
165  //TODO: are these ok?
166  queryMax = 10000;
167  sampleMin = 0.0001;
168  sampleMax = 10000;
169  sampleCount = 200000;
170  dpTol = 0.01;
171  }
172  //PRUTH vars for sampling and surragate model
178  };
179 
180  //Logging functionalities, disabled if not in FPDEBUG mode
181  static inline void logInvocationTriedOneLine( cycleCountEntry* );
182  static inline void logInvocationOneLine( cycleCountEntry* );
183  static inline void logHit(cycleCountEntry*);
184  static inline void logInvocationCountFastPath( cycleCountEntry* );
185  static inline void logInvocationCountSlowPAth( cycleCountEntry* );
186 #ifdef FPDEBUG
187  void logStartCountCycles( timing& );
188  void logStopCountCycles( timing& );
189 #else
190  inline void logStartCountCycles(timing&) {}
191  inline void logStopCountCycles(timing&) {}
192 #endif
193  static inline void logInitCyclesFastPath( cycleCountEntry* , timing& );
194  static inline void logTotalCyclesFastPath( cycleCountEntry* , timing& );
195  static inline void logTotalCyclesSlowPath( cycleCountEntry* , timing& );
196  static inline void logTiming( cycleCountEntry* , fastPathEntry* , timing& );
197 }
198 
199 inline std::ostream& operator<<(std::ostream& os, const G4FastPathHadronicCrossSection::fastPathEntry& fp);
200 
201 //Implementation of inline functions. Note the ifdef
202 
203 namespace G4FastPathHadronicCrossSection {
204 
205 #ifdef FPDEBUG
206 inline void logInvocationTriedOneLine(cycleCountEntry* cl ) {
207  if ( cl != nullptr ) ++(cl->invocationCountTriedOneLineCache);
208 }
209 inline void logInvocationOneLine( cycleCountEntry* cl ) {
210  if ( cl != nullptr ) ++(cl->invocationCountOneLineCache);
211 }
212 inline void logHit(cycleCountEntry* cl) {
213  if ( cl != nullptr ) ++(cl->cacheHitCount);
214 }
215 inline void logInvocationCountFastPath( cycleCountEntry* cl )
216 {
217  if ( cl != nullptr ) ++(cl->invocationCountFastPath);
218 }
219 inline void logInvocationCountSlowPAth( cycleCountEntry* cl)
220 {
221  if ( cl != nullptr ) ++(cl->invocationCountSlowPath);
222 }
223 
224 inline void logInitCyclesFastPath(cycleCountEntry* cl,timing& tm)
225 {
226  if ( cl != nullptr ) cl->initCyclesFastPath = tm.rdtsc_stop - tm.rdtsc_start;
227 }
228 inline void logTotalCyclesFastPath( cycleCountEntry* cl,timing& tm)
229 {
230  if ( cl!=nullptr ) cl->totalCyclesFastPath = tm.rdtsc_stop - tm.rdtsc_start;
231 }
232 inline void logTotalCyclesSlowPath( cycleCountEntry* cl,timing& tm)
233 {
234  if ( cl!=nullptr ) cl->totalCyclesSlowPath = tm.rdtsc_stop - tm.rdtsc_start;
235 }
236 inline void logTiming( cycleCountEntry* entry , fastPathEntry* fast_entry, timing& timing)
237 {
238  if (fast_entry != nullptr ) {
239  if ( entry->invocationCountFastPath == 0 ) {
240  //PRUTH style initialization
243  } else {
244  //PRUTH comment to understand:
245  //the first one includes the initialization... don't count it for now
248  }
249  } else {
252  }
253 }
254 #else
257 inline void logHit(cycleCountEntry*){}
260 inline void logInitCyclesFastPath( cycleCountEntry* , timing& ){}
261 inline void logTotalCyclesFastPath( cycleCountEntry* , timing& ){}
262 inline void logTotalCyclesSlowPath( cycleCountEntry* , timing& ){}
263 inline void logTiming( cycleCountEntry* , fastPathEntry* , timing& ) {}
264 #endif
265 
267 #ifdef FPDEBUG
268  ++methodCalled;
269 #endif
270 }
271 
273 #ifdef FPDEBUG
274  ++hitOneLineCache;
275 #endif
276 }
277 
279 #ifdef FPDEBUG
280  ++fastPath;
281 #endif
282 }
283 
285 #ifdef FPDEBUG
286  ++slowPath;
287 #endif
288 }
289 
291 #ifdef FPDEBUG
292  ++sampleZandA;
293 #endif
294 }
295 }//namespace
296 
297 inline std::ostream& operator<<(std::ostream& os, const G4FastPathHadronicCrossSection::fastPathEntry& fp) {
298  using CLHEP::MeV;
299  os<<"#Particle: "<<(fp.particle!=nullptr?fp.particle->GetParticleName():"UNDEFINED")<<"\n";
300  os<<"#Material: "<<(fp.material!=nullptr?fp.material->GetName():"UNDEFINED")<<"\n";
301  os<<"#min_cutoff(MeV): "<<fp.min_cutoff/MeV<<"\n";
302 #ifdef FPDEBUG
303  os<<"#DEBUG COUNTERS: count="<<fp.count<<" slowpath_sum="<<fp.slowpath_sum<<" max_delta="<<fp.max_delta;
304  os<<" min_delta="<<fp.min_delta<<" sum_delta="<<fp.sum_delta<<" sum_delta_square="<<fp.sum_delta_square<<"\n";
305 #endif
306  os<<*(fp.physicsVector)<<"\n";
307  return os;
308 }
309 
310 #endif //G4FastPathHadronicCrossSection_hh
static void logTotalCyclesSlowPath(cycleCountEntry *, timing &)
bool operator()(const fastPathRequestConfig_t &lhs, const fastPathRequestConfig_t &rhs) const
fastPathEntry(const G4ParticleDefinition *par, const G4Material *mat, G4double min_cutoff)
void Initialize(G4CrossSectionDataStore *)
static void logTiming(cycleCountEntry *, fastPathEntry *, timing &)
const G4String & particle
XSParam * physicsVector
const G4String & GetName() const
Definition: G4Material.hh:178
~fastPathEntry()
const G4ParticleDefinition *const particle
tuple x
Definition: test.py:50
G4double energy
G4double GetCrossSection(G4double ene) const
const G4double min_cutoff
static void logInvocationCountFastPath(cycleCountEntry *)
const G4Material *const material
int G4int
Definition: G4Types.hh:78
const G4Material *const material
const G4String & GetParticleName() const
std::set< fastPathRequestConfig_t, fastPathRequestConfig_Less > G4CrossSectionDataStore_Requests
std::unordered_map< G4CrossSectionDataStore_Key, cycleCountEntry *, G4CrossSectionDataStore_Key_Hash, G4CrossSectionDataStore_Key_EqualTo > G4CrossSectionDataStore_Cache
static void logInvocationCountSlowPAth(cycleCountEntry *)
static void logInitCyclesFastPath(cycleCountEntry *, timing &)
std::pair< const G4ParticleDefinition *, const G4Material * > G4CrossSectionDataStore_Key
static void logInvocationOneLine(cycleCountEntry *)
cycleCountEntry(const G4String &pname, const G4Material *mat)
bool G4bool
Definition: G4Types.hh:79
static constexpr double MeV
G4double Value(G4double theEnergy, size_t &lastidx) const
string pname
Definition: eplot.py:33
fastPathEntry * fastPath
bool operator()(const G4CrossSectionDataStore_Key &lhs, const G4CrossSectionDataStore_Key &rhs) const
static void logTotalCyclesFastPath(cycleCountEntry *, timing &)
G4double crossSection
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
static constexpr double MeV
Definition: G4SIunits.hh:214
static void logInvocationTriedOneLine(cycleCountEntry *)
~cycleCountEntry()
double G4double
Definition: G4Types.hh:76