CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions
edm::RandomNumberGenerator Class Referenceabstract

#include <RandomNumberGenerator.h>

Inheritance diagram for edm::RandomNumberGenerator:
edm::service::RandomNumberGeneratorService

Public Member Functions

virtual void consumes (ConsumesCollector &&iC) const =0
 
virtual CLHEP::HepRandomEngine & getEngine (StreamID const &)=0
 Use this engine in event methods. More...
 
virtual CLHEP::HepRandomEngine & getEngine (LuminosityBlockIndex const &)=0
 Use this engine in the global begin luminosity block method. More...
 
virtual std::vector< RandomEngineState > const & getEventCache (StreamID const &) const =0
 
virtual std::vector< RandomEngineState > const & getLumiCache (LuminosityBlockIndex const &) const =0
 
virtual std::uint32_t mySeed () const =0
 
virtual void postEventRead (Event const &event)=0
 
virtual void preBeginLumi (LuminosityBlock const &lumi)=0
 
virtual void print (std::ostream &os) const =0
 For debugging purposes only. More...
 
 RandomNumberGenerator ()
 
virtual ~RandomNumberGenerator ()
 

Private Member Functions

RandomNumberGenerator const & operator= (RandomNumberGenerator const &)=delete
 
 RandomNumberGenerator (RandomNumberGenerator const &)=delete
 

Detailed Description

Description: Interface for obtaining random number engines.

Usage: This class is the abstract interface to a Service which provides access to the random number engines which are used to generate random numbers. One accesses the service using the Service system.

edm::Service<edm::RandomNumberGenerator> rng; CLHEP::HepRandomEngine& engine = rng->getEngine(streamID); or CLHEP::HepRandomEngine& engine = rng->getEngine(luminosityBlockIndex);

The RandomNumberGenerator automatically knows what module is requesting an engine and will return the proper one for that module.

For each module the service will hold one engine per stream. In addition, for each module the service will hold a number of engines equal to the number of LuminosityBlocks that can be processed concurrently. When running a multithreaded process the correct engine for the current module and streamID/luminosityBlockIndex must be used to avoid data races. This is also important for replay.

A source cannot use this service and sources should not generate random numbers (otherwise replay will fail).

Random numbers should only be generated in two functions of a module, the function used to process the Event and also the global beginLuminosityBlock function. Random numbers should not be generated at any other time, not in the constructor, not at beginJob, not at beginRun ... Note that this restriction applies to generating the random numbers. If one is only calling the function getEngine that takes a streamID argument then it is also OK to call it in the beginStream method, but only to get the reference to the engine and save it or save a pointer to it (but not to generate any random numbers in beginStream).

The service owns the engines and handles memory management for them.

The service does a lot of work behind the scenes to allow one to replay specific events of a prior process. There are two different mechanisms.

First, if the parameter named "saveFileName" is set the state of the random engines will be written to a text file before each event is processed. This text file is overwritten at each event. If a job crashes while processing an event, then one can replay the processing of the event where the crash occurred and get the same random number sequences. For jobs with more than 1 thread or forked processes, the text files are named by appending "_" and a number to the "saveFileName" parameter, where the number is either the child index of the forked process or the streamID of the stream which processed the event.

Second, if the RandomEngineStateProducer module is executed the state of all the engines managed by this service can be saved to both the Event and LuminosityBlock. Then in a later process, the RandomNumberGenerator is capable of restoring the state of the engines in order to be able to exactly replay the earlier process starting at any event without having to replay the entire process.

This service performs its tasks so that the random sequences are independent sequences with different seeds for two cases:

  1. Multiprocess jobs where processes are forked
  2. Multithread jobs where multiple threads are used

It is assumed that we will never run jobs that are both multiprocess and multithread. The service seeding algorithm will fail to produce independent sequences if that is attempted.

Three warnings.

  1. When there is more than one LuminosityBlock in a single process, the random number engines used in global begin luminosity block are reset to the same starting state before each call to that function (except in replay mode). This allows the initialization performed in all of them to be identical. Don't expect unique sequences in different calls to beginLuminosityBlock.
  2. In multiprocess jobs, the engines are reinitialized after the processes are forked with new seeds equal to the original seed plus the child index. In multithread jobs, the stream sequences are initialized in a similar way by adding the streamID to the seed to form a new seed for each stream. The seeds for the engines for the luminosity blocks are all the same and the original seed plus the number of streams or the number of forked child processes is used. In existing work management schemes this works well, because the initial configured seed is derived randomly and the seeds in different jobs should not be close to one another. If not using one of these work management schemes, one has to be careful to not configure seeds in multiple jobs that are close enough together to overlap (closer than the number of forked processes or streams). For example, if one generated the original configured seed for a job using the previous jobs seed and adding one, then there would be a problem.
  3. This service properly handles modules running concurrently and generating random numbers, but not concurrent submodule tasks. If a module creates its own subtasks that are run concurrently and generate numbers, then using the engines from the service will result in data races. If this design if ever needed, one possible approach would be for each submodule task that needs random numbers to create its own engine and seed it using a random number from the module random engine. There might be better ways.

There are more details explaining this service on a TWIKI page which can be accessed through a link on the Framework TWIKI page of the SWGuide.

Author
Chris Jones and W. David Dagenhart, created March 7, 2006

Definition at line 146 of file RandomNumberGenerator.h.

Constructor & Destructor Documentation

edm::RandomNumberGenerator::RandomNumberGenerator ( )
inline

Definition at line 150 of file RandomNumberGenerator.h.

References ecalTB2006H4_GenSimDigiReco_cfg::mySeed, and reco::print().

150 {}
edm::RandomNumberGenerator::~RandomNumberGenerator ( )
virtual

