Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-03 05:27:09

0001 // -*- C++ -*-
0002 //
0003 // Package:    IOMC/RandomEngine
0004 // Class:      TestRandomNumberServiceGlobal
0005 //
0006 /**\class TestRandomNumberServiceGlobal
0007 
0008 Description: Used in tests of the RandomNumberGeneratorService.
0009 
0010 Implementation:
0011 
0012 This module should not be used with the multiprocess mode
0013 that forks processes.
0014 
0015 Dumps to std::cout some initialization information from
0016 the RandomNumberGeneratorService so that this output can
0017 be compared to reference files.
0018 
0019 This module will create it own random engines and generate
0020 the random numbers it expects the service to produce
0021 and do a comparison with the numbers the engines from
0022 the service actually generate. This does not work to test
0023 multistream replay jobs because we do not know which
0024 streams will contain which events so this check is not done
0025 in those cases.
0026 
0027 Creates a set of text file with names like the following:
0028 testRandomService_0_t1.txt where the first number is the stream
0029 and the second number is the module name. It contains the
0030 configured first seed and some random numbers generated by the
0031 module on each event.
0032 
0033 For jobs with more than one stream, it writes a file named
0034 testRandomServiceL1E1 or replaytestRandomServiceL1E1.txt where
0035 the numbers in the name change to reflect the lumi and event
0036 numbers. One file is written per event. Note the order each
0037 modules data appears can vary if modules are run concurrently.
0038 This is used to test the replay mode where the engine states
0039 are written into the event and luminosity block for multistream
0040 jobs.
0041 
0042 Always writes random numbers generated in the last event in
0043 each module to a file named stream0LastEvent.txt or
0044 replaystream0LastEvent.txt. The filename depends on whether
0045 the "replayMultiStream" configuration parameter has been set. Note
0046 that the order the module data is written can vary
0047 if modules can be run in parallel. This is used in the
0048 test of replay of an event in a multistream job with
0049 the text file containing the states.
0050 
0051 */
0052 //
0053 // Original Author:  Chris Jones, David Dagenhart
0054 //         Created:  Tue Mar  7 11:57:09 EST 2006
0055 //
0056 
0057 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
0058 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
0059 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0060 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0061 #include "FWCore/Framework/interface/Event.h"
0062 #include "FWCore/Framework/interface/LuminosityBlock.h"
0063 #include "FWCore/Framework/interface/MakerMacros.h"
0064 #include "FWCore/ServiceRegistry/interface/Service.h"
0065 #include "FWCore/Utilities/interface/Exception.h"
0066 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0067 #include "FWCore/Utilities/interface/propagate_const.h"
0068 #include "IOMC/RandomEngine/interface/TRandomAdaptor.h"
0069 
0070 #include "CLHEP/Random/RandExponential.h"
0071 #include "CLHEP/Random/RandomEngine.h"
0072 #include "CLHEP/Random/engineIDulong.h"
0073 #include "CLHEP/Random/JamesRandom.h"
0074 #include "CLHEP/Random/RanecuEngine.h"
0075 #include "CLHEP/Random/MixMaxRng.h"
0076 
0077 #include <fstream>
0078 #include <iostream>
0079 #include <memory>
0080 #include <mutex>
0081 #include <sstream>
0082 #include <string>
0083 #include <chrono>
0084 
0085 namespace {
0086   std::mutex write_mutex;
0087 }
0088 
0089 class TestRandomNumberServiceStreamCache {
0090 public:
0091   TestRandomNumberServiceStreamCache() : serviceEngine_(nullptr), countEvents_(0) {}
0092   edm::propagate_const<CLHEP::HepRandomEngine*> serviceEngine_;
0093   unsigned int countEvents_;
0094   std::ofstream outFile_;
0095   std::string lastEventRandomNumbers_;
0096 
0097   edm::propagate_const<std::shared_ptr<CLHEP::HepRandomEngine>> referenceEngine_;
0098   std::vector<double> referenceRandomNumbers_;
0099 };
0100 
0101 class TestRandomNumberServiceLumiCache {
0102 public:
0103   TestRandomNumberServiceLumiCache() {}
0104   edm::propagate_const<std::shared_ptr<CLHEP::HepRandomEngine>> referenceEngine_;
0105   std::vector<double> referenceRandomNumbers_;
0106 };
0107 
0108 class TestRandomNumberServiceGlobal
0109     : public edm::global::EDAnalyzer<edm::StreamCache<TestRandomNumberServiceStreamCache>,
0110                                      edm::LuminosityBlockCache<TestRandomNumberServiceLumiCache>> {
0111 public:
0112   explicit TestRandomNumberServiceGlobal(edm::ParameterSet const&);
0113   ~TestRandomNumberServiceGlobal();
0114 
0115   virtual void analyze(edm::StreamID, edm::Event const&, edm::EventSetup const&) const override;
0116   virtual void beginJob() override;
0117   virtual void endJob() override;
0118 
0119   virtual std::shared_ptr<TestRandomNumberServiceLumiCache> globalBeginLuminosityBlock(
0120       edm::LuminosityBlock const&, edm::EventSetup const&) const override;
0121 
0122   virtual void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const override {}
0123 
0124   virtual std::unique_ptr<TestRandomNumberServiceStreamCache> beginStream(edm::StreamID) const override;
0125   virtual void endStream(edm::StreamID) const override;
0126 
0127   virtual void streamBeginRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const override;
0128   virtual void streamEndRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const override;
0129 
0130   virtual void streamBeginLuminosityBlock(edm::StreamID,
0131                                           edm::LuminosityBlock const&,
0132                                           edm::EventSetup const&) const override;
0133   virtual void streamEndLuminosityBlock(edm::StreamID,
0134                                         edm::LuminosityBlock const&,
0135                                         edm::EventSetup const&) const override;
0136 
0137 private:
0138   std::string engineName_;
0139   std::vector<unsigned int> seeds_;
0140   unsigned int offset_;
0141   unsigned int maxEvents_;
0142   unsigned int nStreams_;
0143   std::vector<unsigned int> skippedEvents_;
0144 
0145   // If size larger than 1, the seed for each lumi engine is the
0146   // entry in this vector, where the lumi number is the index into
0147   // the vector. Only needed in replay.
0148   std::vector<unsigned int> seedByLumi_;
0149 
0150   bool multiStreamReplay_;
0151 
0152   // Dump is only intended to be set true for single stream jobs and
0153   // only for one module. Otherwise there will be issues with
0154   // interleaved output.
0155   bool dump_;
0156 };
0157 
0158 TestRandomNumberServiceGlobal::TestRandomNumberServiceGlobal(edm::ParameterSet const& pset)
0159     : engineName_(pset.getUntrackedParameter<std::string>("engineName")),
0160       seeds_(pset.getUntrackedParameter<std::vector<unsigned int>>("seeds")),
0161       offset_(pset.getUntrackedParameter<unsigned int>("offset")),
0162       maxEvents_(pset.getUntrackedParameter<unsigned int>("maxEvents")),
0163       nStreams_(pset.getUntrackedParameter<unsigned int>("nStreams")),
0164       skippedEvents_(
0165           pset.getUntrackedParameter<std::vector<unsigned int>>("skippedEvents", std::vector<unsigned int>(1, 0))),
0166       seedByLumi_(pset.getUntrackedParameter<std::vector<unsigned int>>("seedByLumi", std::vector<unsigned int>(1, 0))),
0167       multiStreamReplay_(pset.getUntrackedParameter<bool>("multiStreamReplay", false)),
0168       dump_(pset.getUntrackedParameter<bool>("dump", false)) {
0169   if (dump_) {
0170     edm::Service<edm::RandomNumberGenerator> rng;
0171     bool exceptionThrown = true;
0172     try {
0173       unsigned int mySeed = rng->mySeed();
0174       std::cout << "*** TestRandomNumberServiceGlobal constructor " << mySeed << "\n";
0175       exceptionThrown = false;
0176     } catch (cms::Exception const&) {
0177     }
0178     if (not exceptionThrown) {
0179       throw cms::Exception("FailedToThrow") << "RandomNunberGenerator::mySeed did not throw";
0180     }
0181   }
0182 }
0183 
0184 TestRandomNumberServiceGlobal::~TestRandomNumberServiceGlobal() {}
0185 
0186 void TestRandomNumberServiceGlobal::analyze(edm::StreamID streamID,
0187                                             edm::Event const& event,
0188                                             edm::EventSetup const&) const {
0189   // Add some sleep to encourage all the streams to get events to process.
0190   if (nStreams_ > 1) {
0191     using namespace std::chrono_literals;
0192     std::this_thread::sleep_for(25ms);
0193   }
0194 
0195   if (dump_) {
0196     edm::Service<edm::RandomNumberGenerator> rng;
0197     std::cout << "*** TestRandomNumberServiceGlobal analyze " << rng->mySeed() << "  "
0198               << rng->getEngine(streamID).name() << " streamID= " << streamID
0199               << " multiStreamReplay: " << multiStreamReplay_ << "\n";
0200   }
0201 
0202   TestRandomNumberServiceStreamCache* cache = streamCache(streamID);
0203 
0204   assert(cache->countEvents_ < maxEvents_);
0205 
0206   edm::Service<edm::RandomNumberGenerator> rng;
0207   CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0208 
0209   if (cache->serviceEngine_ != &engine) {
0210     throw cms::Exception("TestRandomNumberService")
0211         << "TestRandomNumberServiceGlobal::analyze: Engines from event and beginStream are not the same";
0212   }
0213 
0214   // Generate some random numbers for tests purposes
0215   double randomNumberEvent0_ = engine.flat();
0216   double randomNumberEvent1_ = engine.flat();
0217   double randomNumberEvent2_ = engine.flat();
0218 
0219   // Generate one using a distribution to exercise that possibility also
0220   CLHEP::RandExponential expDist(engine);
0221   double mean = 10.0;  // Mean of the exponential
0222   double randomNumberEvent3_ = expDist.fire(mean);
0223 
0224   if (dump_) {
0225     std::cout << "     " << engine.name() << " " << randomNumberEvent0_ << " " << randomNumberEvent1_ << " "
0226               << randomNumberEvent2_ << " " << randomNumberEvent3_ << std::endl;
0227   }
0228 
0229   // Write them to a text file
0230   cache->outFile_ << rng->mySeed() << "\n";
0231   cache->outFile_ << randomNumberEvent0_ << "\n";
0232   cache->outFile_ << randomNumberEvent1_ << "\n";
0233   cache->outFile_ << randomNumberEvent2_ << "\n";
0234   cache->outFile_ << randomNumberEvent3_ << "\n";
0235 
0236   if (!multiStreamReplay_) {
0237     // Compare with the reference numbers when not skipping events at the beginning
0238     if (skippedEvents_.size() == 1 && skippedEvents_[0] == 0) {
0239       if (randomNumberEvent0_ != cache->referenceRandomNumbers_.at(0 + 4 * cache->countEvents_) ||
0240           randomNumberEvent1_ != cache->referenceRandomNumbers_.at(1 + 4 * cache->countEvents_) ||
0241           randomNumberEvent2_ != cache->referenceRandomNumbers_.at(2 + 4 * cache->countEvents_) ||
0242           randomNumberEvent3_ != cache->referenceRandomNumbers_.at(3 + 4 * cache->countEvents_)) {
0243         throw cms::Exception("TestRandomNumberService")
0244             << "TestRandomNumberServiceGlobal::analyze: Random sequence does not match expected sequence";
0245       }
0246       // Now compare when skipping events
0247     } else if (cache->countEvents_ < skippedEvents_.size()) {
0248       if (randomNumberEvent0_ != cache->referenceRandomNumbers_.at(
0249                                      0 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0250           randomNumberEvent1_ != cache->referenceRandomNumbers_.at(
0251                                      1 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0252           randomNumberEvent2_ != cache->referenceRandomNumbers_.at(
0253                                      2 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0254           randomNumberEvent3_ != cache->referenceRandomNumbers_.at(
0255                                      3 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_)))) {
0256         throw cms::Exception("TestRandomNumberService")
0257             << "TestRandomNumberServiceGlobal::analyze: Random sequence does not match expected sequence";
0258       }
0259     }
0260   }
0261 
0262   // Save the random numbers for the last event
0263   // This string gets overwritten on each event
0264   // and printed at endStream
0265   {
0266     std::ostringstream ss;
0267     ss << moduleDescription().moduleLabel() << " ";
0268     ss << engine.name() << " ";
0269     ss << "Last event random numbers ";
0270     ss << randomNumberEvent0_ << " ";
0271     ss << randomNumberEvent1_ << " ";
0272     ss << randomNumberEvent2_ << " ";
0273     ss << randomNumberEvent3_ << "\n";
0274     cache->lastEventRandomNumbers_ = ss.str();
0275   }
0276 
0277   // Print the numbers to a file for each event
0278   if (nStreams_ > 1) {
0279     {
0280       std::lock_guard<std::mutex> lock(write_mutex);
0281       std::ostringstream ss;
0282       if (multiStreamReplay_) {
0283         ss << "replay";
0284       }
0285       ss << "testRandomServiceL" << event.eventAuxiliary().luminosityBlock() << "E" << event.eventAuxiliary().event()
0286          << ".txt";
0287       std::string filename = ss.str();
0288 
0289       std::ofstream outFile;
0290       outFile.open(filename.c_str(), std::ofstream::app);
0291 
0292       outFile << moduleDescription().moduleLabel() << " ";
0293       outFile << engine.name() << " ";
0294 
0295       outFile << "Event random numbers ";
0296       outFile << randomNumberEvent0_ << " ";
0297       outFile << randomNumberEvent1_ << " ";
0298       outFile << randomNumberEvent2_ << " ";
0299       outFile << randomNumberEvent3_ << "\n";
0300 
0301       outFile.close();
0302     }
0303   }
0304 
0305   ++cache->countEvents_;
0306 }
0307 
0308 void TestRandomNumberServiceGlobal::beginJob() {
0309   if (dump_) {
0310     bool exceptionThrown = true;
0311     try {
0312       edm::Service<edm::RandomNumberGenerator> rng;
0313       unsigned int mySeed = rng->mySeed();
0314       std::cout << "*** TestRandomNumberServiceGlobal beginJob " << mySeed << "\n";
0315       exceptionThrown = false;
0316     } catch (cms::Exception const&) {
0317     }
0318     if (not exceptionThrown) {
0319       throw cms::Exception("FailedToThrow") << "RandomNunberGenerator::mySeed did not throw";
0320     }
0321   }
0322 }
0323 
0324 void TestRandomNumberServiceGlobal::endJob() {
0325   if (dump_) {
0326     bool exceptionThrown = true;
0327     try {
0328       edm::Service<edm::RandomNumberGenerator> rng;
0329       unsigned int mySeed = rng->mySeed();
0330       std::cout << "*** TestRandomNumberServiceGlobal endJob " << mySeed << "\n";
0331       exceptionThrown = false;
0332     } catch (cms::Exception const&) {
0333     }
0334     if (not exceptionThrown) {
0335       throw cms::Exception("FailedToThrow") << "RandomNunberGenerator::mySeed did not throw";
0336     }
0337   }
0338 }
0339 
0340 std::shared_ptr<TestRandomNumberServiceLumiCache> TestRandomNumberServiceGlobal::globalBeginLuminosityBlock(
0341     edm::LuminosityBlock const& lumi, edm::EventSetup const& iES) const {
0342   if (dump_) {
0343     edm::Service<edm::RandomNumberGenerator> rng;
0344     std::cout << "*** TestRandomNumberServiceGlobal beginLuminosityBlock " << rng->mySeed() << "  "
0345               << rng->getEngine(lumi.index()).name() << "\n";
0346   }
0347 
0348   auto lumiCache = std::make_shared<TestRandomNumberServiceLumiCache>();
0349 
0350   unsigned int seed0 = seeds_.at(0) + nStreams_;
0351   if (lumi.luminosityBlockAuxiliary().luminosityBlock() < seedByLumi_.size()) {
0352     seed0 = seedByLumi_.at(lumi.luminosityBlockAuxiliary().luminosityBlock());
0353   }
0354 
0355   if (engineName_ == "RanecuEngine") {
0356     lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0357         new CLHEP::RanecuEngine());  // propagate_const<T> has no reset() function
0358     long int seedL[2];
0359     seedL[0] = static_cast<long int>(seed0);
0360     seedL[1] = static_cast<long int>(seeds_.at(1));
0361     lumiCache->referenceEngine_->setSeeds(seedL, 0);
0362   } else {
0363     long int seedL = static_cast<long int>(seed0);
0364     if (engineName_ == "HepJamesRandom") {
0365       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0366           new CLHEP::HepJamesRandom(seedL));  // propagate_const<T> has no reset() function
0367     } else if (engineName_ == "MixMaxRng") {
0368       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0369           new CLHEP::MixMaxRng(seedL));  // propagate_const<T> has no reset() function
0370     } else {
0371       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0372           new edm::TRandomAdaptor(seedL));  // propagate_const<T> has no reset() function
0373     }
0374   }
0375 
0376   double y1 = lumiCache->referenceEngine_->flat();
0377   double y2 = lumiCache->referenceEngine_->flat();
0378 
0379   edm::Service<edm::RandomNumberGenerator> rng;
0380   CLHEP::HepRandomEngine& engine = rng->getEngine(lumi.index());
0381   std::unique_ptr<CLHEP::HepRandomEngine> engineClone = rng->cloneEngine(lumi.index());
0382 
0383   double x1 = engine.flat();
0384   double x2 = engine.flat();
0385 
0386   if (x1 != y1 || x2 != y2) {
0387     throw cms::Exception("TestRandomNumberService")
0388         << "TestRandomNumberServiceGlobal::globalBeginLuminosityBlock:  "
0389         << " x1= " << x1 << " y1= " << y1 << " x2= " << x2 << " y2= " << y2 << " " << engine.name() << " "
0390         << lumiCache->referenceEngine_->name() << " seed0= " << seed0 << " nStream= " << nStreams_;
0391   }
0392 
0393   double z1 = engineClone->flat();
0394   double z2 = engineClone->flat();
0395   if (x1 != z1 || x2 != z2 || engine.getSeed() != engineClone->getSeed()) {
0396     throw cms::Exception("TestRandomNumberService")
0397         << "TestRandomNumberServiceGlobal::globalBeginLuminosityBlock:  test of cloned engine failed "
0398         << " x1= " << x1 << " z1= " << z1 << " x2= " << x2 << " z2= " << z2 << " " << engine.name() << " "
0399         << engineClone->name() << " seed0= " << seed0 << " nStream= " << nStreams_;
0400   }
0401   return lumiCache;
0402 }
0403 
0404 std::unique_ptr<TestRandomNumberServiceStreamCache> TestRandomNumberServiceGlobal::beginStream(
0405     edm::StreamID streamID) const {
0406   auto streamCache = std::make_unique<TestRandomNumberServiceStreamCache>();
0407 
0408   edm::Service<edm::RandomNumberGenerator> rng;
0409   CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0410 
0411   // Running this will causing the checking code to throw an exception
0412   // Uncomment to verify the checking works
0413   // engine.flat();
0414 
0415   streamCache->serviceEngine_ = &engine;
0416 
0417   std::ostringstream suffix;
0418   suffix << "_" << streamID.value() << "_" << moduleDescription().moduleLabel();
0419   std::string outFileName = std::string("testRandomService") + suffix.str() + std::string(".txt");
0420   streamCache->outFile_.open(outFileName.c_str(), std::ofstream::out);
0421 
0422   if (engineName_ == "RanecuEngine") {
0423     streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0424         new CLHEP::RanecuEngine());  // propagate_const<T> has no reset() function
0425     long int seedL[2];
0426     seedL[0] = static_cast<long int>(seeds_.at(0) + streamID.value() + offset_);
0427     seedL[1] = static_cast<long int>(seeds_.at(1));
0428     streamCache->referenceEngine_->setSeeds(seedL, 0);
0429   } else {
0430     long int seedL = static_cast<long int>(seeds_.at(0) + streamID.value() + offset_);
0431     if (engineName_ == "HepJamesRandom") {
0432       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0433           new CLHEP::HepJamesRandom(seedL));  // propagate_const<T> has no reset() function
0434     } else if (engineName_ == "MixMaxRng") {
0435       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0436           new CLHEP::MixMaxRng(seedL));  // propagate_const<T> has no reset() function
0437     } else {
0438       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0439           new edm::TRandomAdaptor(seedL));  // propagate_const<T> has no reset() function
0440     }
0441   }
0442 
0443   for (unsigned int i = 0; i < maxEvents_; ++i) {
0444     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0445     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0446     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0447     CLHEP::RandExponential expDist(*streamCache->referenceEngine_);
0448     double mean = 10.0;
0449     streamCache->referenceRandomNumbers_.push_back(expDist.fire(mean));
0450   }
0451   return streamCache;
0452 }
0453 
0454 void TestRandomNumberServiceGlobal::endStream(edm::StreamID streamID) const {
0455   TestRandomNumberServiceStreamCache* cache = streamCache(streamID);
0456 
0457   std::ostringstream ss;
0458   if (multiStreamReplay_) {
0459     ss << "replay";
0460   }
0461   ss << "stream" << streamID.value() << "LastEvent.txt";
0462   std::string filename = ss.str();
0463 
0464   std::ofstream outFile;
0465   {
0466     std::lock_guard<std::mutex> lock(write_mutex);
0467     outFile.open(filename.c_str(), std::ofstream::app);
0468     outFile << cache->lastEventRandomNumbers_;
0469     outFile.close();
0470   }
0471 
0472   // Running this will causing the checking code to throw an exception
0473   // Uncomment to verify the checking works
0474   // edm::Service<edm::RandomNumberGenerator> rng;
0475   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0476   // engine.flat();
0477 }
0478 
0479 void TestRandomNumberServiceGlobal::streamBeginRun(edm::StreamID streamID,
0480                                                    edm::Run const&,
0481                                                    edm::EventSetup const&) const {
0482   // Running this will causing the checking code to throw an exception
0483   // Uncomment to verify the checking works
0484   // edm::Service<edm::RandomNumberGenerator> rng;
0485   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0486   // engine.flat();
0487 }
0488 
0489 void TestRandomNumberServiceGlobal::streamEndRun(edm::StreamID streamID,
0490                                                  edm::Run const&,
0491                                                  edm::EventSetup const&) const {
0492   // Running this will causing the checking code to throw an exception
0493   // Uncomment to verify the checking works
0494   // edm::Service<edm::RandomNumberGenerator> rng;
0495   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0496   // engine.flat();
0497 }
0498 
0499 void TestRandomNumberServiceGlobal::streamBeginLuminosityBlock(edm::StreamID streamID,
0500                                                                edm::LuminosityBlock const&,
0501                                                                edm::EventSetup const&) const {
0502   // Running this will causing the checking code to throw an exception
0503   // Uncomment to verify the checking works
0504   // edm::Service<edm::RandomNumberGenerator> rng;
0505   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0506   // engine.flat();
0507 }
0508 
0509 void TestRandomNumberServiceGlobal::streamEndLuminosityBlock(edm::StreamID streamID,
0510                                                              edm::LuminosityBlock const&,
0511                                                              edm::EventSetup const&) const {
0512   // Running this will causing the checking code to throw an exception
0513   // Uncomment to verify the checking works
0514   // edm::Service<edm::RandomNumberGenerator> rng;
0515   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0516   // engine.flat();
0517 }
0518 
0519 //define this as a plug-in
0520 DEFINE_FWK_MODULE(TestRandomNumberServiceGlobal);