File indexing completed on 2023-03-17 11:10:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
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
0146
0147
0148 std::vector<unsigned int> seedByLumi_;
0149
0150 bool multiStreamReplay_;
0151
0152
0153
0154
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
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
0214 double randomNumberEvent0_ = engine.flat();
0215 double randomNumberEvent1_ = engine.flat();
0216 double randomNumberEvent2_ = engine.flat();
0217
0218
0219 CLHEP::RandExponential expDist(engine);
0220 double mean = 10.0;
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
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
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
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
0262
0263
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
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());
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));
0366 } else if (engineName_ == "MixMaxRng") {
0367 lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0368 new CLHEP::MixMaxRng(seedL));
0369 } else {
0370 lumiCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0371 new edm::TRandomAdaptor(seedL));
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
0411
0412
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());
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));
0433 } else if (engineName_ == "MixMaxRng") {
0434 streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0435 new CLHEP::MixMaxRng(seedL));
0436 } else {
0437 streamCache->referenceEngine_ = std::shared_ptr<CLHEP::HepRandomEngine>(
0438 new edm::TRandomAdaptor(seedL));
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
0472
0473
0474
0475
0476 }
0477
0478 void TestRandomNumberServiceGlobal::streamBeginRun(edm::StreamID streamID,
0479 edm::Run const&,
0480 edm::EventSetup const&) const {
0481
0482
0483
0484
0485
0486 }
0487
0488 void TestRandomNumberServiceGlobal::streamEndRun(edm::StreamID streamID,
0489 edm::Run const&,
0490 edm::EventSetup const&) const {
0491
0492
0493
0494
0495
0496 }
0497
0498 void TestRandomNumberServiceGlobal::streamBeginLuminosityBlock(edm::StreamID streamID,
0499 edm::LuminosityBlock const&,
0500 edm::EventSetup const&) const {
0501
0502
0503
0504
0505
0506 }
0507
0508 void TestRandomNumberServiceGlobal::streamEndLuminosityBlock(edm::StreamID streamID,
0509 edm::LuminosityBlock const&,
0510 edm::EventSetup const&) const {
0511
0512
0513
0514
0515
0516 }
0517
0518
0519 DEFINE_FWK_MODULE(TestRandomNumberServiceGlobal);