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