Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-20 02:14:57

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 <unistd.h>
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     usleep(25000);
0192   }
0193 
0194   if (dump_) {
0195     edm::Service<edm::RandomNumberGenerator> rng;
0196     std::cout << "*** TestRandomNumberServiceGlobal analyze " << rng->mySeed() << "  "
0197               << rng->getEngine(streamID).name() << " streamID= " << streamID
0198               << " multiStreamReplay: " << multiStreamReplay_ << "\n";
0199   }
0200 
0201   TestRandomNumberServiceStreamCache* cache = streamCache(streamID);
0202 
0203   assert(cache->countEvents_ < maxEvents_);
0204 
0205   edm::Service<edm::RandomNumberGenerator> rng;
0206   CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0207 
0208   if (cache->serviceEngine_ != &engine) {
0209     throw cms::Exception("TestRandomNumberService")
0210         << "TestRandomNumberServiceGlobal::analyze: Engines from event and beginStream are not the same";
0211   }
0212 
0213   // Generate some random numbers for tests purposes
0214   double randomNumberEvent0_ = engine.flat();
0215   double randomNumberEvent1_ = engine.flat();
0216   double randomNumberEvent2_ = engine.flat();
0217 
0218   // Generate one using a distribution to exercise that possibility also
0219   CLHEP::RandExponential expDist(engine);
0220   double mean = 10.0;  // Mean of the exponential
0221   double randomNumberEvent3_ = expDist.fire(mean);
0222 
0223   if (dump_) {
0224     std::cout << "     " << engine.name() << " " << randomNumberEvent0_ << " " << randomNumberEvent1_ << " "
0225               << randomNumberEvent2_ << " " << randomNumberEvent3_ << std::endl;
0226   }
0227 
0228   // Write them to a text file
0229   cache->outFile_ << rng->mySeed() << "\n";
0230   cache->outFile_ << randomNumberEvent0_ << "\n";
0231   cache->outFile_ << randomNumberEvent1_ << "\n";
0232   cache->outFile_ << randomNumberEvent2_ << "\n";
0233   cache->outFile_ << randomNumberEvent3_ << "\n";
0234 
0235   if (!multiStreamReplay_) {
0236     // Compare with the reference numbers when not skipping events at the beginning
0237     if (skippedEvents_.size() == 1 && skippedEvents_[0] == 0) {
0238       if (randomNumberEvent0_ != cache->referenceRandomNumbers_.at(0 + 4 * cache->countEvents_) ||
0239           randomNumberEvent1_ != cache->referenceRandomNumbers_.at(1 + 4 * cache->countEvents_) ||
0240           randomNumberEvent2_ != cache->referenceRandomNumbers_.at(2 + 4 * cache->countEvents_) ||
0241           randomNumberEvent3_ != cache->referenceRandomNumbers_.at(3 + 4 * cache->countEvents_)) {
0242         throw cms::Exception("TestRandomNumberService")
0243             << "TestRandomNumberServiceGlobal::analyze: Random sequence does not match expected sequence";
0244       }
0245       // Now compare when skipping events
0246     } else if (cache->countEvents_ < skippedEvents_.size()) {
0247       if (randomNumberEvent0_ != cache->referenceRandomNumbers_.at(
0248                                      0 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0249           randomNumberEvent1_ != cache->referenceRandomNumbers_.at(
0250                                      1 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0251           randomNumberEvent2_ != cache->referenceRandomNumbers_.at(
0252                                      2 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_))) ||
0253           randomNumberEvent3_ != cache->referenceRandomNumbers_.at(
0254                                      3 + 4 * (cache->countEvents_ + skippedEvents_.at(cache->countEvents_)))) {
0255         throw cms::Exception("TestRandomNumberService")
0256             << "TestRandomNumberServiceGlobal::analyze: Random sequence does not match expected sequence";
0257       }
0258     }
0259   }
0260 
0261   // Save the random numbers for the last event
0262   // This string gets overwritten on each event
0263   // and printed at endStream
0264   {
0265     std::ostringstream ss;
0266     ss << moduleDescription().moduleLabel() << " ";
0267     ss << engine.name() << " ";
0268     ss << "Last event random numbers ";
0269     ss << randomNumberEvent0_ << " ";
0270     ss << randomNumberEvent1_ << " ";
0271     ss << randomNumberEvent2_ << " ";
0272     ss << randomNumberEvent3_ << "\n";
0273     cache->lastEventRandomNumbers_ = ss.str();
0274   }
0275 
0276   // Print the numbers to a file for each event
0277   if (nStreams_ > 1) {
0278     {
0279       std::lock_guard<std::mutex> lock(write_mutex);
0280       std::ostringstream ss;
0281       if (multiStreamReplay_) {
0282         ss << "replay";
0283       }
0284       ss << "testRandomServiceL" << event.eventAuxiliary().luminosityBlock() << "E" << event.eventAuxiliary().event()
0285          << ".txt";
0286       std::string filename = ss.str();
0287 
0288       std::ofstream outFile;
0289       outFile.open(filename.c_str(), std::ofstream::app);
0290 
0291       outFile << moduleDescription().moduleLabel() << " ";
0292       outFile << engine.name() << " ";
0293 
0294       outFile << "Event random numbers ";
0295       outFile << randomNumberEvent0_ << " ";
0296       outFile << randomNumberEvent1_ << " ";
0297       outFile << randomNumberEvent2_ << " ";
0298       outFile << randomNumberEvent3_ << "\n";
0299 
0300       outFile.close();
0301     }
0302   }
0303 
0304   ++cache->countEvents_;
0305 }
0306 
0307 void TestRandomNumberServiceGlobal::beginJob() {
0308   if (dump_) {
0309     bool exceptionThrown = true;
0310     try {
0311       edm::Service<edm::RandomNumberGenerator> rng;
0312       unsigned int mySeed = rng->mySeed();
0313       std::cout << "*** TestRandomNumberServiceGlobal beginJob " << mySeed << "\n";
0314       exceptionThrown = false;
0315     } catch (cms::Exception const&) {
0316     }
0317     if (not exceptionThrown) {
0318       throw cms::Exception("FailedToThrow") << "RandomNunberGenerator::mySeed did not throw";
0319     }
0320   }
0321 }
0322 
0323 void TestRandomNumberServiceGlobal::endJob() {
0324   if (dump_) {
0325     bool exceptionThrown = true;
0326     try {
0327       edm::Service<edm::RandomNumberGenerator> rng;
0328       unsigned int mySeed = rng->mySeed();
0329       std::cout << "*** TestRandomNumberServiceGlobal endJob " << mySeed << "\n";
0330       exceptionThrown = false;
0331     } catch (cms::Exception const&) {
0332     }
0333     if (not exceptionThrown) {
0334       throw cms::Exception("FailedToThrow") << "RandomNunberGenerator::mySeed did not throw";
0335     }
0336   }
0337 }
0338 
0339 std::shared_ptr<TestRandomNumberServiceLumiCache> TestRandomNumberServiceGlobal::globalBeginLuminosityBlock(
0340     edm::LuminosityBlock const& lumi, edm::EventSetup const& iES) const {
0341   if (dump_) {
0342     edm::Service<edm::RandomNumberGenerator> rng;
0343     std::cout << "*** TestRandomNumberServiceGlobal beginLuminosityBlock " << rng->mySeed() << "  "
0344               << rng->getEngine(lumi.index()).name() << "\n";
0345   }
0346 
0347   auto lumiCache = std::make_shared<TestRandomNumberServiceLumiCache>();
0348 
0349   unsigned int seed0 = seeds_.at(0) + nStreams_;
0350   if (lumi.luminosityBlockAuxiliary().luminosityBlock() < seedByLumi_.size()) {
0351     seed0 = seedByLumi_.at(lumi.luminosityBlockAuxiliary().luminosityBlock());
0352   }
0353 
0354   if (engineName_ == "RanecuEngine") {
0355     lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0356         new CLHEP::RanecuEngine());  // propagate_const<T> has no reset() function
0357     long int seedL[2];
0358     seedL[0] = static_cast<long int>(seed0);
0359     seedL[1] = static_cast<long int>(seeds_.at(1));
0360     lumiCache->referenceEngine_->setSeeds(seedL, 0);
0361   } else {
0362     long int seedL = static_cast<long int>(seed0);
0363     if (engineName_ == "HepJamesRandom") {
0364       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0365           new CLHEP::HepJamesRandom(seedL));  // propagate_const<T> has no reset() function
0366     } else if (engineName_ == "MixMaxRng") {
0367       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0368           new CLHEP::MixMaxRng(seedL));  // propagate_const<T> has no reset() function
0369     } else {
0370       lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0371           new edm::TRandomAdaptor(seedL));  // propagate_const<T> has no reset() function
0372     }
0373   }
0374 
0375   double y1 = lumiCache->referenceEngine_->flat();
0376   double y2 = lumiCache->referenceEngine_->flat();
0377 
0378   edm::Service<edm::RandomNumberGenerator> rng;
0379   CLHEP::HepRandomEngine& engine = rng->getEngine(lumi.index());
0380   std::unique_ptr<CLHEP::HepRandomEngine> engineClone = rng->cloneEngine(lumi.index());
0381 
0382   double x1 = engine.flat();
0383   double x2 = engine.flat();
0384 
0385   if (x1 != y1 || x2 != y2) {
0386     throw cms::Exception("TestRandomNumberService")
0387         << "TestRandomNumberServiceGlobal::globalBeginLuminosityBlock:  "
0388         << " x1= " << x1 << " y1= " << y1 << " x2= " << x2 << " y2= " << y2 << " " << engine.name() << " "
0389         << lumiCache->referenceEngine_->name() << " seed0= " << seed0 << " nStream= " << nStreams_;
0390   }
0391 
0392   double z1 = engineClone->flat();
0393   double z2 = engineClone->flat();
0394   if (x1 != z1 || x2 != z2 || engine.getSeed() != engineClone->getSeed()) {
0395     throw cms::Exception("TestRandomNumberService")
0396         << "TestRandomNumberServiceGlobal::globalBeginLuminosityBlock:  test of cloned engine failed "
0397         << " x1= " << x1 << " z1= " << z1 << " x2= " << x2 << " z2= " << z2 << " " << engine.name() << " "
0398         << engineClone->name() << " seed0= " << seed0 << " nStream= " << nStreams_;
0399   }
0400   return lumiCache;
0401 }
0402 
0403 std::unique_ptr<TestRandomNumberServiceStreamCache> TestRandomNumberServiceGlobal::beginStream(
0404     edm::StreamID streamID) const {
0405   auto streamCache = std::make_unique<TestRandomNumberServiceStreamCache>();
0406 
0407   edm::Service<edm::RandomNumberGenerator> rng;
0408   CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0409 
0410   // Running this will causing the checking code to throw an exception
0411   // Uncomment to verify the checking works
0412   // engine.flat();
0413 
0414   streamCache->serviceEngine_ = &engine;
0415 
0416   std::ostringstream suffix;
0417   suffix << "_" << streamID.value() << "_" << moduleDescription().moduleLabel();
0418   std::string outFileName = std::string("testRandomService") + suffix.str() + std::string(".txt");
0419   streamCache->outFile_.open(outFileName.c_str(), std::ofstream::out);
0420 
0421   if (engineName_ == "RanecuEngine") {
0422     streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0423         new CLHEP::RanecuEngine());  // propagate_const<T> has no reset() function
0424     long int seedL[2];
0425     seedL[0] = static_cast<long int>(seeds_.at(0) + streamID.value() + offset_);
0426     seedL[1] = static_cast<long int>(seeds_.at(1));
0427     streamCache->referenceEngine_->setSeeds(seedL, 0);
0428   } else {
0429     long int seedL = static_cast<long int>(seeds_.at(0) + streamID.value() + offset_);
0430     if (engineName_ == "HepJamesRandom") {
0431       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0432           new CLHEP::HepJamesRandom(seedL));  // propagate_const<T> has no reset() function
0433     } else if (engineName_ == "MixMaxRng") {
0434       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0435           new CLHEP::MixMaxRng(seedL));  // propagate_const<T> has no reset() function
0436     } else {
0437       streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0438           new edm::TRandomAdaptor(seedL));  // propagate_const<T> has no reset() function
0439     }
0440   }
0441 
0442   for (unsigned int i = 0; i < maxEvents_; ++i) {
0443     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0444     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0445     streamCache->referenceRandomNumbers_.push_back(streamCache->referenceEngine_->flat());
0446     CLHEP::RandExponential expDist(*streamCache->referenceEngine_);
0447     double mean = 10.0;
0448     streamCache->referenceRandomNumbers_.push_back(expDist.fire(mean));
0449   }
0450   return streamCache;
0451 }
0452 
0453 void TestRandomNumberServiceGlobal::endStream(edm::StreamID streamID) const {
0454   TestRandomNumberServiceStreamCache* cache = streamCache(streamID);
0455 
0456   std::ostringstream ss;
0457   if (multiStreamReplay_) {
0458     ss << "replay";
0459   }
0460   ss << "stream" << streamID.value() << "LastEvent.txt";
0461   std::string filename = ss.str();
0462 
0463   std::ofstream outFile;
0464   {
0465     std::lock_guard<std::mutex> lock(write_mutex);
0466     outFile.open(filename.c_str(), std::ofstream::app);
0467     outFile << cache->lastEventRandomNumbers_;
0468     outFile.close();
0469   }
0470 
0471   // Running this will causing the checking code to throw an exception
0472   // Uncomment to verify the checking works
0473   // edm::Service<edm::RandomNumberGenerator> rng;
0474   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0475   // engine.flat();
0476 }
0477 
0478 void TestRandomNumberServiceGlobal::streamBeginRun(edm::StreamID streamID,
0479                                                    edm::Run const&,
0480                                                    edm::EventSetup const&) const {
0481   // Running this will causing the checking code to throw an exception
0482   // Uncomment to verify the checking works
0483   // edm::Service<edm::RandomNumberGenerator> rng;
0484   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0485   // engine.flat();
0486 }
0487 
0488 void TestRandomNumberServiceGlobal::streamEndRun(edm::StreamID streamID,
0489                                                  edm::Run const&,
0490                                                  edm::EventSetup const&) const {
0491   // Running this will causing the checking code to throw an exception
0492   // Uncomment to verify the checking works
0493   // edm::Service<edm::RandomNumberGenerator> rng;
0494   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0495   // engine.flat();
0496 }
0497 
0498 void TestRandomNumberServiceGlobal::streamBeginLuminosityBlock(edm::StreamID streamID,
0499                                                                edm::LuminosityBlock const&,
0500                                                                edm::EventSetup const&) const {
0501   // Running this will causing the checking code to throw an exception
0502   // Uncomment to verify the checking works
0503   // edm::Service<edm::RandomNumberGenerator> rng;
0504   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0505   // engine.flat();
0506 }
0507 
0508 void TestRandomNumberServiceGlobal::streamEndLuminosityBlock(edm::StreamID streamID,
0509                                                              edm::LuminosityBlock const&,
0510                                                              edm::EventSetup const&) const {
0511   // Running this will causing the checking code to throw an exception
0512   // Uncomment to verify the checking works
0513   // edm::Service<edm::RandomNumberGenerator> rng;
0514   // CLHEP::HepRandomEngine& engine = rng->getEngine(streamID);
0515   // engine.flat();
0516 }
0517 
0518 //define this as a plug-in
0519 DEFINE_FWK_MODULE(TestRandomNumberServiceGlobal);