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