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 
199 
200  if (enableChecking_) {
203 
206 
209 
212 
215 
218  }
219  }
220 
222 
225  iC.consumes<RandomEngineStates>(restoreStateTag_);
226  }
227 
228  CLHEP::HepRandomEngine& RandomNumberGeneratorService::getEngine(StreamID const& streamID) {
230  if (mcc == nullptr || beginJobEndJobActive_) {
232  << "RandomNumberGeneratorService::getEngine\n"
233  "Requested a random number engine from the RandomNumberGeneratorService\n"
234  "while ModuleCallingContext is null or during beginJob or endJob transitions.\n";
235  }
236  unsigned int moduleID = mcc->moduleDescription()->id();
237 
238  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(streamID.value());
239  ModuleIDToEngine target(nullptr, moduleID);
240  std::vector<ModuleIDToEngine>::iterator iter =
241  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
242  if (iter == moduleIDVector.end() || iter->moduleID() != moduleID) {
244  << "The module with label \"" << mcc->moduleDescription()->moduleLabel()
245  << "\" requested a random number engine from the \n"
246  "RandomNumberGeneratorService, but that module was not configured\n"
247  "for random numbers. An engine is created only if a seed(s) is provided\n"
248  "in the configuration file. Please add the following PSet to the\n"
249  "configuration file for the RandomNumberGeneratorService:\n\n"
250  " "
251  << mcc->moduleDescription()->moduleLabel()
252  << " = cms.PSet(\n"
253  " initialSeed = cms.untracked.uint32(your_seed),\n"
254  " engineName = cms.untracked.string('TRandom3')\n"
255  " )\n"
256  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
257  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
258  }
259  return *iter->labelAndEngine()->engine();
260  }
261 
264  if (mcc == nullptr || beginJobEndJobActive_) {
266  << "RandomNumberGeneratorService::getEngine\n"
267  "Requested a random number engine from the RandomNumberGeneratorService\n"
268  "while ModuleCallingContext is null or during beginJob or endJob transitions.\n";
269  }
270  unsigned int moduleID = mcc->moduleDescription()->id();
271 
272  std::vector<ModuleIDToEngine>& moduleIDVector = lumiModuleIDToEngine_.at(lumiIndex.value());
273  ModuleIDToEngine target(nullptr, moduleID);
274  std::vector<ModuleIDToEngine>::iterator iter =
275  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
276  if (iter == moduleIDVector.end() || iter->moduleID() != moduleID) {
278  << "The module with label \"" << mcc->moduleDescription()->moduleLabel()
279  << "\" requested a random number engine from the \n"
280  "RandomNumberGeneratorService, but that module was not configured\n"
281  "for random numbers. An engine is created only if a seed(s) is provided\n"
282  "in the configuration file. Please add the following PSet to the\n"
283  "configuration file for the RandomNumberGeneratorService:\n\n"
284  " "
285  << mcc->moduleDescription()->moduleLabel()
286  << " = cms.PSet(\n"
287  " initialSeed = cms.untracked.uint32(your_seed),\n"
288  " engineName = cms.untracked.string('TRandom3')\n"
289  " )\n"
290  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
291  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
292  }
293  return *iter->labelAndEngine()->engine();
294  }
295 
296  std::unique_ptr<CLHEP::HepRandomEngine> RandomNumberGeneratorService::cloneEngine(
299  }
300 
301  // PROBABLY TO BE DELETED, This returns the configured seed without
302  // any of the modifications for streams or the offset configuration
303  // parameter. Maybe useful to use for debugging/checks, but dangerous if one tries
304  // to create your own engines using it. It is difficult to get the offsets
305  // for streams/forking/offset parameters correct and almost certainly would break
306  // replay.
307  std::uint32_t RandomNumberGeneratorService::mySeed() const {
310  if (mcc == nullptr || beginJobEndJobActive_) {
312  << "RandomNumberGeneratorService::mySeed()\n"
313  "Requested a random number seed from the RandomNumberGeneratorService\n"
314  "while ModuleCallingContext is null or during beginJob or endJob transitions.\n";
315  } else {
316  label = mcc->moduleDescription()->moduleLabel();
317  }
318 
319  std::map<std::string, SeedsAndName>::const_iterator iter = seedsAndNameMap_.find(label);
320  if (iter == seedsAndNameMap_.end()) {
322  << "The module with label \"" << label
323  << "\" requested a random number seed from the \n"
324  "RandomNumberGeneratorService, but that module was not configured\n"
325  "for random numbers. An engine is created only if a seed(s) is provided\n"
326  "in the configuration file. Please add the following PSet to the\n"
327  "configuration file for the RandomNumberGeneratorService:\n\n"
328  " "
329  << label
330  << " = cms.PSet(\n"
331  " initialSeed = cms.untracked.uint32(your_seed),\n"
332  " engineName = cms.untracked.string('TRandom3')\n"
333  " )\n"
334  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
335  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
336  }
337  return iter->second.seeds()[0];
338  }
339 
342 
344  edm::InputTag emptyInputTag("", "", "");
345 
346  desc.addNode(edm::ParameterDescription<edm::InputTag>("restoreStateTag", emptyInputTag, false) xor
347  edm::ParameterDescription<std::string>("restoreStateLabel", emptyString, false));
348 
349  desc.addUntracked<std::string>("saveFileName", emptyString);
350  desc.addUntracked<std::string>("restoreFileName", emptyString);
351  desc.addUntracked<bool>("enableChecking", false);
352  desc.addUntracked<unsigned>("eventSeedOffset", 0U);
353  desc.addUntracked<bool>("verbose", false);
354 
356  val.addOptionalUntracked<std::uint32_t>("initialSeed");
357  val.addOptionalUntracked<std::vector<std::uint32_t> >("initialSeedSet");
358  val.addOptionalUntracked<std::string>("engineName");
359 
361  wnode.setComment("The name of each ParameterSet will be the associated module label.");
362  desc.addNode(wnode);
363 
364  descriptions.add("RandomNumberGeneratorService", desc);
365  }
366 
368  std::map<std::string, SeedsAndName>::iterator iter = seedsAndNameMap_.find(description.moduleLabel());
369  if (iter != seedsAndNameMap_.end()) {
370  iter->second.setModuleID(description.id());
371  }
372  }
373 
375  std::map<std::string, SeedsAndName>::iterator iter = seedsAndNameMap_.find(description.moduleLabel());
376  if (iter != seedsAndNameMap_.end()) {
377  iter->second.setModuleID(SeedsAndName::kInvalid);
378  }
379  }
380 
383  assert(nStreams_ >= 1);
384  if (!restoreFileName_.empty() && nStreams_ != 1) {
386  << "Configuration is illegal. The RandomNumberGeneratorService is configured\n"
387  << "to run replay using a text file to input the random engine states and\n"
388  << "the number of streams is greater than 1. Either set the\n"
389  << "parameter named \"restoreFileName\" in the RandomNumberGeneratorService\n"
390  << "to the empty string or set the parameter \"numberOfStreams\" in the top\n"
391  << "level options parameter set to 1. (Probably these are the default values\n"
392  << "and just not setting the parameters will also work)\n";
393  }
394  unsigned int nConcurrentLumis = sb.maxNumberOfConcurrentLuminosityBlocks();
395 
397  lumiModuleIDToEngine_.resize(nConcurrentLumis);
398  streamEngines_.resize(nStreams_);
399  lumiEngines_.resize(nConcurrentLumis);
400  eventCache_.resize(nStreams_);
401  lumiCache_.resize(nConcurrentLumis);
402  outFiles_.resize(nStreams_);
403 
404  for (unsigned int iStream = 0; iStream < nStreams_; ++iStream) {
405  unsigned int seedOffset = iStream;
407  if (!saveFileName_.empty()) {
408  outFiles_[iStream] = std::make_shared<std::ofstream>(); // propagate_const<T> has no reset() function
409  }
410  }
411  for (unsigned int iLumi = 0; iLumi < nConcurrentLumis; ++iLumi) {
412  unsigned int seedOffset = nStreams_;
413  createEnginesInVector(lumiEngines_[iLumi], seedOffset, 0, lumiModuleIDToEngine_[iLumi]);
414  snapShot(lumiEngines_[iLumi], lumiCache_[iLumi]);
415  if (!restoreFileName_.empty()) {
417  }
418  }
419 
420  if (!restoreFileName_.empty()) {
421  // There is guaranteed to be one stream in this case
425  }
426  if (verbose_) {
427  print(std::cout);
428  }
429  }
430 
432  beginJobEndJobActive_ = true;
433  }
434 
436 
438 
440 
442  if (!restoreStateTag_.label().empty()) {
443  // Copy from a product in the LuminosityBlock to cache for a particular luminosityBlockIndex
445  }
446  // Copy from cache to engine the state for a particular luminosityBlockIndex
447  restoreFromCache(lumiCache_[lumi.index()], lumiEngines_[lumi.index()]);
448  }
449 
451  if (!restoreStateTag_.label().empty()) {
452  // This initializes the cache before readFromEvent
453  snapShot(streamEngines_[event.streamID()], eventCache_[event.streamID()]);
454 
455  // copy from Event to event cache
457 
458  // copy from event cache to engines
459  restoreFromCache(eventCache_[event.streamID()], streamEngines_[event.streamID()]);
460 
461  } else {
462  // copy from engines to event cache
463  snapShot(streamEngines_[event.streamID()], eventCache_[event.streamID()]);
464  }
465 
466  // if requested write text file from both caches
467  if (!saveFileName_.empty()) {
468  saveStatesToFile(saveFileName_, event.streamID(), event.getLuminosityBlock().index());
469  bool expected = false;
470  if (saveFileNameRecorded_.compare_exchange_strong(expected, true)) {
472  Service<JobReport> reportSvc;
473  reportSvc->reportRandomStateFile(fullName);
474  }
475  }
476  }
477 
479  std::vector<RandomEngineState> const& iStates) {
480  lumiCache_[iLumi] = iStates;
481  // Copy from cache to engine the state for a particular luminosityBlockIndex
482  restoreFromCache(lumiCache_[iLumi], lumiEngines_[iLumi]);
483  }
484  void RandomNumberGeneratorService::setEventCache(StreamID iStream, std::vector<RandomEngineState> const& iStates) {
485  eventCache_[iStream] = iStates;
486  // copy from event cache to engines
487  restoreFromCache(eventCache_[iStream], streamEngines_[iStream]);
488  }
489 
491  preModuleStreamCheck(sc, mcc);
492  }
493 
495  postModuleStreamCheck(sc, mcc);
496  }
497 
499  preModuleStreamCheck(sc, mcc);
500  }
501 
503  postModuleStreamCheck(sc, mcc);
504  }
505 
507  ModuleCallingContext const& mcc) {
508  preModuleStreamCheck(sc, mcc);
509  }
510 
512  ModuleCallingContext const& mcc) {
513  postModuleStreamCheck(sc, mcc);
514  }
515 
517  preModuleStreamCheck(sc, mcc);
518  }
519 
521  ModuleCallingContext const& mcc) {
522  postModuleStreamCheck(sc, mcc);
523  }
524 
526  ModuleCallingContext const& mcc) {
527  preModuleStreamCheck(sc, mcc);
528  }
529 
531  ModuleCallingContext const& mcc) {
532  postModuleStreamCheck(sc, mcc);
533  }
534 
536  ModuleCallingContext const& mcc) {
537  preModuleStreamCheck(sc, mcc);
538  }
539 
541  ModuleCallingContext const& mcc) {
542  postModuleStreamCheck(sc, mcc);
543  }
544 
545  std::vector<RandomEngineState> const& RandomNumberGeneratorService::getLumiCache(
546  LuminosityBlockIndex const& lumiIndex) const {
547  return lumiCache_.at(lumiIndex.value());
548  }
549 
550  std::vector<RandomEngineState> const& RandomNumberGeneratorService::getEventCache(StreamID const& streamID) const {
551  return eventCache_.at(streamID.value());
552  }
553 
554  void RandomNumberGeneratorService::print(std::ostream& os) const {
555  os << "\n\nRandomNumberGeneratorService dump\n\n";
556 
557  os << " Contents of seedsAndNameMap (label moduleID engineType seeds)\n";
558  for (auto const& entry : seedsAndNameMap_) {
559  os << " " << entry.first << " " << entry.second.moduleID() << " " << entry.second.engineName();
560  for (auto val : entry.second.seeds()) {
561  os << " " << val;
562  }
563  os << "\n";
564  }
565  os << " nStreams_ = " << nStreams_ << "\n";
566  os << " saveFileName_ = " << saveFileName_ << "\n";
567  os << " saveFileNameRecorded_ = " << saveFileNameRecorded_ << "\n";
568  os << " restoreFileName_ = " << restoreFileName_ << "\n";
569  os << " enableChecking_ = " << enableChecking_ << "\n";
570  os << " eventSeedOffset_ = " << eventSeedOffset_ << "\n";
571  os << " verbose_ = " << verbose_ << "\n";
572  os << " restoreStateTag_ = " << restoreStateTag_ << "\n";
573  os << " restoreStateBeginLumiTag_ = " << restoreStateBeginLumiTag_ << "\n";
574 
575  os << "\n streamEngines_\n";
576  unsigned int iStream = 0;
577  for (auto const& k : streamEngines_) {
578  os << " Stream " << iStream << "\n";
579  for (auto const& i : k) {
580  os << " " << i.label();
581  for (auto const& j : i.seeds()) {
582  os << " " << j;
583  }
584  os << " " << i.engine()->name();
585  if (i.engine()->name() == std::string("HepJamesRandom")) {
586  os << " " << i.engine()->getSeed();
587  } else if (i.engine()->name() == std::string("MixMaxRng")) {
588  os << " " << i.engine()->getSeed();
589  } else {
590  os << " engine does not know seeds";
591  }
592  os << "\n";
593  }
594  ++iStream;
595  }
596  os << "\n lumiEngines_\n";
597  unsigned int iLumi = 0;
598  for (auto const& k : lumiEngines_) {
599  os << " lumiIndex " << iLumi << "\n";
600  for (auto const& i : k) {
601  os << " " << i.label();
602  for (auto const& j : i.seeds()) {
603  os << " " << j;
604  }
605  os << " " << i.engine()->name();
606  if (i.engine()->name() == std::string("HepJamesRandom")) {
607  os << " " << i.engine()->getSeed();
608  } else if (i.engine()->name() == std::string("MixMaxRng")) {
609  os << " " << i.engine()->getSeed();
610  } else {
611  os << " engine does not know seeds";
612  }
613  os << "\n";
614  }
615  ++iLumi;
616  }
617  }
618 
620  if (enableChecking_) {
621  unsigned int moduleID = mcc.moduleDescription()->id();
622  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(sc.streamID().value());
623  ModuleIDToEngine target(nullptr, moduleID);
624  std::vector<ModuleIDToEngine>::iterator iter =
625  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
626  if (iter != moduleIDVector.end() && iter->moduleID() == moduleID) {
627  LabelAndEngine* labelAndEngine = iter->labelAndEngine();
628  iter->setEngineState(labelAndEngine->engine()->put());
629  }
630  }
631  }
632 
634  if (enableChecking_) {
635  unsigned int moduleID = mcc.moduleDescription()->id();
636  std::vector<ModuleIDToEngine>& moduleIDVector = streamModuleIDToEngine_.at(sc.streamID().value());
637  ModuleIDToEngine target(nullptr, moduleID);
638  std::vector<ModuleIDToEngine>::iterator iter =
639  std::lower_bound(moduleIDVector.begin(), moduleIDVector.end(), target);
640  if (iter != moduleIDVector.end() && iter->moduleID() == moduleID) {
641  LabelAndEngine* labelAndEngine = iter->labelAndEngine();
642  if (iter->engineState() != labelAndEngine->engine()->put()) {
644  << "It is illegal to generate random numbers during beginStream, endStream,\n"
645  "beginRun, endRun, beginLumi, endLumi because that makes it very difficult\n"
646  "to replay the processing of individual events. Random numbers were\n"
647  "generated during one of these methods for the module with class name\n\""
648  << mcc.moduleDescription()->moduleName()
649  << "\" "
650  "and module label \""
651  << mcc.moduleDescription()->moduleLabel() << "\"\n";
652  }
653  }
654  }
655  }
656 
659  if (tns.isAvailable()) {
660  if (tns->getProcessName() == restoreStateTag_.process()) {
662  << "In the configuration for the RandomNumberGeneratorService the\n"
663  << "restoreStateTag contains the current process which is illegal.\n"
664  << "The process name in the replay process should have been changed\n"
665  << "to be different than the original process name and the restoreStateTag\n"
666  << "should contain either the original process name or an empty process name.\n";
667  }
668  }
669 
671  lumi.getByLabel(restoreStateBeginLumiTag_, states);
672 
673  if (!states.isValid()) {
675  << "The RandomNumberGeneratorService is trying to restore\n"
676  << "the state of the random engines by reading a product from\n"
677  << "the LuminosityBlock with input tag \"" << restoreStateBeginLumiTag_ << "\".\n"
678  << "It could not find the product.\n"
679  << "Either the product in the LuminosityBlock was dropped or\n"
680  << "not produced or the configured input tag is incorrect or there is a bug somewhere\n";
681  return;
682  }
683  states->getRandomEngineStates(lumiCache_.at(lumi.index()));
684  }
685 
688 
689  event.getByLabel(restoreStateTag_, states);
690 
691  if (!states.isValid()) {
693  << "The RandomNumberGeneratorService is trying to restore\n"
694  << "the state of the random engines by reading a product from\n"
695  << "the Event with input tag \"" << restoreStateTag_ << "\".\n"
696  << "It could not find the product.\n"
697  << "Either the product in the Event was dropped or\n"
698  << "not produced or the configured input tag is incorrect or there is a bug somewhere\n";
699  return;
700  }
701  states->getRandomEngineStates(eventCache_.at(event.streamID()));
702  }
703 
704  void RandomNumberGeneratorService::snapShot(std::vector<LabelAndEngine> const& engines,
705  std::vector<RandomEngineState>& cache) {
706  cache.resize(engines.size());
707  std::vector<RandomEngineState>::iterator state = cache.begin();
708 
709  for (std::vector<LabelAndEngine>::const_iterator iter = engines.begin(); iter != engines.end(); ++iter, ++state) {
710  std::string const& label = iter->label();
711  state->setLabel(label);
712  state->setSeed(iter->seeds());
713 
714  std::vector<unsigned long> stateL = iter->engine()->put();
715  state->clearStateVector();
716  state->reserveStateVector(stateL.size());
717  for (auto element : stateL) {
718  state->push_back_stateVector(static_cast<std::uint32_t>(element));
719  }
720  }
721  }
722 
723  void RandomNumberGeneratorService::restoreFromCache(std::vector<RandomEngineState> const& cache,
724  std::vector<LabelAndEngine>& engines) {
725  std::vector<LabelAndEngine>::iterator labelAndEngine = engines.begin();
726  for (auto const& cachedState : cache) {
727  std::string const& engineLabel = cachedState.getLabel();
728 
729  std::vector<std::uint32_t> const& engineState = cachedState.getState();
730  std::vector<unsigned long> engineStateL;
731  engineStateL.reserve(engineState.size());
732  for (auto const& value : engineState) {
733  engineStateL.push_back(static_cast<unsigned long>(value));
734  }
735 
736  std::vector<std::uint32_t> const& engineSeeds = cachedState.getSeed();
737  std::vector<long> engineSeedsL;
738  engineSeedsL.reserve(engineSeeds.size());
739  for (auto const& val : engineSeeds) {
740  long seedL = static_cast<long>(val);
741  engineSeedsL.push_back(seedL);
742 
743  // There is a dangerous conversion from std::uint32_t to long
744  // that occurs above. In the next 2 lines we check the
745  // behavior is what we need for the service to work
746  // properly. This conversion is forced on us by the
747  // CLHEP and ROOT interfaces. If the assert ever starts
748  // to fail we will have to come up with a way to deal
749  // with this.
750  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
751  assert(val == seedu32);
752  }
753 
754  assert(labelAndEngine != engines.end() && engineLabel == labelAndEngine->label());
755  std::shared_ptr<CLHEP::HepRandomEngine> const& engine = labelAndEngine->engine();
756 
757  // We need to handle each type of engine differently because each
758  // has different requirements on the seed or seeds.
759  if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::HepJamesRandom>()) {
760  checkEngineType(engine->name(), std::string("HepJamesRandom"), engineLabel);
761 
762  // These two lines actually restore the seed and engine state.
763  engine->setSeed(engineSeedsL[0], 0);
764  engine->get(engineStateL);
765 
766  labelAndEngine->setSeed(engineSeeds[0], 0);
767  } else if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::RanecuEngine>()) {
768  checkEngineType(engine->name(), std::string("RanecuEngine"), engineLabel);
769 
770  // This line actually restores the engine state.
771  engine->get(engineStateL);
772 
773  labelAndEngine->setSeed(engineSeeds[0], 0);
774  labelAndEngine->setSeed(engineSeeds[1], 1);
775  } else if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::MixMaxRng>()) {
776  checkEngineType(engine->name(), std::string("MixMaxRng"), engineLabel);
777 
778  // This line actually restores the engine state.
779  engine->setSeed(engineSeedsL[0], 0);
780  engine->get(engineStateL);
781 
782  labelAndEngine->setSeed(engineSeeds[0], 0);
783  } else if (engineStateL[0] == CLHEP::engineIDulong<TRandomAdaptor>()) {
784  checkEngineType(engine->name(), std::string("TRandom3"), engineLabel);
785 
786  // This line actually restores the engine state.
787  engine->setSeed(engineSeedsL[0], 0);
788  engine->get(engineStateL);
789 
790  labelAndEngine->setSeed(engineSeeds[0], 0);
791  } else {
792  // This should not be possible because this code should be able to restore
793  // any kind of engine whose state can be saved.
795  << "The RandomNumberGeneratorService is trying to restore the state\n"
796  "of the random engines. The state in the event indicates an engine\n"
797  "of an unknown type. This should not be possible unless you are\n"
798  "running with an old code release on a new file that was created\n"
799  "with a newer release which had new engine types added. In this case\n"
800  "the only solution is to use a newer release. In any other case, notify\n"
801  "the EDM developers because this should not be possible\n";
802  }
803  ++labelAndEngine;
804  }
805  }
806 
808  std::string const& typeFromEvent,
809  std::string const& engineLabel) const {
810  if (typeFromConfig != typeFromEvent) {
812  << "The RandomNumberGeneratorService is trying to restore\n"
813  << "the state of the random engine for the module \"" << engineLabel << "\". An\n"
814  << "error was detected because the type of the engine in the\n"
815  << "input file and the configuration file do not match.\n"
816  << "In the configuration file the type is \"" << typeFromConfig << "\".\nIn the input file the type is \""
817  << typeFromEvent << "\". If\n"
818  << "you are not generating any random numbers in this module, then\n"
819  << "remove the line in the configuration file that gives it\n"
820  << "a seed and the error will go away. Otherwise, you must give\n"
821  << "this module the same engine type in the configuration file or\n"
822  << "stop trying to restore the random engine state.\n";
823  }
824  }
825 
827  StreamID const& streamID,
829  std::ofstream& outFile = *outFiles_.at(streamID);
830 
831  if (!outFile.is_open()) {
832  std::stringstream file;
833  file << fileName;
834  if (nStreams_ > 1) {
835  file << "_" << streamID.value();
836  }
837 
838  outFile.open(file.str().c_str(), std::ofstream::out | std::ofstream::trunc);
839 
840  if (!outFile) {
842  << "Unable to open the file \"" << file.str() << "\" to save the state of the random engines.\n";
843  }
844  }
845 
846  outFile.seekp(0, std::ios_base::beg);
847  outFile << "<RandomEngineStates>\n";
848 
849  outFile << "<Event>\n";
850  writeStates(eventCache_.at(streamID), outFile);
851  outFile << "</Event>\n";
852 
853  outFile << "<Lumi>\n";
855  outFile << "</Lumi>\n";
856 
857  outFile << "</RandomEngineStates>\n";
858  outFile.flush();
859  }
860 
861  void RandomNumberGeneratorService::writeStates(std::vector<RandomEngineState> const& v, std::ofstream& outFile) {
862  for (auto& state : v) {
863  std::vector<std::uint32_t> const& seedVector = state.getSeed();
864  std::vector<std::uint32_t>::size_type seedVectorLength = seedVector.size();
865 
866  std::vector<std::uint32_t> const& stateVector = state.getState();
867  std::vector<std::uint32_t>::size_type stateVectorLength = stateVector.size();
868 
869  outFile << "<ModuleLabel>\n" << state.getLabel() << "\n</ModuleLabel>\n";
870 
871  outFile << "<SeedLength>\n" << seedVectorLength << "\n</SeedLength>\n";
872  outFile << "<InitialSeeds>\n";
873  writeVector(seedVector, outFile);
874  outFile << "</InitialSeeds>\n";
875  outFile << "<FullStateLength>\n" << stateVectorLength << "\n</FullStateLength>\n";
876  outFile << "<FullState>\n";
877  writeVector(stateVector, outFile);
878  outFile << "</FullState>\n";
879  }
880  }
881 
883  if (v.empty())
884  return;
885  size_t numItems = v.size();
886  for (size_t i = 0; i < numItems; ++i) {
887  if (i != 0 && i % 10 == 0)
888  outFile << "\n";
889  outFile << std::setw(13) << v[i];
890  }
891  outFile << "\n";
892  }
893 
895  char directory[1500];
896  std::string fullName(getcwd(directory, sizeof(directory)) ? directory : "/PathIsTooBig");
897  fullName += "/" + saveFileName_;
898  return fullName;
899  }
900 
902  std::vector<RandomEngineState>& cache) {
903  std::string whichStates("<Event>");
904  readStatesFromFile(fileName, cache, whichStates);
905  }
906 
908  std::vector<RandomEngineState>& cache) {
909  std::string whichStates("<Lumi>");
910  readStatesFromFile(fileName, cache, whichStates);
911  }
912 
914  std::vector<RandomEngineState>& cache,
915  std::string const& whichStates) {
916  std::ifstream inFile;
917  inFile.open(fileName.c_str(), std::ifstream::in);
918  if (!inFile) {
920  << "Unable to open the file \"" << fileName << "\" to restore the random engine states.\n";
921  }
922 
924  inFile >> text;
925  if (!inFile.good() || text != std::string("<RandomEngineStates>")) {
927  << "Attempting to read file with random number engine states.\n"
928  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
929  << "Cannot read the file header word.\n";
930  }
931  bool saveToCache = false;
932  while (readEngineState(inFile, cache, whichStates, saveToCache)) {
933  }
934  }
935 
937  std::vector<RandomEngineState>& cache,
938  std::string const& whichStates,
939  bool& saveToCache) {
940  std::string leading;
941  std::string trailing;
944  std::vector<std::uint32_t> seedVector;
946  std::vector<std::uint32_t> stateVector;
947 
948  // First we need to look for the special strings
949  // that mark the end of the file and beginning and
950  // and end of the data for different sections.
951 
952  is >> leading;
953  if (!is.good()) {
955  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
956  << "Cannot read next field and did not hit the end yet.\n";
957  }
958 
959  // This marks the end of the file. We are done.
960  if (leading == std::string("</RandomEngineStates>"))
961  return false;
962 
963  // This marks the end of a section of the data
964  if (leading == std::string("</Event>") || leading == std::string("</Lumi>")) {
965  saveToCache = false;
966  return true;
967  }
968 
969  // This marks the beginning of a section
970  if (leading == std::string("<Event>") || leading == std::string("<Lumi>")) {
971  saveToCache = (leading == whichStates);
972  return true;
973  }
974 
975  // Process the next engine state
976 
977  is >> moduleLabel >> trailing;
978  if (!is.good() || leading != std::string("<ModuleLabel>") || trailing != std::string("</ModuleLabel>")) {
980  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
981  << "Cannot read a module label when restoring random engine states.\n";
982  }
983 
984  is >> leading >> seedVectorSize >> trailing;
985  if (!is.good() || leading != std::string("<SeedLength>") || trailing != std::string("</SeedLength>")) {
987  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
988  << "Cannot read seed vector length when restoring random engine states.\n";
989  }
990 
991  is >> leading;
992  if (!is.good() || leading != std::string("<InitialSeeds>")) {
994  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
995  << "Cannot read beginning of InitialSeeds when restoring random engine states.\n";
996  }
997 
998  if (seedVectorSize > maxSeeds) {
1000  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1001  << "The number of seeds exceeds 64K.\n";
1002  }
1003 
1004  readVector(is, seedVectorSize, seedVector);
1005 
1006  is >> trailing;
1007  if (!is.good() || trailing != std::string("</InitialSeeds>")) {
1009  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1010  << "Cannot read end of InitialSeeds when restoring random engine states.\n";
1011  }
1012 
1013  is >> leading >> stateVectorSize >> trailing;
1014  if (!is.good() || leading != std::string("<FullStateLength>") || trailing != std::string("</FullStateLength>")) {
1016  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1017  << "Cannot read state vector length when restoring random engine states.\n";
1018  }
1019 
1020  is >> leading;
1021  if (!is.good() || leading != std::string("<FullState>")) {
1023  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1024  << "Cannot read beginning of FullState when restoring random engine states.\n";
1025  }
1026 
1027  if (stateVectorSize > maxStates) {
1029  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1030  << "The number of states exceeds 64K.\n";
1031  }
1032 
1033  readVector(is, stateVectorSize, stateVector);
1034 
1035  is >> trailing;
1036  if (!is.good() || trailing != std::string("</FullState>")) {
1038  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1039  << "Cannot read end of FullState when restoring random engine states.\n";
1040  }
1041 
1042  if (saveToCache) {
1043  RandomEngineState randomEngineState;
1044  randomEngineState.setLabel(moduleLabel);
1045  std::vector<RandomEngineState>::iterator state =
1046  std::lower_bound(cache.begin(), cache.end(), randomEngineState);
1047 
1048  if (state != cache.end() && moduleLabel == state->getLabel()) {
1049  if (seedVector.size() != state->getSeed().size() || stateVector.size() != state->getState().size()) {
1051  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1052  << "Vectors containing engine state are the incorrect size for the type of random engine.\n";
1053  }
1054  state->setSeed(seedVector);
1055  state->setState(stateVector);
1056  }
1057  }
1058  return true;
1059  }
1060 
1061  void RandomNumberGeneratorService::readVector(std::istream& is, unsigned numItems, std::vector<std::uint32_t>& v) {
1062  v.clear();
1063  v.reserve(numItems);
1064  std::uint32_t data;
1065  for (unsigned i = 0; i < numItems; ++i) {
1066  is >> data;
1067  if (!is.good()) {
1069  << "File \"" << restoreFileName_ << "\" is ill-structured or otherwise corrupted.\n"
1070  << "Cannot read vector when restoring random engine states.\n";
1071  }
1072  v.push_back(data);
1073  }
1074  }
1075 
1076  void RandomNumberGeneratorService::createEnginesInVector(std::vector<LabelAndEngine>& engines,
1077  unsigned int seedOffset,
1078  unsigned int eventSeedOffset,
1079  std::vector<ModuleIDToEngine>& moduleIDVector) {
1080  // The vectors we will fill here will be the same size as
1081  // or smaller than seedsAndNameMap_.
1082  engines.reserve(seedsAndNameMap_.size());
1083  moduleIDVector.reserve(seedsAndNameMap_.size());
1084 
1085  for (auto const& i : seedsAndNameMap_) {
1086  unsigned int moduleID = i.second.moduleID();
1087  if (moduleID != std::numeric_limits<unsigned int>::max()) {
1088  std::string const& label = i.first;
1089  std::string const& name = i.second.engineName();
1090  VUint32 const& seeds = i.second.seeds();
1091 
1092  if (name == "RanecuEngine") {
1093  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::RanecuEngine>();
1094  engines.emplace_back(label, seeds, engine);
1095  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1096  }
1097  // For the other engines, one seed is required
1098  else {
1099  long int seedL = static_cast<long int>(seeds[0]);
1100 
1101  if (name == "HepJamesRandom") {
1102  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::HepJamesRandom>(seedL);
1103  engines.emplace_back(label, seeds, engine);
1104  if (seedOffset != 0 || eventSeedOffset != 0) {
1105  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1106  }
1107  } else if (name == "MixMaxRng") {
1108  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<CLHEP::MixMaxRng>(seedL);
1109  engines.emplace_back(label, seeds, engine);
1110  if (seedOffset != 0 || eventSeedOffset != 0) {
1111  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1112  }
1113  } else { // TRandom3, currently the only other possibility
1114 
1115  // There is a dangerous conversion from std::uint32_t to long
1116  // that occurs above. In the next 2 lines we check the
1117  // behavior is what we need for the service to work
1118  // properly. This conversion is forced on us by the
1119  // CLHEP and ROOT interfaces. If the assert ever starts
1120  // to fail we will have to come up with a way to deal
1121  // with this.
1122  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
1123  assert(seeds[0] == seedu32);
1124 
1125  std::shared_ptr<CLHEP::HepRandomEngine> engine = std::make_shared<TRandomAdaptor>(seedL);
1126  engines.emplace_back(label, seeds, engine);
1127  if (seedOffset != 0 || eventSeedOffset != 0) {
1128  resetEngineSeeds(engines.back(), name, seeds, seedOffset, eventSeedOffset);
1129  }
1130  }
1131  }
1132  moduleIDVector.emplace_back(&engines.back(), moduleID);
1133  } // if moduleID valid
1134  } // loop over seedsAndMap
1135  std::sort(moduleIDVector.begin(), moduleIDVector.end());
1136  }
1137 
1139  std::string const& engineName,
1140  VUint32 const& seeds,
1141  std::uint32_t offset1,
1142  std::uint32_t offset2) {
1143  if (engineName == "RanecuEngine") {
1144  assert(seeds.size() == 2U);
1145  // Wrap around if the offsets push the seed over the maximum allowed value
1146  std::uint32_t mod = maxSeedRanecu + 1U;
1147  offset1 %= mod;
1148  offset2 %= mod;
1149  std::uint32_t seed0 = (seeds[0] + offset1) % mod;
1150  seed0 = (seed0 + offset2) % mod;
1151  labelAndEngine.setSeed(seed0, 0);
1152  labelAndEngine.setSeed(seeds[1], 1);
1153  long int seedL[2];
1154  seedL[0] = static_cast<long int>(seed0);
1155  seedL[1] = static_cast<long int>(seeds[1]);
1156  labelAndEngine.engine()->setSeeds(seedL, 0);
1157  } else {
1158  assert(seeds.size() == 1U);
1159 
1160  if (engineName == "HepJamesRandom" || engineName == "MixMaxRng") {
1161  // Wrap around if the offsets push the seed over the maximum allowed value
1162  std::uint32_t mod = maxSeedHepJames + 1U;
1163  offset1 %= mod;
1164  offset2 %= mod;
1165  std::uint32_t seed0 = (seeds[0] + offset1) % mod;
1166  seed0 = (seed0 + offset2) % mod;
1167  labelAndEngine.setSeed(seed0, 0);
1168 
1169  long int seedL = static_cast<long int>(seed0);
1170  labelAndEngine.engine()->setSeed(seedL, 0);
1171  } else {
1172  assert(engineName == "TRandom3");
1173  // Wrap around if the offsets push the seed over the maximum allowed value
1174  // We have to be extra careful with this one because it may also go beyond
1175  // the values 32 bits can hold
1176  std::uint32_t max32 = maxSeedTRandom3;
1177  std::uint32_t seed0 = seeds[0];
1178  if ((max32 - seed0) >= offset1) {
1179  seed0 += offset1;
1180  } else {
1181  seed0 = offset1 - (max32 - seed0) - 1U;
1182  }
1183  if ((max32 - seed0) >= offset2) {
1184  seed0 += offset2;
1185  } else {
1186  seed0 = offset2 - (max32 - seed0) - 1U;
1187  }
1188  labelAndEngine.setSeed(seed0, 0);
1189 
1190  long seedL = static_cast<long>(seed0);
1191 
1192  // There is a dangerous conversion from std::uint32_t to long
1193  // that occurs above. In the next 2 lines we check the
1194  // behavior is what we need for the service to work
1195  // properly. This conversion is forced on us by the
1196  // CLHEP and ROOT interfaces. If the assert ever starts
1197  // to fail we will have to come up with a way to deal
1198  // with this.
1199  std::uint32_t seedu32 = static_cast<std::uint32_t>(seedL);
1200  assert(seed0 == seedu32);
1201 
1202  labelAndEngine.engine()->setSeed(seedL, 0);
1203  }
1204  }
1205  }
1206  } // namespace service
1207 } // namespace edm
void writeStates(std::vector< RandomEngineState > const &v, std::ofstream &outFile)
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.
std::shared_ptr< CLHEP::HepRandomEngine const > engine() const
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
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)
ModuleDescription const * moduleDescription() const noexcept
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
void watchPreBeginJob(PreBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
bool isValid() const
Definition: HandleBase.h:70
void watchPreEndJob(PreEndJob::slot_type const &iSlot)
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:80
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
void preBeginJob(PathsAndConsumesOfModulesBase const &, ProcessContext const &)
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal