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