CMS 3D CMS Logo

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