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