Definition at line 4 of file RandomNumberGenerator.cc.

4 {}
edm::RandomNumberGenerator::RandomNumberGenerator ( RandomNumberGenerator const &  )
privatedelete

Member Function Documentation

virtual void edm::RandomNumberGenerator::consumes ( ConsumesCollector &&  iC) const
pure virtual
virtual CLHEP::HepRandomEngine& edm::RandomNumberGenerator::getEngine ( StreamID const &  )
pure virtual

Use this engine in event methods.

Use the next 2 functions to get the random number engine. These are the only functions most modules should call.

Implemented in edm::service::RandomNumberGeneratorService.

Referenced by cms::Phase2TrackerDigitizer::beginLuminosityBlock(), EcalDigiProducer::beginLuminosityBlock(), ElectronEnergyCalibrator::calibrate(), GaussianZBeamSpotFilter::filter(), edm::RandomFilter::filter(), cms::SiPixelDigitizer::finalizeEvent(), PhotonEnergyCalibratorRun2::gauss(), ElectronEnergyCalibratorRun2::gauss(), PhotonEnergyCalibrator::gauss(), ElectronEnergyCalibrator::gauss(), edm::FlatRandomMultiParticlePGunProducer::produce(), edm::FlatRandomPtThetaGunProducer::produce(), edm::GaussRandomPThetaGunProducer::produce(), edm::FlatRandomEThetaGunProducer::produce(), edm::FileRandomKEThetaGunProducer::produce(), edm::RandomtXiGunProducer::produce(), edm::FlatRandomOneOverPtGunProducer::produce(), CSCDigiProducer::produce(), edm::FlatRandomPtGunProducer::produce(), edm::FlatRandomEGunProducer::produce(), edm::ExpoRandomPtGunProducer::produce(), edm::MultiParticleInConeGunProducer::produce(), OscarProducer::produce(), edm::ExpoRandomPGunProducer::produce(), ME0DigiPreRecoProducer::produce(), BaseEvtVtxGenerator::produce(), edm::FlatRandomPtAndDxyGunProducer::produce(), RPCDigiProducer::produce(), EcalTBMCInfoProducer::produce(), GEMDigiProducer::produce(), ME0DigiProducer::produce(), RPCandIRPCDigiProducer::produce(), QjetsAdder::produce(), HectorProducer::produce(), OscarMTProducer::produce(), CTPPSHectorProducer::produce(), DigiSimLinkProducer::produce(), SubsystemNeutronWriter::produce(), EcalBarrelClusterFastTimer::produce(), L1EmulBias::produce(), L1DummyProducer::produce(), DTDigitizer::produce(), TrackTimeValueMapProducer::produce(), FFTJetVertexAdder::produce(), BetaBoostEvtVtxGenerator::produce(), ME0ReDigiProducer::produce(), RPCChamberMasker::produce(), DTChamberMasker::produce(), CTPPSRecHitProducer::produce(), CSCChamberMasker::produce(), EmbeddingLHEProducer::produce(), cms::HTTTopJetProducer::produce(), edm::DataMixingSiPixelMCDigiWorker::putSiPixel(), edm::DataMixingSiStripMCDigiWorker::putSiStrip(), HGCDigiProducer::randomEngine(), FTLDigiProducer::randomEngine(), HcalDigiProducer::randomEngine(), HcalTBDigiProducer::randomEngine(), CastorDigiProducer::randomEngine(), SiStripDigitizer::randomEngine(), cms::SiPixelDigitizer::randomEngine(), EcalDigiProducer::randomEngine(), EcalMixingModuleValidation::randomEngine(), and RandomEngineAndDistribution::RandomEngineAndDistribution().

virtual CLHEP::HepRandomEngine& edm::RandomNumberGenerator::getEngine ( LuminosityBlockIndex const &  )
pure virtual

Use this engine in the global begin luminosity block method.

Implemented in edm::service::RandomNumberGeneratorService.

virtual std::vector<RandomEngineState> const& edm::RandomNumberGenerator::getEventCache ( StreamID const &  ) const
pure virtual
virtual std::vector<RandomEngineState> const& edm::RandomNumberGenerator::getLumiCache ( LuminosityBlockIndex const &  ) const
pure virtual
virtual std::uint32_t edm::RandomNumberGenerator::mySeed ( ) const
pure virtual

This returns the seed from the configuration. In the unusual case where an an engine type takes multiple seeds to initialize a sequence, this function only returns the first. As a general rule, this function should not be used, but is available for backward compatibility and debugging. It might be useful for some types of tests. Using this to seed engines constructed in modules is not recommended because (unless done very carefully) it will create duplicate sequences in different threads and/or data races. Also, if engines are created by modules the replay mechanism will be broken. Because it is dangerous and could be misused, this function might be deleted someday if we ever find time to delete all uses of it in CMSSW. There are of order 10 last time I checked ...

Implemented in edm::service::RandomNumberGeneratorService.

Referenced by ExternalLHEProducer::beginRunProduce(), LaserBeamsTEC2::GeneratePrimaries(), LaserBeamsBarrel::GeneratePrimaries(), LaserBeamsTEC1::GeneratePrimaries(), and AlignableModifier::setSeed().

RandomNumberGenerator const& edm::RandomNumberGenerator::operator= ( RandomNumberGenerator const &  )
privatedelete
virtual void edm::RandomNumberGenerator::postEventRead ( Event const &  event)
pure virtual
virtual void edm::RandomNumberGenerator::preBeginLumi ( LuminosityBlock const &  lumi)
pure virtual
virtual void edm::RandomNumberGenerator::print ( std::ostream &  os) const
pure virtual

For debugging purposes only.

Implemented in edm::service::RandomNumberGeneratorService.