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