CMS 3D CMS Logo

RandomNumberGeneratorService.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RandomEngine
4 // Class : RandomNumberGeneratorService
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones, W. David Dagenhart
10 // Created: Tue Mar 7 09:43:46 EST 2006 (originally in FWCore/Services)
11 //
12 
14 
40 
41 #include "CLHEP/Random/engineIDulong.h"
42 #include "CLHEP/Random/JamesRandom.h"
43 #include "CLHEP/Random/RanecuEngine.h"
44 #include "CLHEP/Random/MixMaxRng.h"
45 
46 #include <algorithm>
47 #include <cassert>
48 #include <ostream>
49 #include <sstream>
50 #include <unistd.h>
51 
52 namespace edm {
53  namespace service {
54 
57  const std::uint32_t RandomNumberGeneratorService::maxSeedRanecu = 2147483647U;
58  const std::uint32_t RandomNumberGeneratorService::maxSeedHepJames = 900000000U;
59  const std::uint32_t RandomNumberGeneratorService::maxSeedTRandom3 = 4294967295U;
60 
62  ActivityRegistry& activityRegistry)
63  : nStreams_(0),
64  saveFileName_(pset.getUntrackedParameter<std::string>("saveFileName")),
65  saveFileNameRecorded_(false),
66  restoreFileName_(pset.getUntrackedParameter<std::string>("restoreFileName")),
67  enableChecking_(pset.getUntrackedParameter<bool>("enableChecking")),
68  eventSeedOffset_(pset.getUntrackedParameter<unsigned>("eventSeedOffset")),
69  verbose_(pset.getUntrackedParameter<bool>("verbose")) {
70  if (pset.exists("restoreStateTag")) {
71  restoreStateTag_ = pset.getUntrackedParameter<edm::InputTag>("restoreStateTag");
72  if (restoreStateTag_.process().empty()) {
74  }
75  } else {
78  }
80 
81  if (!restoreFileName_.empty() && !restoreStateTag_.label().empty()) {
82  throw Exception(errors::Configuration) << "In the configuration for the RandomNumberGeneratorService both\n"
83  << "restoreFileName and restoreStateLabel were set to nonempty values\n"
84  << "which is illegal. It is impossible to restore the random engine\n"
85  << "states two different ways in the same process.\n";
86  }
87 
88  // The saveFileName must correspond to a file name without any path specification.
89  // Throw if that is not true.
90  if (!saveFileName_.empty() && (saveFileName_.find("/") != std::string::npos)) {
92  << "The saveFileName parameter must be a simple file name with no path\n"
93  << "specification. In the configuration, it was given the value \"" << saveFileName_ << "\"\n";
94  }
95 
96  std::uint32_t initialSeed;
99 
100  std::vector<std::string> pSets = pset.getParameterNamesForType<ParameterSet>();
101  for (auto const& label : pSets) {
102  ParameterSet const& modulePSet = pset.getParameterSet(label);
103  engineName = modulePSet.getUntrackedParameter<std::string>("engineName", std::string("HepJamesRandom"));
104 
105  bool initialSeedExists = modulePSet.exists("initialSeed");
106  bool initialSeedSetExists = modulePSet.exists("initialSeedSet");
107 
108  if (initialSeedExists && initialSeedSetExists) {
109  throw Exception(errors::Configuration) << "For the module with the label \"" << label << "\",\n"
110  << "both the parameters \"initialSeed\" and \"initialSeedSet\"\n"
111  << "have been set in the configuration. You must set one or\n"
112  << "the other. It is illegal to set both.\n";
113  } else if (!initialSeedExists && !initialSeedSetExists) {
114  throw Exception(errors::Configuration) << "For the module with the label \"" << label << "\",\n"
115  << "neither the parameter \"initialSeed\" nor \"initialSeedSet\"\n"
116  << "has been set in the configuration. You must set one or\n"
117  << "the other.\n";
118  } else if (initialSeedExists) {
119  initialSeed = modulePSet.getUntrackedParameter<std::uint32_t>("initialSeed");
120  initialSeedSet.clear();
121  initialSeedSet.push_back(initialSeed);
122  } else if (initialSeedSetExists) {
123  initialSeedSet = modulePSet.getUntrackedParameter<VUint32>("initialSeedSet");
124  }
125  seedsAndNameMap_.insert(std::pair<std::string, SeedsAndName>(label, SeedsAndName(initialSeedSet, engineName)));
126 
127  // For the CLHEP::RanecuEngine case, require a seed set containing exactly two seeds.
128  if (engineName == std::string("RanecuEngine")) {
129  if (initialSeedSet.size() != 2U) {
131  << "Random engines of type \"RanecuEngine\" require 2 seeds\n"
132  << "be specified with the parameter named \"initialSeedSet\".\n"
133  << "Either \"initialSeedSet\" was not in the configuration\n"
134  << "or its size was not 2 for the module with label \"" << label << "\".\n";
135  }
136  if (initialSeedSet[0] > maxSeedRanecu ||
137  initialSeedSet[1] > maxSeedRanecu) { // They need to fit in a 31 bit integer
139  << "The RanecuEngine seeds should be in the range 0 to " << maxSeedRanecu << ".\n"
140  << "The seeds passed to the RandomNumberGenerationService from the\n"
141  "configuration file were "
142  << initialSeedSet[0] << " and " << initialSeedSet[1] << "\nThis was for the module with label \""
143  << label << "\".\n";
144  }
145  }
146  // For the other engines, one seed is required
147  else {
148  if (initialSeedSet.size() != 1U) {
150  << "Random engines of type \"HepJamesRandom\", \"TRandom3\" and \"MixMaxRng\" \n"
151  << "require exactly 1 seed be specified in the configuration.\n"
152  << "There were " << initialSeedSet.size() << " seeds set for the\n"
153  << "module with label \"" << label << "\".\n";
154  }
155  if (engineName == "HepJamesRandom") {
156  if (initialSeedSet[0] > maxSeedHepJames) {
158  << "The CLHEP::HepJamesRandom engine seed should be in the range 0 to " << maxSeedHepJames << ".\n"
159  << "The seed passed to the RandomNumberGenerationService from the\n"
160  "configuration file was "
161  << initialSeedSet[0] << ". This was for \n"
162  << "the module with label " << label << ".\n";
163  }
164  } else if (engineName == "MixMaxRng") {
165  if (initialSeedSet[0] > maxSeedTRandom3) {
167  << "The CLHEP::MixMaxRng engine seed should be in the range 0 to " << maxSeedTRandom3 << ".\n"
168  << "The seed passed to the RandomNumberGenerationService from the\n"
169  "configuration file was "
170  << initialSeedSet[0] << ". This was for \n"
171  << "the module with label " << label << ".\n";
172  }
173  } else if (engineName == "TRandom3") {
174  if (initialSeedSet[0] > maxSeedTRandom3) {
176  << "The CLHEP::MixMaxRng engine seed should be in the range 0 to " << maxSeedTRandom3 << ".\n"
177  << "The seed passed to the RandomNumberGenerationService from the\n"
178  "configuration file was "
179  << initialSeedSet[0] << ". This was for \n"
180  << "the module with label " << label << ".\n";
181  }
182  } else {
184  << "The random engine name, \"" << engineName << "\", does not correspond to a supported engine.\n"
185  << "This engine was configured for the module with label \"" << label << "\"";
186  }
187  }
188  }
190 
192 
193  if (enableChecking_) {
196 
199 
202 
205 
208 
211  }
212  }
213 
215 
218  iC.consumes<RandomEngineStates>(restoreStateTag_);
219  }
220 
221  CLHEP::HepRandomEngine& RandomNumberGeneratorService::getEngine(StreamID const& streamID) {
223  if (mcc == nullptr) {
225  << "RandomNumberGeneratorService::getEngine\n"
226  "Requested a random number engine from the RandomNumberGeneratorService\n"
227  "when no module was active. ModuleCallingContext is null\n";
228  }
229  unsigned int moduleID = mcc->moduleDescription()->id();
230 
231  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(streamID.value());
232  ModuleIDToEngine target(nullptr, moduleID);
233  std::vector<ModuleIDToEngine>::iterator iter =
234  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
235  if (iter == moduleIDVector.end() || iter->moduleID() != moduleID) {
237  << "The module with label \"" << mcc->moduleDescription()->moduleLabel()
238  << "\" requested a random number engine from the \n"
239  "RandomNumberGeneratorService, but that module was not configured\n"
240  "for random numbers. An engine is created only if a seed(s) is provided\n"
241  "in the configuration file. Please add the following PSet to the\n"
242  "configuration file for the RandomNumberGeneratorService:\n\n"
243  " "
244  << mcc->moduleDescription()->moduleLabel()
245  << " = cms.PSet(\n"
246  " initialSeed = cms.untracked.uint32(your_seed),\n"
247  " engineName = cms.untracked.string('TRandom3')\n"
248  " )\n"
249  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
250  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
251  }
252  return *iter->labelAndEngine()->engine();
253  }
254 
257  if (mcc == nullptr) {
259  << "RandomNumberGeneratorService::getEngine\n"
260  "Requested a random number engine from the RandomNumberGeneratorService\n"
261  "when no module was active. ModuleCallingContext is null\n";
262  }
263  unsigned int moduleID = mcc->moduleDescription()->id();
264 
265  std::vector<ModuleIDToEngine>& moduleIDVector = lumiModuleIDToEngine_.at(lumiIndex.value());
266  ModuleIDToEngine target(nullptr, moduleID);
267  std::vector<ModuleIDToEngine>::iterator iter =
268  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
269  if (iter == moduleIDVector.end() || iter->moduleID() != moduleID) {
271  << "The module with label \"" << mcc->moduleDescription()->moduleLabel()
272  << "\" requested a random number engine from the \n"
273  "RandomNumberGeneratorService, but that module was not configured\n"
274  "for random numbers. An engine is created only if a seed(s) is provided\n"
275  "in the configuration file. Please add the following PSet to the\n"
276  "configuration file for the RandomNumberGeneratorService:\n\n"
277  " "
278  << mcc->moduleDescription()->moduleLabel()
279  << " = cms.PSet(\n"
280  " initialSeed = cms.untracked.uint32(your_seed),\n"
281  " engineName = cms.untracked.string('TRandom3')\n"
282  " )\n"
283  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
284  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
285  }
286  return *iter->labelAndEngine()->engine();
287  }
288 
289  // PROBABLY TO BE DELETED, This returns the configured seed without
290  // any of the modifications for streams, forking, or the offset configuration
291  // parameter. Maybe useful to use for debugging/checks, but dangerous if one tries
292  // to create your own engines using it. It is difficult to get the offsets
293  // for streams/forking/offset parameters correct and almost certainly would break
294  // replay.
295  std::uint32_t RandomNumberGeneratorService::mySeed() const {
298  if (mcc == nullptr) {
300  << "RandomNumberGeneratorService::getEngine()\n"
301  "Requested a random number engine from the RandomNumberGeneratorService\n"
302  "from an unallowed transition. ModuleCallingContext is null\n";
303  } else {
304  label = mcc->moduleDescription()->moduleLabel();
305  }
306 
307  std::map<std::string, SeedsAndName>::const_iterator iter = seedsAndNameMap_.find(label);
308  if (iter == seedsAndNameMap_.end()) {
310  << "The module with label \"" << label
311  << "\" requested a random number seed from the \n"
312  "RandomNumberGeneratorService, but that module was not configured\n"
313  "for random numbers. An engine is created only if a seed(s) is provided\n"
314  "in the configuration file. Please add the following PSet to the\n"
315  "configuration file for the RandomNumberGeneratorService:\n\n"
316  " "
317  << label
318  << " = cms.PSet(\n"
319  " initialSeed = cms.untracked.uint32(your_seed),\n"
320  " engineName = cms.untracked.string('TRandom3')\n"
321  " )\n"
322  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
323  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
324  }
325  return iter->second.seeds()[0];
326  }
327 
330 
332  edm::InputTag emptyInputTag("", "", "");
333 
334  desc.addNode(edm::ParameterDescription<edm::InputTag>("restoreStateTag", emptyInputTag, false) xor
335  edm::ParameterDescription<std::string>("restoreStateLabel", emptyString, false));
336 
337  desc.addUntracked<std::string>("saveFileName", emptyString);
338  desc.addUntracked<std::string>("restoreFileName", emptyString);
339  desc.addUntracked<bool>("enableChecking", false);
340  desc.addUntracked<unsigned>("eventSeedOffset", 0U);
341  desc.addUntracked<bool>("verbose", false);
342 
344  val.addOptionalUntracked<std::uint32_t>("initialSeed");
345  val.addOptionalUntracked<std::vector<std::uint32_t> >("initialSeedSet");
346  val.addOptionalUntracked<std::string>("engineName");
347 
349  wnode.setComment("The name of each ParameterSet will be the associated module label.");
350  desc.addNode(wnode);
351 
352  descriptions.add("RandomNumberGeneratorService", desc);
353  }
354 
356  std::map<std::string, SeedsAndName>::iterator iter = seedsAndNameMap_.find(description.moduleLabel());
357  if (iter != seedsAndNameMap_.end()) {
358  iter->second.setModuleID(description.id());
359  }
360  }
361 
364  assert(nStreams_ >= 1);
365  if (!restoreFileName_.empty() && nStreams_ != 1) {
367  << "Configuration is illegal. The RandomNumberGeneratorService is configured\n"
368  << "to run replay using a text file to input the random engine states and\n"
369  << "the number of streams is greater than 1. Either set the\n"
370  << "parameter named \"restoreFileName\" in the RandomNumberGeneratorService\n"
371  << "to the empty string or set the parameter \"numberOfStreams\" in the top\n"
372  << "level options parameter set to 1. (Probably these are the default values\n"
373  << "and just not setting the parameters will also work)\n";
374  }
375  unsigned int nConcurrentLumis = sb.maxNumberOfConcurrentLuminosityBlocks();
376 
378  lumiModuleIDToEngine_.resize(nConcurrentLumis);
379  streamEngines_.resize(nStreams_);
380  lumiEngines_.resize(nConcurrentLumis);
381  eventCache_.resize(nStreams_);
382  lumiCache_.resize(nConcurrentLumis);
383  outFiles_.resize(nStreams_);
384 
385  for (unsigned int iStream = 0; iStream < nStreams_; ++iStream) {
386  unsigned int seedOffset = iStream;
388  if (!saveFileName_.empty()) {
389  outFiles_[iStream] = std::make_shared<std::ofstream>(); // propagate_const<T> has no reset() function
390  }
391  }
392  for (unsigned int iLumi = 0; iLumi < nConcurrentLumis; ++iLumi) {
393  unsigned int seedOffset = nStreams_;
394  createEnginesInVector(lumiEngines_[iLumi], seedOffset, 0, lumiModuleIDToEngine_[iLumi]);
395  snapShot(lumiEngines_[iLumi], lumiCache_[iLumi]);
396  if (!restoreFileName_.empty()) {
398  }
399  }
400 
401  if (!restoreFileName_.empty()) {
402  // There is guaranteed to be one stream in this case
406  }
407  if (verbose_) {
408  print(std::cout);
409  }
410  }
411 
413  if (!restoreStateTag_.label().empty()) {
414  // Copy from a product in the LuminosityBlock to cache for a particular luminosityBlockIndex
416  }
417  // Copy from cache to engine the state for a particular luminosityBlockIndex
419  }
420 
422  if (!restoreStateTag_.label().empty()) {
423  // This initializes the cache before readFromEvent
424  snapShot(streamEngines_[event.streamID()], eventCache_[event.streamID()]);
425 
426  // copy from Event to event cache
427  readFromEvent(event);
428 
429  // copy from event cache to engines
430  restoreFromCache(eventCache_[event.streamID()], streamEngines_[event.streamID()]);
431 
432  } else {
433  // copy from engines to event cache
434  snapShot(streamEngines_[event.streamID()], eventCache_[event.streamID()]);
435  }
436 
437  // if requested write text file from both caches
438  if (!saveFileName_.empty()) {
439  saveStatesToFile(saveFileName_, event.streamID(), event.getLuminosityBlock().index());
440  bool expected = false;
441  if (saveFileNameRecorded_.compare_exchange_strong(expected, true)) {
443  Service<JobReport> reportSvc;
444  reportSvc->reportRandomStateFile(fullName);
445  }
446  }
447  }
448 
450  preModuleStreamCheck(sc, mcc);
451  }
452 
454  postModuleStreamCheck(sc, mcc);
455  }
456 
458  preModuleStreamCheck(sc, mcc);
459  }
460 
462  postModuleStreamCheck(sc, mcc);
463  }
464 
466  ModuleCallingContext const& mcc) {
467  preModuleStreamCheck(sc, mcc);
468  }
469 
471  ModuleCallingContext const& mcc) {
472  postModuleStreamCheck(sc, mcc);
473  }
474 
476  preModuleStreamCheck(sc, mcc);
477  }
478 
480  ModuleCallingContext const& mcc) {
481  postModuleStreamCheck(sc, mcc);
482  }
483 
485  ModuleCallingContext const& mcc) {
486  preModuleStreamCheck(sc, mcc);
487  }
488 
490  ModuleCallingContext const& mcc) {
491  postModuleStreamCheck(sc, mcc);
492  }
493 
495  ModuleCallingContext const& mcc) {
496  preModuleStreamCheck(sc, mcc);
497  }
498 
500  ModuleCallingContext const& mcc) {
501  postModuleStreamCheck(sc, mcc);
502  }
503 
504  std::vector<RandomEngineState> const& RandomNumberGeneratorService::getLumiCache(
505  LuminosityBlockIndex const& lumiIndex) const {
506  return lumiCache_.at(lumiIndex.value());
507  }
508 
509  std::vector<RandomEngineState> const& RandomNumberGeneratorService::getEventCache(StreamID const& streamID) const {
510  return eventCache_.at(streamID.value());
511  }
512 
513  void RandomNumberGeneratorService::print(std::ostream& os) const {
514  os << "\n\nRandomNumberGeneratorService dump\n\n";
515 
516  os << " Contents of seedsAndNameMap (label moduleID engineType seeds)\n";
517  for (auto const& entry : seedsAndNameMap_) {
518  os << " " << entry.first << " " << entry.second.moduleID() << " " << entry.second.engineName();
519  for (auto val : entry.second.seeds()) {
520  os << " " << val;
521  }
522  os << "\n";
523  }
524  os << " nStreams_ = " << nStreams_ << "\n";
525  os << " saveFileName_ = " << saveFileName_ << "\n";
526  os << " saveFileNameRecorded_ = " << saveFileNameRecorded_ << "\n";
527  os << " restoreFileName_ = " << restoreFileName_ << "\n";
528  os << " enableChecking_ = " << enableChecking_ << "\n";
529  os << " eventSeedOffset_ = " << eventSeedOffset_ << "\n";
530  os << " verbose_ = " << verbose_ << "\n";
531  os << " restoreStateTag_ = " << restoreStateTag_ << "\n";
532  os << " restoreStateBeginLumiTag_ = " << restoreStateBeginLumiTag_ << "\n";
533 
534  os << "\n streamEngines_\n";
535  unsigned int iStream = 0;
536  for (auto const& k : streamEngines_) {
537  os << " Stream " << iStream << "\n";
538  for (auto const& i : k) {
539  os << " " << i.label();
540  for (auto const& j : i.seeds()) {
541  os << " " << j;
542  }
543  os << " " << i.engine()->name();
544  if (i.engine()->name() == std::string("HepJamesRandom")) {
545  os << " " << i.engine()->getSeed();
546  } else if (i.engine()->name() == std::string("MixMaxRng")) {
547  os << " " << i.engine()->getSeed();
548  } else {
549  os << " engine does not know seeds";
550  }
551  os << "\n";
552  }
553  ++iStream;
554  }
555  os << "\n lumiEngines_\n";
556  unsigned int iLumi = 0;
557  for (auto const& k : lumiEngines_) {
558  os << " lumiIndex " << iLumi << "\n";
559  for (auto const& i : k) {
560  os << " " << i.label();
561  for (auto const& j : i.seeds()) {
562  os << " " << j;
563  }
564  os << " " << i.engine()->name();
565  if (i.engine()->name() == std::string("HepJamesRandom")) {
566  os << " " << i.engine()->getSeed();
567  } else if (i.engine()->name() == std::string("MixMaxRng")) {
568  os << " " << i.engine()->getSeed();
569  } else {
570  os << " engine does not know seeds";
571  }
572  os << "\n";
573  }
574  ++iLumi;
575  }
576  }
577 
579  if (enableChecking_) {
580  unsigned int moduleID = mcc.moduleDescription()->id();
581  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(sc.streamID().value());
582  ModuleIDToEngine target(nullptr, moduleID);
583  std::vector<ModuleIDToEngine>::iterator iter =
584  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
585  if (iter != moduleIDVector.end() && iter->moduleID() == moduleID) {
586  LabelAndEngine* labelAndEngine = iter->labelAndEngine();
587  iter->setEngineState(labelAndEngine->engine()->put());
588  }
589  }
590  }
591 
593  if (enableChecking_) {
594  unsigned int moduleID = mcc.moduleDescription()->id();
595  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(sc.streamID().value());
596  ModuleIDToEngine target(nullptr, moduleID);
597  std::vector<ModuleIDToEngine>::iterator iter =
598  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
599  if (iter != moduleIDVector.end() && iter->moduleID() == moduleID) {
600  LabelAndEngine* labelAndEngine = iter->labelAndEngine();
601  if (iter->engineState() != labelAndEngine->engine()->put()) {
603  << "It is illegal to generate random numbers during beginStream, endStream,\n"
604  "beginRun, endRun, beginLumi, endLumi because that makes it very difficult\n"
605  "to replay the processing of individual events. Random numbers were\n"
606  "generated during one of these methods for the module with class name\n\""
607  << mcc.moduleDescription()->moduleName()
608  << "\" "
609  "and module label \""
610  << mcc.moduleDescription()->moduleLabel() << "\"\n";
611  }
612  }
613  }
614  }
615 
618  if (tns.isAvailable()) {
619  if (tns->getProcessName() == restoreStateTag_.process()) {
621  << "In the configuration for the RandomNumberGeneratorService the\n"
622  << "restoreStateTag contains the current process which is illegal.\n"
623  << "The process name in the replay process should have been changed\n"
624  << "to be different than the original process name and the restoreStateTag\n"
625  << "should contain either the original process name or an empty process name.\n";
626  }
627  }
628 
631 
632  if (!states.isValid()) {
634  << "The RandomNumberGeneratorService is trying to restore\n"
635  << "the state of the random engines by reading a product from\n"
636  << "the LuminosityBlock with input tag \"" << restoreStateBeginLumiTag_ << "\".\n"
637  << "It could not find the product.\n"
638  << "Either the product in the LuminosityBlock was dropped or\n"
639  << "not produced or the configured input tag is incorrect or there is a bug somewhere\n";
640  return;
641  }
642  states->getRandomEngineStates(lumiCache_.at(lumi.index()));
643  }
644 
647 
648  event.getByLabel(restoreStateTag_, states);
649 
650  if (!states.isValid()) {
652  << "The RandomNumberGeneratorService is trying to restore\n"
653  << "the state of the random engines by reading a product from\n"
654  << "the Event with input tag \"" << restoreStateTag_ << "\".\n"
655  << "It could not find the product.\n"
656  << "Either the product in the Event was dropped or\n"
657  << "not produced or the configured input tag is incorrect or there is a bug somewhere\n";
658  return;
659  }
660  states->getRandomEngineStates(eventCache_.at(event.streamID()));
661  }
662 
663  void RandomNumberGeneratorService::snapShot(std::vector<LabelAndEngine> const& engines,
664  std::vector<RandomEngineState>& cache) {
665  cache.resize(engines.size());
666  std::vector<RandomEngineState>::iterator state = cache.begin();
667 
668  for (std::vector<LabelAndEngine>::const_iterator iter = engines.begin(); iter != engines.end(); ++iter, ++state) {
669  std::string const& label = iter->label();
670  state->setLabel(label);
671  state->setSeed(iter->seeds());
672 
673  std::vector<unsigned long> stateL = iter->engine()->put();
674  state->clearStateVector();
675  state->reserveStateVector(stateL.size());
676  for (auto element : stateL) {
677  state->push_back_stateVector(static_cast<std::uint32_t>(element));
678  }
679  }
680  }
681 
682  void RandomNumberGeneratorService::restoreFromCache(std::vector<RandomEngineState> const& cache,
683  std::vector<LabelAndEngine>& engines) {
684  std::vector<LabelAndEngine>::iterator labelAndEngine = engines.begin();
685  for (auto const& cachedState : cache) {
686  std::string const& engineLabel = cachedState.getLabel();
687 
688  std::vector<std::uint32_t> const& engineState = cachedState.getState();
689  std::vector<unsigned long> engineStateL;
690  engineStateL.reserve(engineState.size());
691  for (auto const& value : engineState) {
692  engineStateL.push_back(static_cast<unsigned long>(value));
693  }
694 
695  std::vector<std::uint32_t> const& engineSeeds = cachedState.getSeed();
696  std::vector<long> engineSeedsL;
697  engineSeedsL.reserve(engineSeeds.size());
698  for (auto const& val : engineSeeds) {
699  long seedL = static_cast<long>(val);
700  engineSeedsL.push_back(seedL);
701 
702  // There is a dangerous conversion from std::uint32_t to long
703  // that occurs above. In the next 2 lines we check the
704  // behavior is what we need for the service to work
705  // properly. This conversion is forced on us by the
706  // CLHEP and ROOT interfaces. If the assert ever starts
707  // to fail we will have to come up with a way to deal
708  // with this.
709  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
710  assert(val == seedu32);
711  }
712 
713  assert(labelAndEngine != engines.end() && engineLabel == labelAndEngine->label());
714  std::shared_ptr<CLHEP::HepRandomEngine> const& engine = labelAndEngine->engine();
715 
716  // We need to handle each type of engine differently because each
717  // has different requirements on the seed or seeds.
718  if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::HepJamesRandom>()) {
719  checkEngineType(engine->name(), std::string("HepJamesRandom"), engineLabel);
720 
721  // These two lines actually restore the seed and engine state.
722  engine->setSeed(engineSeedsL[0], 0);
723  engine->get(engineStateL);
724 
725  labelAndEngine->setSeed(engineSeeds[0], 0);
726  } else if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::RanecuEngine>()) {
727  checkEngineType(engine->name(), std::string("RanecuEngine"), engineLabel);
728 
729  // This line actually restores the engine state.
730  engine->get(engineStateL);
731 
732  labelAndEngine->setSeed(engineSeeds[0], 0);
733  labelAndEngine->setSeed(engineSeeds[1], 1);
734  } else if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::MixMaxRng>()) {
735  checkEngineType(engine->name(), std::string("MixMaxRng"), engineLabel);
736 
737  // This line actually restores the engine state.
738  engine->setSeed(engineSeedsL[0], 0);
739  engine->get(engineStateL);
740 
741  labelAndEngine->setSeed(engineSeeds[0], 0);
742  } else if (engineStateL[0] == CLHEP::engineIDulong<TRandomAdaptor>()) {
743  checkEngineType(engine->name(), std::string("TRandom3"), engineLabel);
744 
745  // This line actually restores the engine state.
746  engine->setSeed(engineSeedsL[0], 0);
747  engine->get(engineStateL);
748 
749  labelAndEngine->setSeed(engineSeeds[0], 0);
750  } else {
751  // This should not be possible because this code should be able to restore
752  // any kind of engine whose state can be saved.
754  << "The RandomNumberGeneratorService is trying to restore the state\n"
755  "of the random engines. The state in the event indicates an engine\n"
756  "of an unknown type. This should not be possible unless you are\n"
757  "running with an old code release on a new file that was created\n"
758  "with a newer release which had new engine types added. In this case\n"
759  "the only solution is to use a newer release. In any other case, notify\n"
760  "the EDM developers because this should not be possible\n";
761  }
762  ++labelAndEngine;
763  }
764  }
765 
767  std::string const& typeFromEvent,
768  std::string const& engineLabel) const {
769  if (typeFromConfig != typeFromEvent) {
771  << "The RandomNumberGeneratorService is trying to restore\n"
772  << "the state of the random engine for the module \"" << engineLabel << "\". An\n"
773  << "error was detected because the type of the engine in the\n"
774  << "input file and the configuration file do not match.\n"
775  << "In the configuration file the type is \"" << typeFromConfig << "\".\nIn the input file the type is \""
776  << typeFromEvent << "\". If\n"
777  << "you are not generating any random numbers in this module, then\n"
778  << "remove the line in the configuration file that gives it\n"
779  << "a seed and the error will go away. Otherwise, you must give\n"
780  << "this module the same engine type in the configuration file or\n"
781  << "stop trying to restore the random engine state.\n";
782  }
783  }
784 
786  StreamID const& streamID,
788  std::ofstream& outFile = *outFiles_.at(streamID);
789 
790  if (!outFile.is_open()) {
791  std::stringstream file;
792  file << fileName;
793  if (nStreams_ > 1) {
794  file << "_" << streamID.value();
795  }
796 
797  outFile.open(file.str().c_str(), std::ofstream::out | std::ofstream::trunc);
798 
799  if (!outFile) {
801  << "Unable to open the file \"" << file.str() << "\" to save the state of the random engines.\n";
802  }
803  }
804 
805  outFile.seekp(0, std::ios_base::beg);
806  outFile << "<RandomEngineStates>\n";
807 
808  outFile << "<Event>\n";
809  writeStates(eventCache_.at(streamID), outFile);
810  outFile << "</Event>\n";
811 
812  outFile << "<Lumi>\n";
813  writeStates(lumiCache_.at(lumiIndex), outFile);
814  outFile << "</Lumi>\n";
815 
816  outFile << "</RandomEngineStates>\n";
817  outFile.flush();
818  }
819 
820  void RandomNumberGeneratorService::writeStates(std::vector<RandomEngineState> const& v, std::ofstream& outFile) {
821  for (auto& state : v) {
822  std::vector<std::uint32_t> const& seedVector = state.getSeed();
823  std::vector<std::uint32_t>::size_type seedVectorLength = seedVector.size();
824 
825  std::vector<std::uint32_t> const& stateVector = state.getState();
826  std::vector<std::uint32_t>::size_type stateVectorLength = stateVector.size();
827 
828  outFile << "<ModuleLabel>\n" << state.getLabel() << "\n</ModuleLabel>\n";
829 
830  outFile << "<SeedLength>\n" << seedVectorLength << "\n</SeedLength>\n";
831  outFile << "<InitialSeeds>\n";
832  writeVector(seedVector, outFile);
833  outFile << "</InitialSeeds>\n";
834  outFile << "<FullStateLength>\n" << stateVectorLength << "\n</FullStateLength>\n";
835  outFile << "<FullState>\n";
836  writeVector(stateVector, outFile);
837  outFile << "</FullState>\n";
838  }
839  }
840 
842  if (v.empty())
843  return;
844  size_t numItems = v.size();
845  for (size_t i = 0; i < numItems; ++i) {
846  if (i != 0 && i % 10 == 0)
847  outFile << "\n";
848  outFile << std::setw(13) << v[i];
849  }
850  outFile << "\n";
851  }
852 
854  char directory[1500];
855  std::string fullName(getcwd(directory, sizeof(directory)) ? directory : "/PathIsTooBig");
856  fullName += "/" + saveFileName_;
857  return fullName;
858  }
859 
861  std::vector<RandomEngineState>& cache) {
862  std::string whichStates("<Event>");
863  readStatesFromFile(fileName, cache, whichStates);
864  }
865 
867  std::vector<RandomEngineState>& cache) {
868  std::string whichStates("<Lumi>");
869  readStatesFromFile(fileName, cache, whichStates);
870  }
871 
873  std::vector<RandomEngineState>& cache,
874  std::string const& whichStates) {
875  std::ifstream inFile;
876  inFile.open(fileName.c_str(), std::ifstream::in);
877  if (!inFile) {
879  << "Unable to open the file \"" << fileName << "\" to restore the random engine states.\n";
880  }
881 
883  inFile >> text;
884  if (!inFile.good() || text != std::string("<RandomEngineStates>")) {
886  << "Attempting to read file with random number engine states.\n"
887  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
888  << "Cannot read the file header word.\n";
889  }
890  bool saveToCache = false;
891  while (readEngineState(inFile, cache, whichStates, saveToCache)) {
892  }
893  }
894 
896  std::vector<RandomEngineState>& cache,
897  std::string const& whichStates,
898  bool& saveToCache) {
899  std::string leading;
900  std::string trailing;
903  std::vector<std::uint32_t> seedVector;
905  std::vector<std::uint32_t> stateVector;
906 
907  // First we need to look for the special strings
908  // that mark the end of the file and beginning and
909  // and end of the data for different sections.
910 
911  is >> leading;
912  if (!is.good()) {
914  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
915  << "Cannot read next field and did not hit the end yet.\n";
916  }
917 
918  // This marks the end of the file. We are done.
919  if (leading == std::string("</RandomEngineStates>"))
920  return false;
921 
922  // This marks the end of a section of the data
923  if (leading == std::string("</Event>") || leading == std::string("</Lumi>")) {
924  saveToCache = false;
925  return true;
926  }
927 
928  // This marks the beginning of a section
929  if (leading == std::string("<Event>") || leading == std::string("<Lumi>")) {
930  saveToCache = (leading == whichStates);
931  return true;
932  }
933 
934  // Process the next engine state
935 
936  is >> moduleLabel >> trailing;
937  if (!is.good() || leading != std::string("<ModuleLabel>") || trailing != std::string("</ModuleLabel>")) {
939  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
940  << "Cannot read a module label when restoring random engine states.\n";
941  }
942 
943  is >> leading >> seedVectorSize >> trailing;
944  if (!is.good() || leading != std::string("<SeedLength>") || trailing != std::string("</SeedLength>")) {
946  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
947  << "Cannot read seed vector length when restoring random engine states.\n";
948  }
949 
950  is >> leading;
951  if (!is.good() || leading != std::string("<InitialSeeds>")) {
953  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
954  << "Cannot read beginning of InitialSeeds when restoring random engine states.\n";
955  }
956 
957  if (seedVectorSize > maxSeeds) {
959  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
960  << "The number of seeds exceeds 64K.\n";
961  }
962 
963  readVector(is, seedVectorSize, seedVector);
964 
965  is >> trailing;
966  if (!is.good() || trailing != std::string("</InitialSeeds>")) {
968  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
969  << "Cannot read end of InitialSeeds when restoring random engine states.\n";
970  }
971 
972  is >> leading >> stateVectorSize >> trailing;
973  if (!is.good() || leading != std::string("<FullStateLength>") || trailing != std::string("</FullStateLength>")) {
975  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
976  << "Cannot read state vector length when restoring random engine states.\n";
977  }
978 
979  is >> leading;
980  if (!is.good() || leading != std::string("<FullState>")) {
982  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
983  << "Cannot read beginning of FullState when restoring random engine states.\n";
984  }
985 
986  if (stateVectorSize > maxStates) {
988  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
989  << "The number of states exceeds 64K.\n";
990  }
991 
992  readVector(is, stateVectorSize, stateVector);
993 
994  is >> trailing;
995  if (!is.good() || trailing != std::string("</FullState>")) {
997  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
998  << "Cannot read end of FullState when restoring random engine states.\n";
999  }
1000 
1001  if (saveToCache) {
1002  RandomEngineState randomEngineState;
1003  randomEngineState.setLabel(moduleLabel);
1004  std::vector<RandomEngineState>::iterator state =
1005  std::lower_bound(cache.begin(), cache.end(), randomEngineState);
1006 
1007  if (state != cache.end() && moduleLabel == state->getLabel()) {
1008  if (seedVector.size() != state->getSeed().size() || stateVector.size() != state->getState().size()) {
1010  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1011  << "Vectors containing engine state are the incorrect size for the type of random engine.\n";
1012  }
1013  state->setSeed(seedVector);
1014  state->setState(stateVector);
1015  }
1016  }
1017  return true;
1018  }
1019 
1020  void RandomNumberGeneratorService::readVector(std::istream& is, unsigned numItems, std::vector<std::uint32_t>& v) {
1021  v.clear();
1022  v.reserve(numItems);
1023  std::uint32_t data;
1024  for (unsigned i = 0; i < numItems; ++i) {
1025  is >> data;
1026  if (!is.good()) {
1028  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1029  << "Cannot read vector when restoring random engine states.\n";
1030  }
1031  v.push_back(data);
1032  }
1033  }
1034 
1035  void RandomNumberGeneratorService::createEnginesInVector(std::vector<LabelAndEngine>& engines,
1036  unsigned int seedOffset,
1037  unsigned int eventSeedOffset,
1038  std::vector<ModuleIDToEngine>& moduleIDVector) {
1039  // The vectors we will fill here will be the same size as
1040  // or smaller than seedsAndNameMap_.
1041  engines.reserve(seedsAndNameMap_.size());
1042  moduleIDVector.reserve(seedsAndNameMap_.size());
1043 
1044  for (auto const& i : seedsAndNameMap_) {
1045  unsigned int moduleID = i.second.moduleID();
1046  if (moduleID != std::numeric_limits<unsigned int>::max()) {
1047  std::string const& label = i.first;
1048  std::string const& name = i.second.engineName();
1049  VUint32 const& seeds = i.second.seeds();
1050 
1051  if (name == "RanecuEngine") {
1052  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::RanecuEngine>();
1053  engines.emplace_back(label, seeds, engine);
1054  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1055  }
1056  // For the other engines, one seed is required
1057  else {
1058  long int seedL = static_cast<long int>(seeds[0]);
1059 
1060  if (name == "HepJamesRandom") {
1061  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::HepJamesRandom>(seedL);
1062  engines.emplace_back(label, seeds, engine);
1063  if (seedOffset != 0 || eventSeedOffset != 0) {
1064  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1065  }
1066  } else if (name == "MixMaxRng") {
1067  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::MixMaxRng>(seedL);
1068  engines.emplace_back(label, seeds, engine);
1069  if (seedOffset != 0 || eventSeedOffset != 0) {
1070  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1071  }
1072  } else { // TRandom3, currently the only other possibility
1073 
1074  // There is a dangerous conversion from std::uint32_t to long
1075  // that occurs above. In the next 2 lines we check the
1076  // behavior is what we need for the service to work
1077  // properly. This conversion is forced on us by the
1078  // CLHEP and ROOT interfaces. If the assert ever starts
1079  // to fail we will have to come up with a way to deal
1080  // with this.
1081  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
1082  assert(seeds[0] == seedu32);
1083 
1084  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<TRandomAdaptor>(seedL);
1085  engines.emplace_back(label, seeds, engine);
1086  if (seedOffset != 0 || eventSeedOffset != 0) {
1087  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1088  }
1089  }
1090  }
1091  moduleIDVector.emplace_back(&engines.back(), moduleID);
1092  } // if moduleID valid
1093  } // loop over seedsAndMap
1094  std::sort(moduleIDVector.begin(), moduleIDVector.end());
1095  }
1096 
1098  std::string const& engineName,
1099  VUint32 const& seeds,
1100  std::uint32_t offset1,
1101  std::uint32_t offset2) {
1102  if (engineName == "RanecuEngine") {
1103  assert(seeds.size() == 2U);
1104  // Wrap around if the offsets push the seed over the maximum allowed value
1105  std::uint32_t mod = maxSeedRanecu + 1U;
1106  offset1 %= mod;
1107  offset2 %= mod;
1108  std::uint32_t seed0 = (seeds[0] + offset1) % mod;
1109  seed0 = (seed0 + offset2) % mod;
1110  labelAndEngine.setSeed(seed0, 0);
1111  labelAndEngine.setSeed(seeds[1], 1);
1112  long int seedL[2];
1113  seedL[0] = static_cast<long int>(seed0);
1114  seedL[1] = static_cast<long int>(seeds[1]);
1115  labelAndEngine.engine()->setSeeds(seedL, 0);
1116  } else {
1117  assert(seeds.size() == 1U);
1118 
1119  if (engineName == "HepJamesRandom" || engineName == "MixMaxRng") {
1120  // Wrap around if the offsets push the seed over the maximum allowed value
1121  std::uint32_t mod = maxSeedHepJames + 1U;
1122  offset1 %= mod;
1123  offset2 %= mod;
1124  std::uint32_t seed0 = (seeds[0] + offset1) % mod;
1125  seed0 = (seed0 + offset2) % mod;
1126  labelAndEngine.setSeed(seed0, 0);
1127 
1128  long int seedL = static_cast<long int>(seed0);
1129  labelAndEngine.engine()->setSeed(seedL, 0);
1130  } else {
1131  assert(engineName == "TRandom3");
1132  // Wrap around if the offsets push the seed over the maximum allowed value
1133  // We have to be extra careful with this one because it may also go beyond
1134  // the values 32 bits can hold
1135  std::uint32_t max32 = maxSeedTRandom3;
1136  std::uint32_t seed0 = seeds[0];
1137  if ((max32 - seed0) >= offset1) {
1138  seed0 += offset1;
1139  } else {
1140  seed0 = offset1 - (max32 - seed0) - 1U;
1141  }
1142  if ((max32 - seed0) >= offset2) {
1143  seed0 += offset2;
1144  } else {
1145  seed0 = offset2 - (max32 - seed0) - 1U;
1146  }
1147  labelAndEngine.setSeed(seed0, 0);
1148 
1149  long seedL = static_cast<long>(seed0);
1150 
1151  // There is a dangerous conversion from std::uint32_t to long
1152  // that occurs above. In the next 2 lines we check the
1153  // behavior is what we need for the service to work
1154  // properly. This conversion is forced on us by the
1155  // CLHEP and ROOT interfaces. If the assert ever starts
1156  // to fail we will have to come up with a way to deal
1157  // with this.
1158  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
1159  assert(seed0 == seedu32);
1160 
1161  labelAndEngine.engine()->setSeed(seedL, 0);
1162  }
1163  }
1164  }
1165  } // namespace service
1166 } // namespace edm
void writeStates(std::vector< RandomEngineState > const &v, std::ofstream &outFile)
T getUntrackedParameter(std::string const &, T const &) const
void preModuleStreamEndLumi(StreamContext const &sc, ModuleCallingContext const &mcc)
void readVector(std::istream &is, unsigned numItems, std::vector< std::uint32_t > &v)
void watchPreallocate(Preallocate::slot_type const &iSlot)
CLHEP::HepRandomEngine & getEngine(StreamID const &streamID) override
Use this engine in event methods.
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
LuminosityBlockIndex index() const
void watchPostModuleEndStream(PostModuleEndStream::slot_type const &iSlot)
void watchPreModuleConstruction(PreModuleConstruction::slot_type const &iSlot)
void setLabel(const std::string &value)
bool exists(std::string const &parameterName) const
checks if a parameter exists
static ModuleCallingContext const * getCurrentModuleOnThread()
std::string const & moduleName() const
std::shared_ptr< CLHEP::HepRandomEngine const > engine() const
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
void preModuleEndStream(StreamContext const &sc, ModuleCallingContext const &mcc)
void watchPostModuleStreamEndLumi(PostModuleStreamEndLumi::slot_type const &iSlot)
void watchPostModuleStreamBeginRun(PostModuleStreamBeginRun::slot_type const &iSlot)
void preModuleConstruction(ModuleDescription const &description)
void postModuleStreamEndRun(StreamContext const &sc, ModuleCallingContext const &mcc)
void postModuleStreamCheck(StreamContext const &sc, ModuleCallingContext const &mcc)
void watchPreModuleBeginStream(PreModuleBeginStream::slot_type const &iSlot)
void resetEngineSeeds(LabelAndEngine &labelAndEngine, std::string const &engineName, VUint32 const &seeds, std::uint32_t offset1, std::uint32_t offset2)
bool getByLabel(std::string const &label, Handle< PROD > &result) const
void readFromLuminosityBlock(LuminosityBlock const &lumi)
std::string const & moduleLabel() const
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 postModuleEndStream(StreamContext const &sc, ModuleCallingContext const &mcc)
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:168
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:35
std::vector< std::vector< ModuleIDToEngine > > streamModuleIDToEngine_
char const * label
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_
void consumes(ConsumesCollector &&iC) const override
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)
static const std::string kSkipCurrentProcess
Definition: InputTag.h:53
ModuleDescription const * moduleDescription() const
bool isAvailable() const
Definition: Service.h:40
std::vector< std::vector< LabelAndEngine > > streamEngines_
std::vector< std::vector< RandomEngineState > > eventCache_
unsigned int value() const
void readStatesFromFile(std::string const &fileName, std::vector< RandomEngineState > &cache, std::string const &whichStates)
static void fillDescriptions(ConfigurationDescriptions &descriptions)
Definition: value.py:1
bool isValid() const
Definition: HandleBase.h:70
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 watchPostModuleStreamEndRun(PostModuleStreamEndRun::slot_type const &iSlot)
StreamID const & streamID() const
Definition: StreamContext.h:54
void preModuleStreamEndRun(StreamContext const &sc, ModuleCallingContext const &mcc)
void watchPreModuleStreamBeginLumi(PreModuleStreamBeginLumi::slot_type const &iSlot)
void watchPostModuleBeginStream(PostModuleBeginStream::slot_type const &iSlot)
unsigned int value() const
Definition: StreamID.h:42
unsigned int maxNumberOfConcurrentLuminosityBlocks() const
Definition: SystemBounds.h:37
void watchPostModuleStreamBeginLumi(PostModuleStreamBeginLumi::slot_type const &iSlot)
ParameterSet const & getParameterSet(std::string const &) const
void watchPreModuleStreamEndLumi(PreModuleStreamEndLumi::slot_type const &iSlot)
void checkEngineType(std::string const &typeFromConfig, std::string const &typeFromEvent, std::string const &engineLabel) const
void watchPreModuleStreamBeginRun(PreModuleStreamBeginRun::slot_type const &iSlot)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void watchPreModuleEndStream(PreModuleEndStream::slot_type const &iSlot)
std::string const & label() const
Definition: InputTag.h:36
void postModuleStreamEndLumi(StreamContext const &sc, ModuleCallingContext const &mcc)
static std::string const emptyString("")
std::string const & process() const
Definition: InputTag.h:40
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
void watchPreModuleStreamEndRun(PreModuleStreamEndRun::slot_type const &iSlot)
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
StreamID streamID() const
Definition: Event.h:96
void readLumiStatesFromTextFile(std::string const &fileName, std::vector< RandomEngineState > &cache)
std::vector< RandomEngineState > const & getEventCache(StreamID const &) 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 print(std::ostream &os) const override
For debugging.
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
std::map< std::string, SeedsAndName > seedsAndNameMap_
std::vector< std::vector< ModuleIDToEngine > > lumiModuleIDToEngine_
void preModuleStreamCheck(StreamContext const &sc, ModuleCallingContext const &mcc)
void preBeginLumi(LuminosityBlock const &lumi) override
void postModuleStreamBeginLumi(StreamContext const &sc, ModuleCallingContext const &mcc)
Definition: event.py:1
unsigned int id() const