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