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