|
||||
File indexing completed on 2025-01-18 09:14:19
0001 //========================================================================== 0002 // AIDA Detector description implementation 0003 //-------------------------------------------------------------------------- 0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) 0005 // All rights reserved. 0006 // 0007 // For the licensing terms see $DD4hepINSTALL/LICENSE. 0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS. 0009 // 0010 // Author : A.Sailer 0011 // 0012 //========================================================================== 0013 #ifndef DDG4_PLUGINS_GEANT4EVENTSEED_H 0014 #define DDG4_PLUGINS_GEANT4EVENTSEED_H 0015 0016 // Framework include files 0017 #include <DDG4/Geant4RunAction.h> 0018 0019 // fallthrough only exists from c++17 0020 #if defined __has_cpp_attribute 0021 #if __has_cpp_attribute(fallthrough) 0022 #define ATTR_FALLTHROUGH [[fallthrough]] 0023 #else 0024 #define ATTR_FALLTHROUGH 0025 #endif 0026 #else 0027 #define ATTR_FALLTHROUGH 0028 #endif 0029 0030 0031 /// Namespace for the AIDA detector description toolkit 0032 namespace dd4hep { 0033 0034 /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit 0035 namespace sim { 0036 0037 /** 0038 * \addtogroup Geant4RunActions 0039 * @{ 0040 * \package EventSeed 0041 * \brief Set the event seed for each event 0042 * 0043 * This plugins allows one to skip events and still be reproducible. 0044 * We are using jenkins_hash from an intial seed, runID and eventID 0045 * see http://burtleburtle.net/bob/hash/evahash.html 0046 * 0047 * \author A.Sailer 0048 * \version 1.0 0049 * \ingroup DD4HEP_SIMULATION 0050 * @} 0051 */ 0052 /// Plugin class to set the event seed for each event 0053 class Geant4EventSeed: public Geant4RunAction { 0054 0055 protected: 0056 unsigned int m_initialSeed; 0057 unsigned int m_runID; 0058 std::string m_type; 0059 bool m_initialised; 0060 public: 0061 /// Standard constructor with initializing arguments 0062 Geant4EventSeed(Geant4Context*, const std::string& ); 0063 /// Default destructor 0064 virtual ~Geant4EventSeed(); 0065 /// begin-of-run callback 0066 void begin(const G4Run*); 0067 /// begin-of-event callback 0068 void beginEvent(const G4Event*); 0069 }; 0070 0071 /* 0072 0073 Hashing for random seed as used in Marlin EventSeeder processor 0074 0075 Original source by Bob Jenkins 0076 0077 http://www.burtleburtle.net/bob/hash/doobs.html 0078 0079 Hash a variable-length key into a 32-bit value 0080 0081 */ 0082 0083 #define hashsize(n) ( 1U << (n) ) 0084 #define hashmask(n) ( hashsize ( n ) - 1 ) 0085 0086 0087 /* 0088 -------------------------------------------------------------------- 0089 mix -- mix 3 32-bit values reversibly. 0090 For every delta with one or two bits set, and the deltas of all three 0091 high bits or all three low bits, whether the original value of a,b,c 0092 is almost all zero or is uniformly distributed, 0093 * If mix() is run forward or backward, at least 32 bits in a,b,c 0094 have at least 1/4 probability of changing. 0095 * If mix() is run forward, every bit of c will change between 1/3 and 0096 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) 0097 mix() was built out of 36 single-cycle latency instructions in a 0098 structure that could supported 2x parallelism, like so: 0099 a -= b; 0100 a -= c; x = (c>>13); 0101 b -= c; a ^= x; 0102 b -= a; x = (a<<8); 0103 c -= a; b ^= x; 0104 c -= b; x = (b>>13); 0105 ... 0106 Unfortunately, superscalar Pentiums and Sparcs can't take advantage 0107 of that parallelism. They've also turned some of those single-cycle 0108 latency instructions into multi-cycle latency instructions. Still, 0109 this is the fastest good hash I could find. There were about 2^^68 0110 to choose from. I only looked at a billion or so. 0111 -------------------------------------------------------------------- 0112 */ 0113 #define mix(a,b,c) \ 0114 { \ 0115 a -= b; a -= c; a ^= (c>>13); \ 0116 b -= c; b -= a; b ^= (a<<8); \ 0117 c -= a; c -= b; c ^= (b>>13); \ 0118 a -= b; a -= c; a ^= (c>>12); \ 0119 b -= c; b -= a; b ^= (a<<16); \ 0120 c -= a; c -= b; c ^= (b>>5); \ 0121 a -= b; a -= c; a ^= (c>>3); \ 0122 b -= c; b -= a; b ^= (a<<10); \ 0123 c -= a; c -= b; c ^= (b>>15); \ 0124 } 0125 0126 /* 0127 -------------------------------------------------------------------- 0128 jenkins_hash() -- hash a variable-length key into a 32-bit value 0129 k : the key (the unaligned variable-length array of bytes) 0130 len : the length of the key, counting by bytes 0131 initval : can be any 4-byte value 0132 Returns a 32-bit value. Every bit of the key affects every bit of 0133 the return value. Every 1-bit and 2-bit delta achieves avalanche. 0134 About 6*len+35 instructions. 0135 0136 The best hash table sizes are powers of 2. There is no need to do 0137 mod a prime (mod is sooo slow!). If you need less than 32 bits, 0138 use a bitmask. For example, if you need only 10 bits, do 0139 h = (h & hashmask(10)); 0140 In which case, the hash table should have hashsize(10) elements. 0141 0142 If you are hashing n strings (ub1 **)k, do it like this: 0143 for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h); 0144 0145 By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this 0146 code any way you wish, private, educational, or commercial. It's free. 0147 0148 See http://burtleburtle.net/bob/hash/evahash.html 0149 Use for hash table lookup, or anything where one collision in 2^^32 is 0150 acceptable. Do NOT use for cryptographic purposes. 0151 -------------------------------------------------------------------- 0152 */ 0153 unsigned jenkins_hash ( unsigned char *k, unsigned length, unsigned initval ) 0154 { 0155 unsigned a, b; 0156 unsigned c = initval; 0157 unsigned len = length; 0158 0159 a = b = 0x9e3779b9; 0160 0161 while ( len >= 12 ) { 0162 a += ( k[0] + ( (unsigned)k[1] << 8 ) 0163 + ( (unsigned)k[2] << 16 ) 0164 + ( (unsigned)k[3] << 24 ) ); 0165 b += ( k[4] + ( (unsigned)k[5] << 8 ) 0166 + ( (unsigned)k[6] << 16 ) 0167 + ( (unsigned)k[7] << 24 ) ); 0168 c += ( k[8] + ( (unsigned)k[9] << 8 ) 0169 + ( (unsigned)k[10] << 16 ) 0170 + ( (unsigned)k[11] << 24 ) ); 0171 0172 mix ( a, b, c ); 0173 0174 k += 12; 0175 len -= 12; 0176 } 0177 0178 c += length; 0179 0180 switch ( len ) { 0181 case 11: c += ( (unsigned)k[10] << 24 ); ATTR_FALLTHROUGH; 0182 case 10: c += ( (unsigned)k[9] << 16 ); ATTR_FALLTHROUGH; 0183 case 9 : c += ( (unsigned)k[8] << 8 ); ATTR_FALLTHROUGH; 0184 /* First byte of c reserved for length */ 0185 case 8 : b += ( (unsigned)k[7] << 24 ); ATTR_FALLTHROUGH; 0186 case 7 : b += ( (unsigned)k[6] << 16 ); ATTR_FALLTHROUGH; 0187 case 6 : b += ( (unsigned)k[5] << 8 ); ATTR_FALLTHROUGH; 0188 case 5 : b += k[4]; ATTR_FALLTHROUGH; 0189 case 4 : a += ( (unsigned)k[3] << 24 ); ATTR_FALLTHROUGH; 0190 case 3 : a += ( (unsigned)k[2] << 16 ); ATTR_FALLTHROUGH; 0191 case 2 : a += ( (unsigned)k[1] << 8 ); ATTR_FALLTHROUGH; 0192 case 1 : a += k[0]; 0193 } 0194 0195 mix ( a, b, c ); 0196 0197 return c; 0198 } 0199 0200 /// calculate hash from initialSeed, eventID and runID 0201 unsigned int hash( unsigned int initialSeed, unsigned int eventNumber, unsigned int runNumber ){ 0202 unsigned int seed = 0; 0203 unsigned char * c = (unsigned char *) &eventNumber ; 0204 seed = jenkins_hash( c, sizeof eventNumber, seed) ; 0205 0206 c = (unsigned char *) &runNumber ; 0207 seed = jenkins_hash( c, sizeof runNumber, seed) ; 0208 0209 c = (unsigned char *) &initialSeed ; 0210 seed = jenkins_hash( c, sizeof initialSeed, seed) ; 0211 0212 return seed; 0213 } 0214 0215 } // End namespace sim 0216 } // End namespace dd4hep 0217 0218 #endif // DDG4_PLUGINS_GEANT4EVENTSEED_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |