CMS 3D CMS Logo

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