ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4FastPathHadronicCrossSection.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4FastPathHadronicCrossSection.hh
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