ATLAS Offline Software
Loading...
Searching...
No Matches
RNGWrapper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "CLHEP/Random/RandomEngine.h"
8#include "CxxUtils/crc64.h"
9#include "crc_combine.h"
10
15size_t ATHRNG::calculateSeedMC16(const std::string& algName, uint64_t ev, uint64_t run, uint32_t offset) {
16 uint32_t theHash = static_cast<uint32_t>(ev);
17 if (0 != offset) theHash=crc_combine(theHash, offset);
18 uint32_t runNumber = static_cast<uint32_t>(run);
19 theHash=crc_combine(theHash, runNumber);
20 theHash=crc_combine(theHash, algName);
21 return theHash;
22}
23
26size_t ATHRNG::calculateSeedMC20(const std::string& algName, uint64_t ev, uint64_t run) {
27 auto algHash = std::hash<std::string>{}(algName);
28 auto evHash = std::hash<uint64_t>{}(ev);
29 auto runHash = std::hash<uint64_t>{}(run);
30 auto hsh = evHash ^ (runHash + (evHash << 6) + (evHash >> 2));
31 hsh = hsh ^ (algHash + (hsh << 6) + (hsh >> 2));
32 return hsh;
33}
34
37void ATHRNG::calculateSeedsMC21(long* seeds, const std::string& algName, uint64_t ev, uint64_t run, uint64_t offset) {
38 //RanecuEngine only takes the first seed, so the first seed should be good on it's own
39 //using 64bit crc which is already performing quite well on it's own
40 uint64_t theHash = CxxUtils::crc64(algName);
41 theHash = CxxUtils::crc64addint(theHash,ev);
42 theHash = CxxUtils::crc64addint(theHash,offset);
43 theHash = CxxUtils::crc64addint(theHash,run);
44
45 size_t iseed=0;
46 seeds[iseed]=(long)theHash; //CLHEP takes a zero terminated array for seeding. Avoid 0
47 if(seeds[iseed]!=0) ++iseed; //if zero, make the seed vector shorter, which should in itself already cause a different seeding
48 seeds[iseed]=(long)ev; //CLHEP takes a zero terminated array for seeding. Avoid ev==0
49 if(seeds[iseed]!=0) ++iseed; //Avoid 0
50 seeds[iseed]=(long)(ev >> 32); //explicitly split out the upper 32bit as dSFMTEngine only takes 32bits.
51 if(seeds[iseed]!=0) ++iseed; //Avoid 0
52 seeds[iseed]=(long)run;
53 if(seeds[iseed]!=0) ++iseed; //Avoid 0
54 uint64_t algHash = CxxUtils::MurmurHash64A ( algName.data(), algName.size(), 0 );
55 seeds[iseed]=(long)algHash;
56 if(seeds[iseed]!=0) ++iseed; //Avoid 0
57 seeds[iseed]=(long)offset;
58 if(seeds[iseed]!=0) ++iseed; //Avoid 0
59 seeds[iseed]=0; //CLHEP takes a zero terminated array for seeding, so end with 0
60 return;
61}
62
63long ATHRNG::calculateSeedsPython(const std::string& algName, uint64_t ev, uint64_t run, uint64_t offset) {
64 long seeds[7];
65 calculateSeedsMC21(seeds, algName, ev, run, offset);
66 return seeds[0];
67}
68
69ATHRNG::RNGWrapper::RNGWrapper(const factoryFunc& genFact, size_t nSlots)
70{
71 // Construct the random engines; one per event slot.
72 m_engines.reserve(nSlots);
73 for(size_t t = 0; t < nSlots; t++){
74 m_engines.emplace_back(genFact());
75 }
76 m_evtSeeded.resize (nSlots, EventContext::INVALID_CONTEXT_EVT);
77}
78
80{
81 // Clean up the allocated engines
82 for(auto engPtr : m_engines) {
83 delete engPtr;
84 }
85}
86
87void ATHRNG::RNGWrapper::setSeedMC20(const std::string& algName, size_t slot,
88 uint64_t ev, uint64_t run,
89 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
90{
91 auto hsh = calculateSeedMC20(algName, ev, run);
92 setSeed(slot, hsh, evt);
93}
94
95void ATHRNG::RNGWrapper::setSeedMC21(const std::string& algName, size_t slot,
96 uint64_t ev, uint64_t run, uint64_t offset,
97 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
98{
99 long seeds[7]; //CLHEP uses long for seeding
100 calculateSeedsMC21(seeds, algName, ev, run, offset);
101 setSeeds(slot, seeds, evt);
102}
103
104void ATHRNG::RNGWrapper::setSeedLegacy(const std::string& algName, size_t slot,
105 uint64_t ev, uint64_t run, uint64_t offset, SeedingOptionType seeding,
106 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
107{
108 if(seeding==MC16Seeding) {
109 // Use MC16 legacy seeding
110 setSeedMC16(algName, slot, ev, run, offset, evt);
111 return;
112 }
113 if(seeding==MC20Seeding) {
114 // Use MC20 seeding
115 setSeedMC20(algName, slot, ev, run, evt);
116 return;
117 }
118 // Use MC21 seeding
119 setSeedMC21(algName, slot, ev, run, offset, evt);
120}
121
122void ATHRNG::RNGWrapper::setSeedMC16(const std::string& algName, size_t slot, uint64_t ev, uint64_t run, uint32_t offset,
123 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
124{
125 uint32_t theHash = calculateSeedMC16(algName, ev, run, offset);
126 setSeed(slot, theHash, evt);
127}
128
129void ATHRNG::RNGWrapper::setSeed(size_t slot, size_t seed,
130 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
131{
132 m_engines[slot]->setSeed(seed, 0);
133 if (evt == EventContext::INVALID_CONTEXT_EVT) {
134 evt = Gaudi::Hive::currentContext().evt();
135 }
136 m_evtSeeded[slot] = evt;
137}
138
139void ATHRNG::RNGWrapper::setSeeds(size_t slot, const long * seeds,
140 EventContext::ContextEvt_t evt /*= EventContext::INVALID_CONTEXT_EVT*/)
141{
142 m_engines[slot]->setSeeds(seeds, 0);
143 if (evt == EventContext::INVALID_CONTEXT_EVT) {
144 evt = Gaudi::Hive::currentContext().evt();
145 }
146 m_evtSeeded[slot] = evt;
147}
uint32_t crc_combine(uint32_t seed, uint32_t v)
using crc32 for architecture independence in combining the seeds
Implementation of MurmurHash2.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
void setSeedMC20(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
std::function< CLHEP::HepRandomEngine *(void)> factoryFunc
Definition RNGWrapper.h:58
RNGWrapper(const factoryFunc &genFact, size_t nSlots)
Constructor takes a factory function which can instantiate a CLHEP::HepRandomEngine and the number of...
std::vector< EventContext::ContextEvt_t > m_evtSeeded
Event counter when the engine was last seeded.
Definition RNGWrapper.h:156
void setSeeds(size_t slot, const long *seeds, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the seed value(s) directly for a specified slot.
void setSeedMC21(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, uint64_t offset=0, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
std::vector< CLHEP::HepRandomEngine * > m_engines
Vector of random engines, ordered by slot number.
Definition RNGWrapper.h:153
void setSeedMC16(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, uint32_t offset=0, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
SeedingOptionType
Options for seeding option=0 is setSeed as in MC20 option=1 is setSeedLegacy as in MC16 option=2 is s...
Definition RNGWrapper.h:97
void setSeedLegacy(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, uint64_t offset, SeedingOptionType seeding, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
A crc-64 implementation, using pclmul where possible.
int ev
Definition globals.cxx:25
size_t calculateSeedMC20(const std::string &algName, uint64_t ev, uint64_t run)
Set the random seed using a string (e.g.
void calculateSeedsMC21(long *seeds, const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
Set the random seed using a string (e.g.
long calculateSeedsPython(const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
size_t calculateSeedMC16(const std::string &algName, uint64_t ev, uint64_t run, uint32_t offset=0)
Helper methods.
uint64_t crc64(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string,.
Definition crc64.cxx:696
uint64_t MurmurHash64A(const void *key, int len, uint64_t seed)
uint64_t crc64addint(uint64_t crc, uint64_t x)
Extend a previously-calculated CRC to include an int.
Definition crc64.cxx:732
Definition run.py:1