CMS 3D CMS Logo

RandomNumberGeneratorService.h
Go to the documentation of this file.
1 #ifndef IOMC_RandomEngine_RandomNumberGeneratorService_h
2 #define IOMC_RandomEngine_RandomNumberGeneratorService_h
3 
17 
18 #include <atomic>
19 #include <cstdint>
20 #include <fstream>
21 #include <iosfwd>
22 #include <istream>
23 #include <limits>
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 class RandomEngineState;
30 
31 namespace CLHEP {
32  class HepRandomEngine;
33 }
34 
35 namespace edm {
36  class ActivityRegistry;
38  class ConsumesCollector;
39  class Event;
40  class LuminosityBlock;
41  class LuminosityBlockIndex;
42  class ModuleCallingContext;
43  class ModuleDescription;
44  class ParameterSet;
45  class StreamContext;
46  class StreamID;
47 
48  namespace service {
49 
50  class SystemBounds;
51 
53 
54  public:
55 
57  ~RandomNumberGeneratorService() override;
58 
61 
63  CLHEP::HepRandomEngine& getEngine(StreamID const& streamID) override;
64 
66  CLHEP::HepRandomEngine& getEngine(LuminosityBlockIndex const& luminosityBlockIndex) override;
67 
68  // This returns the seed from the configuration. In the unusual case where an
69  // an engine type takes multiple seeds to initialize a sequence, this function
70  // only returns the first. As a general rule, this function should not be used,
71  // but is available for backward compatibility and debugging. It might be useful
72  // for some types of tests. Using this to seed engines constructed in modules is
73  // not recommended because (unless done very carefully) it will create duplicate
74  // sequences in different threads and/or data races. Also, if engines are created
75  // by modules the replay mechanism will be broken.
76  // Because it is dangerous and could be misused, this function might be deleted
77  // someday if we ever find time to delete all uses of it in CMSSW. There are of
78  // order 10 last time I checked ...
79  std::uint32_t mySeed() const override;
80 
81  static void fillDescriptions(ConfigurationDescriptions& descriptions);
82 
83  void preModuleConstruction(ModuleDescription const& description);
84  void preallocate(SystemBounds const&);
85 
86  void preBeginLumi(LuminosityBlock const& lumi) override;
87  void postEventRead(Event const& event) override;
88 
91  void preModuleBeginStream(StreamContext const& sc, ModuleCallingContext const& mcc);
92  void postModuleBeginStream(StreamContext const& sc, ModuleCallingContext const& mcc);
93 
94  void preModuleEndStream(StreamContext const& sc, ModuleCallingContext const& mcc);
95  void postModuleEndStream(StreamContext const& sc, ModuleCallingContext const& mcc);
96 
97  void preModuleStreamBeginRun(StreamContext const& sc, ModuleCallingContext const& mcc);
98  void postModuleStreamBeginRun(StreamContext const& sc, ModuleCallingContext const& mcc);
99 
100  void preModuleStreamEndRun(StreamContext const& sc, ModuleCallingContext const& mcc);
101  void postModuleStreamEndRun(StreamContext const& sc, ModuleCallingContext const& mcc);
102 
103  void preModuleStreamBeginLumi(StreamContext const& sc, ModuleCallingContext const& mcc);
104  void postModuleStreamBeginLumi(StreamContext const& sc, ModuleCallingContext const& mcc);
105 
106  void preModuleStreamEndLumi(StreamContext const& sc, ModuleCallingContext const& mcc);
107  void postModuleStreamEndLumi(StreamContext const& sc, ModuleCallingContext const& mcc);
108 
110  std::vector<RandomEngineState> const& getLumiCache(LuminosityBlockIndex const&) const override;
111  std::vector<RandomEngineState> const& getEventCache(StreamID const&) const override;
112 
113  void consumes(ConsumesCollector&& iC) const override;
114 
116  void print(std::ostream& os) const override;
117 
118  private:
119 
120  typedef std::vector<std::uint32_t> VUint32;
121 
123  public:
124  LabelAndEngine(std::string const& theLabel, VUint32 const& theSeeds, std::shared_ptr<CLHEP::HepRandomEngine> const& theEngine) :
125  label_(theLabel), seeds_(theSeeds), engine_(theEngine) { }
126  std::string const& label() const { return label_; }
127  VUint32 const& seeds() const { return seeds_; }
128  std::shared_ptr<CLHEP::HepRandomEngine const> engine() const { return get_underlying_safe(engine_); }
129  std::shared_ptr<CLHEP::HepRandomEngine>& engine() { return get_underlying_safe(engine_); }
130  void setSeed(std::uint32_t v, unsigned int index) { seeds_.at(index) = v; }
131  private:
133  VUint32 seeds_;
135  };
136 
137  // This class exists because it is faster to lookup a module using
138  // the moduleID (an integer) than the label (a string). There is a
139  // one to one association between LabelAndEngine objects and ModuleIDToEngine objects.
141  public:
142  ModuleIDToEngine(LabelAndEngine* theLabelAndEngine, unsigned int theModuleID) :
143  engineState_(), labelAndEngine_(theLabelAndEngine), moduleID_(theModuleID) { }
144 
145  std::vector<unsigned long> const& engineState() const { return engineState_; }
146  LabelAndEngine const* labelAndEngine() const { return get_underlying_safe(labelAndEngine_); }
147  LabelAndEngine*& labelAndEngine() { return get_underlying_safe(labelAndEngine_); }
148  unsigned int moduleID() const { return moduleID_; }
149  void setEngineState(std::vector<unsigned long> const& v) { engineState_ = v; }
150  // Used to sort so binary lookup can be used on a container of these.
151  bool operator<(ModuleIDToEngine const& r) const { return moduleID() < r.moduleID(); }
152  private:
153  std::vector<unsigned long> engineState_; // Used only for check in stream transitions
155  unsigned int moduleID_;
156  };
157 
159  RandomNumberGeneratorService const& operator=(RandomNumberGeneratorService const&) = delete;
160 
161  void preModuleStreamCheck(StreamContext const& sc, ModuleCallingContext const& mcc);
162  void postModuleStreamCheck(StreamContext const& sc, ModuleCallingContext const& mcc);
163 
164  void readFromLuminosityBlock(LuminosityBlock const& lumi);
165  void readFromEvent(Event const& event);
166 
167  void snapShot(std::vector<LabelAndEngine> const& engines, std::vector<RandomEngineState>& cache);
168  void restoreFromCache(std::vector<RandomEngineState> const& cache,
169  std::vector<LabelAndEngine>& engines);
170 
171  void checkEngineType(std::string const& typeFromConfig,
172  std::string const& typeFromEvent,
173  std::string const& engineLabel) const;
174 
175  void saveStatesToFile(std::string const& fileName,
176  StreamID const& streamID,
177  LuminosityBlockIndex const& lumiIndex);
178  void writeStates(std::vector<RandomEngineState> const& v,
179  std::ofstream& outFile);
180  void writeVector(VUint32 const& v,
181  std::ofstream& outFile);
182  std::string constructSaveFileName() const;
183 
184  void readEventStatesFromTextFile(std::string const& fileName,
185  std::vector<RandomEngineState>& cache);
186  void readLumiStatesFromTextFile(std::string const& fileName,
187  std::vector<RandomEngineState>& cache);
188  void readStatesFromFile(std::string const& fileName,
189  std::vector<RandomEngineState>& cache,
190  std::string const& whichStates);
191  bool readEngineState(std::istream& is,
192  std::vector<RandomEngineState>& cache,
193  std::string const& whichStates,
194  bool& saveToCache);
195  void readVector(std::istream& is, unsigned numItems, std::vector<std::uint32_t>& v);
196 
197  void createEnginesInVector(std::vector<LabelAndEngine>& engines,
198  unsigned int seedOffset,
199  unsigned int eventSeedOffset,
200  std::vector<ModuleIDToEngine>& moduleIDVector);
201 
202  void resetEngineSeeds(LabelAndEngine& labelAndEngine,
203  std::string const& engineName,
204  VUint32 const& seeds,
205  std::uint32_t offset1,
206  std::uint32_t offset2);
207 
208  // ---------- member data --------------------------------
209 
210  unsigned int nStreams_;
211 
212  // This exists because we can look things up faster using the moduleID
213  // than using string comparisons with the moduleLabel
214  std::vector<std::vector<ModuleIDToEngine> > streamModuleIDToEngine_; // streamID, sorted by moduleID
215  std::vector<std::vector<ModuleIDToEngine> > lumiModuleIDToEngine_; // luminosityBlockIndex, sortedByModuleID
216 
217  // Holds the engines, plus the seeds and module label also
218  std::vector<std::vector<LabelAndEngine> > streamEngines_; // streamID, sorted by label
219  std::vector<std::vector<LabelAndEngine> > lumiEngines_; // luminosityBlockIndex, sorted by label
220 
221  // These hold the input tags needed to retrieve the states
222  // of the random number engines stored in a previous process.
223  // If the label in the tag is the empty string (the default),
224  // then the service does not try to restore the random numbers.
227 
228  std::vector<std::vector<RandomEngineState> > eventCache_; // streamID, sorted by module label
229  std::vector<std::vector<RandomEngineState> > lumiCache_; // luminosityBlockIndex, sorted by module label
230 
231  // This is used to keep track of the seeds and engine name from
232  // the configuration. The map key is the module label.
233  // The module ID is filled in as modules are constructed.
234  // It is left as max unsigned if the module is never constructed and not in the process
235  class SeedsAndName {
236  public:
237  SeedsAndName(VUint32 const& theSeeds, std::string const& theEngineName) :
238  seeds_(theSeeds), engineName_(theEngineName), moduleID_(std::numeric_limits<unsigned int>::max()) { }
239  VUint32 const& seeds() const { return seeds_; }
240  std::string const& engineName() const { return engineName_; }
241  unsigned int moduleID() const { return moduleID_; }
242  void setModuleID(unsigned int v) { moduleID_ = v; }
243  private:
244  VUint32 seeds_;
246  unsigned int moduleID_;
247  };
248  std::map<std::string, SeedsAndName> seedsAndNameMap_;
249 
250  // Keep the name of the file where we want to save the state
251  // of all declared engines at the end of each event. A blank
252  // name means don't bother. Also, keep a record of whether
253  // the save file name has been recorded in the job report.
255  std::atomic<bool> saveFileNameRecorded_;
256  std::vector<edm::propagate_const<std::shared_ptr<std::ofstream>>> outFiles_; // streamID
257 
258  // Keep the name of the file from which we restore the state
259  // of all declared engines at the beginning of a run. A
260  // blank name means there isn't one.
262 
263  // This turns on or off the checks that ensure no random
264  // numbers are generated in a module during stream
265  // beginStream, beginRun, endLuminosityBlock, or endRun.
267 
268  std::uint32_t eventSeedOffset_;
269 
270  bool verbose_;
271 
274  static const std::uint32_t maxSeedRanecu;
275  static const std::uint32_t maxSeedHepJames;
276  static const std::uint32_t maxSeedTRandom3;
277  };
278  }
279 }
280 #endif
std::shared_ptr< CLHEP::HepRandomEngine const > engine() const
ModuleIDToEngine(LabelAndEngine *theLabelAndEngine, unsigned int theModuleID)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
uint16_t size_type
void writeVector(std::ostream &os, int indentation, std::vector< T > const &value_, ValueFormat format)
std::vector< std::vector< ModuleIDToEngine > > streamModuleIDToEngine_
std::vector< edm::propagate_const< std::shared_ptr< std::ofstream > > > outFiles_
edm::propagate_const< std::shared_ptr< CLHEP::HepRandomEngine > > engine_
std::vector< std::vector< LabelAndEngine > > streamEngines_
std::vector< std::vector< RandomEngineState > > eventCache_
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
std::vector< std::vector< RandomEngineState > > lumiCache_
def cache(function)
static const std::vector< std::uint32_t >::size_type maxStates
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
LabelAndEngine(std::string const &theLabel, VUint32 const &theSeeds, std::shared_ptr< CLHEP::HepRandomEngine > const &theEngine)
HLT enums.
static const std::vector< std::uint32_t >::size_type maxSeeds
RandomNumberGeneratorService
Modules for shifting and smearing 4-vectors&#39; energies of Objects.
std::vector< std::vector< LabelAndEngine > > lumiEngines_
std::map< std::string, SeedsAndName > seedsAndNameMap_
std::vector< std::vector< ModuleIDToEngine > > lumiModuleIDToEngine_
SeedsAndName(VUint32 const &theSeeds, std::string const &theEngineName)
Definition: event.py:1