00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "IOMC/RandomEngine/src/RandomNumberGeneratorService.h"
00014
00015 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/LuminosityBlock.h"
00018 #include "FWCore/MessageLogger/interface/JobReport.h"
00019 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00022 #include "FWCore/ParameterSet/interface/ParameterWildcard.h"
00023 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00024 #include "FWCore/ServiceRegistry/interface/Service.h"
00025 #include "FWCore/Utilities/interface/EDMException.h"
00026 #include "IOMC/RandomEngine/src/TRandomAdaptor.h"
00027 #include "SimDataFormats/RandomEngine/interface/RandomEngineState.h"
00028 #include "SimDataFormats/RandomEngine/interface/RandomEngineStates.h"
00029
00030 #include "CLHEP/Random/engineIDulong.h"
00031 #include "CLHEP/Random/JamesRandom.h"
00032 #include "CLHEP/Random/RanecuEngine.h"
00033
00034 #include <iostream>
00035 #include <limits>
00036 #include <sstream>
00037 #include <unistd.h>
00038
00039 namespace edm {
00040 namespace service {
00041
00042 uint32_t RandomNumberGeneratorService::maxSeedRanecu = 2147483647U;
00043 uint32_t RandomNumberGeneratorService::maxSeedHepJames = 900000000U;
00044 uint32_t RandomNumberGeneratorService::maxSeedTRandom3 = 4294967295U;
00045
00046 RandomNumberGeneratorService::RandomNumberGeneratorService(ParameterSet const& pset,
00047 ActivityRegistry& activityRegistry):
00048 saveFileName_(pset.getUntrackedParameter<std::string>("saveFileName")),
00049 saveFileNameRecorded_(false),
00050 restoreFileName_(pset.getUntrackedParameter<std::string>("restoreFileName")),
00051 enableChecking_(pset.getUntrackedParameter<bool>("enableChecking")),
00052 firstLumi_(true),
00053 childIndex_(0U),
00054 eventSeedOffset_(pset.getUntrackedParameter<unsigned>("eventSeedOffset")),
00055 failedToFindStatesInLumi_(false) {
00056
00057 if(pset.exists("restoreStateTag")) {
00058 restoreStateTag_ = pset.getUntrackedParameter<edm::InputTag>("restoreStateTag");
00059 } else {
00060 restoreStateTag_ = edm::InputTag(pset.getUntrackedParameter<std::string>("restoreStateLabel"), "", "");
00061 }
00062 restoreStateBeginLumiTag_ = edm::InputTag(restoreStateTag_.label(), "beginLumi", restoreStateTag_.process());
00063
00064 if(!restoreFileName_.empty() && !restoreStateTag_.label().empty()) {
00065 throw Exception(errors::Configuration)
00066 << "In the configuration for the RandomNumberGeneratorService both\n"
00067 << "restoreFileName and restoreStateLabel were set to nonempty values\n"
00068 << "which is illegal. It is impossible to restore the random engine\n"
00069 << "states two different ways in the same process.\n";
00070 }
00071
00072
00073
00074 if(!saveFileName_.empty() && (saveFileName_.find("/") != std::string::npos)) {
00075 throw Exception(errors::Configuration)
00076 << "The saveFileName parameter must be a simple file name with no path\n"
00077 << "specification. In the configuration, it was given the value \""
00078 << saveFileName_ << "\"\n";
00079 }
00080
00081 uint32_t initialSeed;
00082 VUint32 initialSeedSet;
00083 std::string engineName;
00084
00085 VString pSets = pset.getParameterNamesForType<ParameterSet>();
00086 for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
00087
00088 ParameterSet const& modulePSet = pset.getParameterSet(*it);
00089 engineName = modulePSet.getUntrackedParameter<std::string>("engineName", std::string("HepJamesRandom"));
00090
00091 bool initialSeedExists = modulePSet.exists("initialSeed");
00092 bool initialSeedSetExists = modulePSet.exists("initialSeedSet");
00093
00094 if(initialSeedExists && initialSeedSetExists) {
00095 throw Exception(errors::Configuration)
00096 << "For the module with the label \"" << *it << "\",\n"
00097 << "both the parameters \"initialSeed\" and \"initialSeedSet\"\n"
00098 << "have been set in the configuration. You must set one or\n"
00099 << "the other. It is illegal to set both.\n";
00100 } else if(!initialSeedExists && !initialSeedSetExists) {
00101 throw Exception(errors::Configuration)
00102 << "For the module with the label \"" << *it << "\",\n"
00103 << "neither the parameter \"initialSeed\" nor \"initialSeedSet\"\n"
00104 << "has been set in the configuration. You must set one or\n"
00105 << "the other.\n";
00106 } else if(initialSeedExists) {
00107 initialSeed = modulePSet.getUntrackedParameter<uint32_t>("initialSeed");
00108 initialSeedSet.clear();
00109 initialSeedSet.push_back(initialSeed);
00110 } else if(initialSeedSetExists) {
00111 initialSeedSet = modulePSet.getUntrackedParameter<VUint32>("initialSeedSet");
00112 }
00113 seedMap_[*it] = initialSeedSet;
00114 engineNameMap_[*it] = engineName;
00115
00116
00117
00118 if(engineName == std::string("RanecuEngine")) {
00119 if(initialSeedSet.size() != 2U) {
00120 throw Exception(errors::Configuration)
00121 << "Random engines of type \"RanecuEngine\" require 2 seeds\n"
00122 << "be specified with the parameter named \"initialSeedSet\".\n"
00123 << "Either \"initialSeedSet\" was not in the configuration\n"
00124 << "or its size was not 2 for the module with label \"" << *it << "\".\n" ;
00125 }
00126 boost::shared_ptr<CLHEP::HepRandomEngine> engine(new CLHEP::RanecuEngine());
00127 engineMap_[*it] = engine;
00128
00129 if(initialSeedSet[0] > maxSeedRanecu ||
00130 initialSeedSet[1] > maxSeedRanecu) {
00131 throw Exception(errors::Configuration)
00132 << "The RanecuEngine seeds should be in the range 0 to 2147483647.\n"
00133 << "The seeds passed to the RandomNumberGenerationService from the\n"
00134 "configuration file were " << initialSeedSet[0] << " and " << initialSeedSet[1]
00135 << "\nThis was for the module with label \"" << *it << "\".\n";
00136 }
00137 long int seedL[2];
00138 seedL[0] = static_cast<long int>(initialSeedSet[0]);
00139 seedL[1] = static_cast<long int>(initialSeedSet[1]);
00140 engine->setSeeds(seedL, 0);
00141 }
00142
00143 else {
00144 if(initialSeedSet.size() != 1U) {
00145 throw Exception(errors::Configuration)
00146 << "Random engines of type \"HepJamesRandom\" and \"TRandom3\n"
00147 << "require exactly 1 seed be specified in the configuration.\n"
00148 << "There were " << initialSeedSet.size() << " seeds set for the\n"
00149 << "module with label \"" << *it << "\".\n" ;
00150 }
00151 long int seedL = static_cast<long int>(initialSeedSet[0]);
00152
00153 if(engineName == "HepJamesRandom") {
00154 if(initialSeedSet[0] > maxSeedHepJames) {
00155 throw Exception(errors::Configuration)
00156 << "The CLHEP::HepJamesRandom engine seed should be in the range 0 to 900000000.\n"
00157 << "The seed passed to the RandomNumberGenerationService from the\n"
00158 "configuration file was " << initialSeedSet[0] << ". This was for \n"
00159 << "the module with label " << *it << ".\n";
00160 }
00161 boost::shared_ptr<CLHEP::HepRandomEngine> engine(new CLHEP::HepJamesRandom(seedL));
00162 engineMap_[*it] = engine;
00163 } else if(engineName == "TRandom3") {
00164
00165
00166
00167
00168
00169
00170
00171
00172 uint32_t seedu32 = static_cast<uint32_t>(seedL);
00173 assert(initialSeedSet[0] == seedu32);
00174
00175 boost::shared_ptr<CLHEP::HepRandomEngine> engine(new TRandomAdaptor(seedL));
00176 engineMap_[*it] = engine;
00177 } else {
00178 throw Exception(errors::Configuration)
00179 << "The random engine name, \"" << engineName
00180 << "\", does not correspond to a supported engine.\n"
00181 << "This engine was configured for the module with label \"" << *it << "\"";
00182 }
00183 }
00184 }
00185
00186 activityRegistry.watchPostBeginLumi(this, &RandomNumberGeneratorService::postBeginLumi);
00187
00188 activityRegistry.watchPreModuleConstruction(this, &RandomNumberGeneratorService::preModuleConstruction);
00189 activityRegistry.watchPostModuleConstruction(this, &RandomNumberGeneratorService::postModuleConstruction);
00190
00191 activityRegistry.watchPreModuleBeginJob(this, &RandomNumberGeneratorService::preModuleBeginJob);
00192 activityRegistry.watchPostModuleBeginJob(this, &RandomNumberGeneratorService::postModuleBeginJob);
00193
00194 activityRegistry.watchPreModuleBeginRun(this, &RandomNumberGeneratorService::preModuleBeginRun);
00195 activityRegistry.watchPostModuleBeginRun(this, &RandomNumberGeneratorService::postModuleBeginRun);
00196
00197 activityRegistry.watchPreModuleBeginLumi(this, &RandomNumberGeneratorService::preModuleBeginLumi);
00198 activityRegistry.watchPostModuleBeginLumi(this, &RandomNumberGeneratorService::postModuleBeginLumi);
00199
00200 activityRegistry.watchPreModule(this, &RandomNumberGeneratorService::preModule);
00201 activityRegistry.watchPostModule(this, &RandomNumberGeneratorService::postModule);
00202
00203 activityRegistry.watchPreModuleEndLumi(this, &RandomNumberGeneratorService::preModuleEndLumi);
00204 activityRegistry.watchPostModuleEndLumi(this, &RandomNumberGeneratorService::postModuleEndLumi);
00205
00206 activityRegistry.watchPreModuleEndRun(this, &RandomNumberGeneratorService::preModuleEndRun);
00207 activityRegistry.watchPostModuleEndRun(this, &RandomNumberGeneratorService::postModuleEndRun);
00208
00209 activityRegistry.watchPreModuleEndJob(this, &RandomNumberGeneratorService::preModuleEndJob);
00210 activityRegistry.watchPostModuleEndJob(this, &RandomNumberGeneratorService::postModuleEndJob);
00211
00212 activityRegistry.watchPostForkReacquireResources(this, &RandomNumberGeneratorService::postForkReacquireResources);
00213
00214
00215 engineStack_.push_back(engineMap_.end());
00216 currentEngine_ = engineMap_.end();
00217
00218 labelStack_.push_back(std::string());
00219 currentLabel_ = std::string();
00220 }
00221
00222 RandomNumberGeneratorService::~RandomNumberGeneratorService() {
00223 }
00224
00225 CLHEP::HepRandomEngine&
00226 RandomNumberGeneratorService::getEngine() const {
00227
00228 if(currentEngine_ == engineMap_.end()) {
00229 if(currentLabel_ != std::string()) {
00230 throw Exception(errors::Configuration)
00231 << "The module with label \""
00232 << currentLabel_
00233 << "\" requested a random number engine from the \n"
00234 "RandomNumberGeneratorService, but that module was not configured\n"
00235 "for random numbers. An engine is created only if a seed(s) is provided\n"
00236 "in the configuration file. Please add the following PSet to the\n"
00237 "configuration file for the RandomNumberGeneratorService:\n\n"
00238 " " << currentLabel_ << " = cms.PSet(\n"
00239 " initialSeed = cms.untracked.uint32(your_seed),\n"
00240 " engineName = cms.untracked.string('TRandom3')\n"
00241 " )\n"
00242 "where you replace \"your_seed\" with a number and add a comma if necessary\n"
00243 "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
00244 } else {
00245 throw Exception(errors::Unknown)
00246 << "Requested a random number engine from the RandomNumberGeneratorService\n"
00247 "when no module was active. This is not supposed to be possible.\n"
00248 "Please inform the edm developers about this. It would be helpful to\n"
00249 "know the stack. If a source was requesting a random engine this could\n"
00250 "happen. Sources are not supposed to be doing that anymore.\n";
00251 }
00252 }
00253 return *(currentEngine_->second);
00254 }
00255
00256 uint32_t
00257 RandomNumberGeneratorService::mySeed() const {
00258
00259 std::map<std::string, VUint32>::const_iterator iter;
00260 iter = seedMap_.find(currentLabel_);
00261
00262 if(iter == seedMap_.end()) {
00263 if(currentLabel_ != std::string()) {
00264 throw Exception(errors::Configuration)
00265 << "The module with label \""
00266 << currentLabel_
00267 << "\" requested a random number seed from the \n"
00268 "RandomNumberGeneratorService, but that module was not configured\n"
00269 "for random numbers. An engine is created only if a seed(s) is provided\n"
00270 "in the configuration file. Please add the following PSet to the\n"
00271 "configuration file for the RandomNumberGeneratorService:\n\n"
00272 " " << currentLabel_ << " = cms.PSet(\n"
00273 " initialSeed = cms.untracked.uint32(your_seed),\n"
00274 " engineName = cms.untracked.string('TRandom3')\n"
00275 " )\n"
00276 "where you replace \"your_seed\" with a number and add a comma if necessary\n"
00277 "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
00278 } else {
00279 throw Exception(errors::Unknown)
00280 << "Requested a random number seed from the RandomNumberGeneratorService\n"
00281 "when no module was active. This is not supposed to be possible.\n"
00282 "Please inform the edm developers about this. It would be helpful to\n"
00283 "know the stack. If a source was requesting a random engine this could\n"
00284 "happen. Sources are not supposed to be doing that anymore.\n";
00285 }
00286 }
00287 return iter->second[0];
00288 }
00289
00290 void
00291 RandomNumberGeneratorService::fillDescriptions(ConfigurationDescriptions& descriptions) {
00292 ParameterSetDescription desc;
00293
00294 std::string emptyString;
00295 edm::InputTag emptyInputTag("", "", "");
00296
00297 desc.addNode( edm::ParameterDescription<edm::InputTag>("restoreStateTag", emptyInputTag, false) xor
00298 edm::ParameterDescription<std::string>("restoreStateLabel", emptyString, false) );
00299
00300 desc.addUntracked<std::string>("saveFileName", emptyString);
00301 desc.addUntracked<std::string>("restoreFileName", emptyString);
00302 desc.addUntracked<bool>("enableChecking", false);
00303 desc.addUntracked<unsigned>("eventSeedOffset", 0U);
00304
00305 ParameterSetDescription val;
00306 val.addOptionalUntracked<uint32_t>("initialSeed");
00307 val.addOptionalUntracked<std::vector<uint32_t> >("initialSeedSet");
00308 val.addOptionalUntracked<std::string>("engineName");
00309
00310 ParameterWildcard<ParameterSetDescription> wnode("*", RequireZeroOrMore, true, val);
00311 wnode.setComment("The name of each ParameterSet will be the associated module label.");
00312 desc.addNode(wnode);
00313
00314 descriptions.add("RandomNumberGeneratorService", desc);
00315 }
00316
00317 void
00318 RandomNumberGeneratorService::postForkReacquireResources(unsigned childIndex, unsigned ) {
00319 childIndex_ = childIndex;
00320
00321 if(!saveFileName_.empty()) {
00322 std::ostringstream suffix;
00323 suffix << "_" << childIndex;
00324 saveFileName_ += suffix.str();
00325 }
00326 }
00327
00328
00329
00330
00331
00332 void
00333 RandomNumberGeneratorService::preBeginLumi(LuminosityBlock const& lumi) {
00334
00335 if(firstLumi_) {
00336
00337 snapShot(lumiCache_);
00338
00339 if(!restoreFileName_.empty()) {
00340
00341 readLumiStatesFromTextFile(restoreFileName_);
00342 }
00343 } else {
00344 snapShot(eventCache_);
00345 }
00346
00347
00348 if(!restoreStateTag_.label().empty()) {
00349 readFromLuminosityBlock(lumi);
00350 }
00351
00352 if(!firstLumi_ || !restoreFileName_.empty() || !restoreStateTag_.label().empty()) {
00353
00354 restoreFromCache(lumiCache_);
00355 }
00356 }
00357
00358
00359
00360
00361
00362 void
00363 RandomNumberGeneratorService::postBeginLumi(LuminosityBlock const&, EventSetup const&) {
00364
00365 if(firstLumi_) {
00366
00367 startNewSequencesForEvents();
00368 if(!restoreFileName_.empty()) {
00369 snapShot(eventCache_);
00370
00371 readEventStatesFromTextFile(restoreFileName_);
00372 }
00373 }
00374 if(!firstLumi_ || !restoreFileName_.empty()) {
00375
00376 restoreFromCache(eventCache_);
00377 }
00378 firstLumi_ = false;
00379 }
00380
00381 void
00382 RandomNumberGeneratorService::postEventRead(Event const& event) {
00383
00384 if(!restoreStateTag_.label().empty()) {
00385 snapShot(eventCache_);
00386 readFromEvent(event);
00387
00388
00389 restoreFromCache(eventCache_);
00390 } else {
00391
00392 snapShot(eventCache_);
00393 }
00394
00395 if(!saveFileName_.empty()) {
00396 saveStatesToFile(saveFileName_);
00397 if(!saveFileNameRecorded_) {
00398 std::string fullName = constructSaveFileName();
00399 Service<JobReport> reportSvc;
00400 reportSvc->reportRandomStateFile(fullName);
00401 saveFileNameRecorded_ = true;
00402 }
00403 }
00404 }
00405
00406
00407
00408
00409
00410 void
00411 RandomNumberGeneratorService::preModuleConstruction(ModuleDescription const& description) {
00412 push(description.moduleLabel());
00413 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00414 engineStateStack_.push_back(currentEngine_->second->put());
00415 }
00416 }
00417
00418 void
00419 RandomNumberGeneratorService::postModuleConstruction(ModuleDescription const& description) {
00420 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00421 if(engineStateStack_.back() != currentEngine_->second->put()) {
00422 throw Exception(errors::LogicError)
00423 << "It is illegal to generate random numbers during module construction because \n"
00424 "that makes it very difficult to reproduce the processing of individual\n"
00425 "events. Random numbers were generated during module construction for the module with\n"
00426 "class name \"" << description.moduleName() << "\"\n"
00427 "and module label \"" << description.moduleLabel() << "\"\n";
00428 }
00429 engineStateStack_.pop_back();
00430 }
00431 pop();
00432 }
00433
00434 void
00435 RandomNumberGeneratorService::preModuleBeginJob(ModuleDescription const& description) {
00436 push(description.moduleLabel());
00437 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00438 engineStateStack_.push_back(currentEngine_->second->put());
00439 }
00440 }
00441
00442 void
00443 RandomNumberGeneratorService::postModuleBeginJob(ModuleDescription const& description) {
00444 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00445 if(engineStateStack_.back() != currentEngine_->second->put()) {
00446 throw Exception(errors::LogicError)
00447 << "It is illegal to generate random numbers during beginJob because \n"
00448 "that makes it very difficult to reproduce the processing of individual\n"
00449 "events. Random numbers were generated during beginJob for the module with\n"
00450 "class name \"" << description.moduleName() << "\"\n"
00451 "and module label \"" << description.moduleLabel() << "\"\n";
00452 }
00453 engineStateStack_.pop_back();
00454 }
00455 pop();
00456 }
00457
00458 void
00459 RandomNumberGeneratorService::preModuleBeginRun(ModuleDescription const& description) {
00460 push(description.moduleLabel());
00461 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00462 engineStateStack_.push_back(currentEngine_->second->put());
00463 }
00464 }
00465
00466 void
00467 RandomNumberGeneratorService::postModuleBeginRun(ModuleDescription const& description) {
00468 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00469 if(engineStateStack_.back() != currentEngine_->second->put()) {
00470 throw Exception(errors::LogicError)
00471 << "It is illegal to generate random numbers during beginRun because \n"
00472 "that makes it very difficult to reproduce the processing of individual\n"
00473 "events. Random numbers were generated during beginRun for the module with\n"
00474 "class name \"" << description.moduleName() << "\"\n"
00475 "and module label \"" << description.moduleLabel() << "\"\n";
00476 }
00477 engineStateStack_.pop_back();
00478 }
00479 pop();
00480 }
00481
00482 void
00483 RandomNumberGeneratorService::preModuleBeginLumi(ModuleDescription const& description) {
00484 push(description.moduleLabel());
00485 }
00486
00487 void
00488 RandomNumberGeneratorService::postModuleBeginLumi(ModuleDescription const&) {
00489 pop();
00490 }
00491
00492 void
00493 RandomNumberGeneratorService::preModule(ModuleDescription const& description) {
00494 push(description.moduleLabel());
00495 }
00496
00497 void
00498 RandomNumberGeneratorService::postModule(ModuleDescription const&) {
00499 pop();
00500 }
00501
00502 void
00503 RandomNumberGeneratorService::preModuleEndLumi(ModuleDescription const& description) {
00504 push(description.moduleLabel());
00505 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00506 engineStateStack_.push_back(currentEngine_->second->put());
00507 }
00508 }
00509
00510 void
00511 RandomNumberGeneratorService::postModuleEndLumi(ModuleDescription const& description) {
00512 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00513 if(engineStateStack_.back() != currentEngine_->second->put()) {
00514 throw Exception(errors::LogicError)
00515 << "It is illegal to generate random numbers during endLumi because \n"
00516 "that makes it very difficult to reproduce the processing of individual\n"
00517 "events. Random numbers were generated during endLumi for the module with\n"
00518 "class name \"" << description.moduleName() << "\"\n"
00519 "and module label \"" << description.moduleLabel() << "\"\n";
00520 }
00521 engineStateStack_.pop_back();
00522 }
00523 pop();
00524 }
00525
00526 void
00527 RandomNumberGeneratorService::preModuleEndRun(ModuleDescription const& description) {
00528 push(description.moduleLabel());
00529 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00530 engineStateStack_.push_back(currentEngine_->second->put());
00531 }
00532 }
00533
00534 void
00535 RandomNumberGeneratorService::postModuleEndRun(ModuleDescription const& description) {
00536 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00537 if(engineStateStack_.back() != currentEngine_->second->put()) {
00538 throw Exception(errors::LogicError)
00539 << "It is illegal to generate random numbers during endRun because \n"
00540 "that makes it very difficult to reproduce the processing of individual\n"
00541 "events. Random numbers were generated during endRun for the module with\n"
00542 "class name \"" << description.moduleName() << "\"\n"
00543 "and module label \"" << description.moduleLabel() << "\"\n";
00544 }
00545 engineStateStack_.pop_back();
00546 }
00547 pop();
00548 }
00549
00550 void
00551 RandomNumberGeneratorService::preModuleEndJob(ModuleDescription const& description) {
00552 push(description.moduleLabel());
00553 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00554 engineStateStack_.push_back(currentEngine_->second->put());
00555 }
00556 }
00557
00558 void
00559 RandomNumberGeneratorService::postModuleEndJob(ModuleDescription const& description) {
00560 if(enableChecking_ && currentEngine_ != engineMap_.end()) {
00561 if(engineStateStack_.back() != currentEngine_->second->put()) {
00562 throw Exception(errors::LogicError)
00563 << "It is illegal to generate random numbers during endJob because \n"
00564 "that makes it very difficult to reproduce the processing of individual\n"
00565 "events. Random numbers were generated during endJob for the module with\n"
00566 "class name \"" << description.moduleName() << "\"\n"
00567 "and module label \"" << description.moduleLabel() << "\"\n";
00568 }
00569 engineStateStack_.pop_back();
00570 }
00571 pop();
00572 }
00573
00574 std::vector<RandomEngineState> const&
00575 RandomNumberGeneratorService::getLumiCache() const {
00576 return lumiCache_;
00577 }
00578
00579 std::vector<RandomEngineState> const&
00580 RandomNumberGeneratorService::getEventCache() const {
00581 return eventCache_;
00582 }
00583
00584 void
00585 RandomNumberGeneratorService::print() {
00586 std::cout << "\n\nRandomNumberGeneratorService dump\n\n";
00587
00588 std::cout << " Contents of seedMap\n";
00589 for(std::map<std::string, std::vector<uint32_t> >::const_iterator iter = seedMap_.begin();
00590 iter != seedMap_.end();
00591 ++iter) {
00592 std::cout << " " << iter->first;
00593 std::vector<uint32_t> seeds = iter->second;
00594 for(std::vector<uint32_t>::const_iterator vIter = seeds.begin();
00595 vIter != seeds.end();
00596 ++vIter) {
00597 std::cout << " " << *vIter;
00598 }
00599 std::cout << "\n";
00600 }
00601 std::cout << "\n Contents of engineNameMap\n";
00602 for(std::map<std::string, std::string>::const_iterator iter = engineNameMap_.begin();
00603 iter != engineNameMap_.end();
00604 ++iter) {
00605 std::cout << " " << iter->first << " " << iter->second << "\n";
00606 }
00607 std::cout << "\n Contents of engineMap\n";
00608 for(EngineMap::const_iterator iter = engineMap_.begin();
00609 iter != engineMap_.end();
00610 ++iter) {
00611 std::cout << " " << iter->first
00612 << " " << iter->second->name() << " ";
00613 if(iter->second->name() == std::string("HepJamesRandom")) {
00614 std::cout << iter->second->getSeed();
00615 } else {
00616 std::cout << "Engine does not know original seed";
00617 }
00618 std::cout << "\n";
00619 }
00620 std::cout << "\n";
00621 std::cout << " currentLabel_ = " << currentLabel_ << "\n";
00622 std::cout << " labelStack_ size = " << labelStack_.size() << "\n";
00623 int i = 0;
00624 for(VString::const_iterator iter = labelStack_.begin();
00625 iter != labelStack_.end();
00626 ++iter, ++i) {
00627 std::cout << " " << i << " " << *iter << "\n";
00628 }
00629 if(currentEngine_ == engineMap_.end()) {
00630 std::cout << " currentEngine points to end\n";
00631 } else {
00632 std::cout << " currentEngine_ = " << currentEngine_->first
00633 << " " << currentEngine_->second->name()
00634 << " " << currentEngine_->second->getSeed() << "\n";
00635 }
00636
00637 std::cout << " engineStack_ size = " << engineStack_.size() << "\n";
00638 i = 0;
00639 for(std::vector<EngineMap::const_iterator>::const_iterator iter = engineStack_.begin();
00640 iter != engineStack_.end();
00641 ++iter, ++i) {
00642 if(*iter == engineMap_.end()) {
00643 std::cout << " " << i << " Points to end of engine map\n";
00644 } else {
00645 std::cout << " " << i << " " << (*iter)->first
00646 << " " << (*iter)->second->name() << " " << (*iter)->second->getSeed() << "\n";
00647 }
00648 }
00649
00650 std::cout << " restoreStateTag_ = " << restoreStateTag_ << "\n";
00651 std::cout << " saveFileName_ = " << saveFileName_ << "\n";
00652 std::cout << " restoreFileName_ = " << restoreFileName_ << "\n";
00653 }
00654
00655 void
00656 RandomNumberGeneratorService::push(std::string const& iLabel) {
00657 currentEngine_ = engineMap_.find(iLabel);
00658 engineStack_.push_back(currentEngine_);
00659
00660 labelStack_.push_back(iLabel);
00661 currentLabel_ = iLabel;
00662 }
00663
00664 void
00665 RandomNumberGeneratorService::pop() {
00666 engineStack_.pop_back();
00667
00668 currentEngine_ = engineStack_.back();
00669 labelStack_.pop_back();
00670 currentLabel_ = labelStack_.back();
00671 }
00672
00673 void
00674 RandomNumberGeneratorService::readFromLuminosityBlock(LuminosityBlock const& lumi) {
00675
00676 Handle<RandomEngineStates> states;
00677 lumi.getByLabel(restoreStateBeginLumiTag_, states);
00678
00679 if(!states.isValid()) {
00680 failedToFindStatesInLumi_ = true;
00681 return;
00682 }
00683 failedToFindStatesInLumi_ = false;
00684 states->getRandomEngineStates(lumiCache_);
00685 }
00686
00687 void
00688 RandomNumberGeneratorService::readFromEvent(Event const& event) {
00689
00690 Handle<RandomEngineStates> states;
00691
00692 event.getByLabel(restoreStateTag_, states);
00693
00694 if(!states.isValid()) {
00695 if(failedToFindStatesInLumi_ && backwardCompatibilityRead(event)) {
00696 return;
00697 } else {
00698 throw Exception(errors::ProductNotFound)
00699 << "The RandomNumberGeneratorService is trying to restore\n"
00700 << "the state of the random engines by reading a product from\n"
00701 << "the Event with input tag \"" << restoreStateTag_ << "\". It\n"
00702 << "fails to find one. The label used in the request for the product\n"
00703 << "is set in the configuration. It is probably set to the wrong value\n"
00704 << "in the configuration file. It must match the module label\n"
00705 << "of the RandomEngineStateProducer that created the product in\n"
00706 << "a previous process\n";
00707 }
00708 }
00709 if(failedToFindStatesInLumi_) {
00710 throw Exception(errors::ProductNotFound)
00711 << "The RandomNumberGeneratorService is trying to restore\n"
00712 << "the state of the random engines by reading a product from\n"
00713 << "the Event and LuminosityBlock with input tag \"" << restoreStateTag_ << "\".\n"
00714 << "It found the product in the Event but not the one in the LuminosityBlock.\n"
00715 << "Either the product in the LuminosityBlock was dropped or\n"
00716 << "there is a bug somewhere\n";
00717 }
00718 states->getRandomEngineStates(eventCache_);
00719 }
00720
00721 bool
00722 RandomNumberGeneratorService::backwardCompatibilityRead(Event const& event) {
00723
00724 Handle<std::vector<RandomEngineState> > states;
00725
00726 event.getByLabel(restoreStateTag_, states);
00727 if(!states.isValid()) {
00728 return false;
00729 }
00730 for(std::vector<RandomEngineState>::const_iterator state = states->begin(),
00731 iEnd = states->end();
00732 state != iEnd; ++state) {
00733
00734 std::vector<RandomEngineState>::iterator cachedState =
00735 std::lower_bound(eventCache_.begin(), eventCache_.end(), *state);
00736
00737
00738 if(cachedState != eventCache_.end() && cachedState->getLabel() == state->getLabel()) {
00739 if(cachedState->getSeed().size() != state->getSeed().size() ||
00740 cachedState->getState().size() != state->getState().size()) {
00741 throw Exception(errors::Configuration)
00742 << "In function RandomNumberGeneratorService::backwardCompatibilityRead.\n"
00743 << "When attempting to replay processing with the RandomNumberGeneratorService,\n"
00744 << "the engine type for each module must be the same in the replay configuration\n"
00745 << "and the original configuration. If this is not the problem, then the data\n"
00746 << "is somehow corrupted or there is a bug because the vector in the data containing\n"
00747 << "the seeds or engine state is the incorrect size for the type of random engine.\n";
00748 }
00749 cachedState->setSeed(state->getSeed());
00750 cachedState->setState(state->getState());
00751 }
00752 }
00753 return true;
00754 }
00755
00756 void
00757 RandomNumberGeneratorService::snapShot(std::vector<RandomEngineState>& cache) {
00758 cache.resize(engineMap_.size());
00759 std::vector<RandomEngineState>::iterator state = cache.begin();
00760
00761 for(EngineMap::const_iterator iter = engineMap_.begin();
00762 iter != engineMap_.end();
00763 ++iter, ++state) {
00764
00765 state->setLabel(iter->first);
00766 state->setSeed(seedMap_[iter->first]);
00767
00768 std::vector<unsigned long> stateL = iter->second->put();
00769 state->clearStateVector();
00770 state->reserveStateVector(stateL.size());
00771 for(std::vector<unsigned long>::const_iterator vIter = stateL.begin();
00772 vIter != stateL.end();
00773 ++vIter) {
00774 state->push_back_stateVector(static_cast<uint32_t>(*vIter));
00775 }
00776 }
00777 }
00778
00779 void
00780 RandomNumberGeneratorService::restoreFromCache(std::vector<RandomEngineState> const& cache) {
00781 for(std::vector<RandomEngineState>::const_iterator iter = cache.begin(),
00782 iEnd = cache.end();
00783 iter != iEnd; ++iter) {
00784
00785 std::string const& engineLabel = iter->getLabel();
00786
00787 std::vector<uint32_t> const& engineState = iter->getState();
00788 std::vector<unsigned long> engineStateL;
00789 for(std::vector<uint32_t>::const_iterator iVal = engineState.begin(),
00790 theEnd = engineState.end();
00791 iVal != theEnd; ++iVal) {
00792 engineStateL.push_back(static_cast<unsigned long>(*iVal));
00793 }
00794
00795 std::vector<uint32_t> const& engineSeeds = iter->getSeed();
00796 std::vector<long> engineSeedsL;
00797 for(std::vector<uint32_t>::const_iterator iVal = engineSeeds.begin(),
00798 theEnd = engineSeeds.end();
00799 iVal != theEnd;
00800 ++iVal) {
00801 long seedL = static_cast<long>(*iVal);
00802 engineSeedsL.push_back(seedL);
00803
00804
00805
00806
00807
00808
00809
00810
00811 uint32_t seedu32 = static_cast<uint32_t>(seedL);
00812 assert(*iVal == seedu32);
00813 }
00814
00815 EngineMap::iterator engine = engineMap_.find(engineLabel);
00816
00817 if(engine != engineMap_.end()) {
00818
00819 seedMap_[engineLabel] = engineSeeds;
00820
00821
00822
00823 if(engineStateL[0] == CLHEP::engineIDulong<CLHEP::HepJamesRandom>()) {
00824
00825 checkEngineType(engine->second->name(), std::string("HepJamesRandom"), engineLabel);
00826
00827
00828 engine->second->setSeed(engineSeedsL[0], 0);
00829 engine->second->get(engineStateL);
00830 } else if(engineStateL[0] == CLHEP::engineIDulong<CLHEP::RanecuEngine>()) {
00831
00832 checkEngineType(engine->second->name(), std::string("RanecuEngine"), engineLabel);
00833
00834
00835 engine->second->get(engineStateL);
00836 } else if(engineStateL[0] == CLHEP::engineIDulong<TRandomAdaptor>()) {
00837
00838 checkEngineType(engine->second->name(), std::string("TRandom3"), engineLabel);
00839
00840
00841 engine->second->setSeed(engineSeedsL[0], 0);
00842 engine->second->get(engineStateL);
00843 } else {
00844
00845
00846 throw Exception(errors::Unknown)
00847 << "The RandomNumberGeneratorService is trying to restore the state\n"
00848 "of the random engines. The state in the event indicates an engine\n"
00849 "of an unknown type. This should not be possible unless you are\n"
00850 "running with an old code release on a new file that was created\n"
00851 "with a newer release which had new engine types added. In this case\n"
00852 "the only solution is to use a newer release. In any other case, notify\n"
00853 "the EDM developers because this should not be possible\n";
00854 }
00855 }
00856 }
00857 }
00858
00859 void
00860 RandomNumberGeneratorService::checkEngineType(std::string const& typeFromConfig,
00861 std::string const& typeFromEvent,
00862 std::string const& engineLabel) {
00863 if(typeFromConfig != typeFromEvent) {
00864 throw Exception(errors::Configuration)
00865 << "The RandomNumberGeneratorService is trying to restore\n"
00866 << "the state of the random engine for the module \""
00867 << engineLabel << "\". An\n"
00868 << "error was detected because the type of the engine in the\n"
00869 << "input file and the configuration file do not match.\n"
00870 << "In the configuration file the type is \"" << typeFromConfig
00871 << "\".\nIn the input file the type is \"" << typeFromEvent << "\". If\n"
00872 << "you are not generating any random numbers in this module, then\n"
00873 << "remove the line in the configuration file that gives it\n"
00874 << "a seed and the error will go away. Otherwise, you must give\n"
00875 << "this module the same engine type in the configuration file or\n"
00876 << "stop trying to restore the random engine state.\n";
00877 }
00878 }
00879
00880 void
00881 RandomNumberGeneratorService::saveStatesToFile(std::string const& fileName) {
00882 if(!outFile_.is_open()) {
00883 outFile_.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
00884 }
00885 if(!outFile_) {
00886 throw Exception(errors::Configuration)
00887 << "Unable to open the file \""
00888 << fileName << "\" to save the state of the random engines.\n";
00889 }
00890 outFile_.seekp(0, std::ios_base::beg);
00891 outFile_ << "<RandomEngineStates>\n";
00892
00893 outFile_ << "<Event>\n";
00894 writeStates(eventCache_, outFile_);
00895 outFile_ << "</Event>\n" ;
00896
00897 outFile_ << "<Lumi>\n";
00898 writeStates(lumiCache_, outFile_);
00899 outFile_ << "</Lumi>\n" ;
00900
00901 outFile_ << "</RandomEngineStates>\n" ;
00902 outFile_.flush();
00903 }
00904
00905 void
00906 RandomNumberGeneratorService::writeStates(std::vector<RandomEngineState> const& v,
00907 std::ofstream& outFile) {
00908 for(std::vector<RandomEngineState>::const_iterator iter = v.begin(),
00909 iEnd = v.end();
00910 iter != iEnd; ++iter) {
00911
00912 std::vector<uint32_t> const& seedVector = iter->getSeed();
00913 std::vector<uint32_t>::size_type seedVectorLength = seedVector.size();
00914
00915 std::vector<uint32_t> const& stateVector = iter->getState();
00916 std::vector<uint32_t>::size_type stateVectorLength = stateVector.size();
00917
00918 outFile << "<ModuleLabel>\n" << iter->getLabel() << "\n</ModuleLabel>\n";
00919
00920 outFile << "<SeedLength>\n" << seedVectorLength << "\n</SeedLength>\n" ;
00921 outFile << "<InitialSeeds>\n";
00922 writeVector(seedVector, outFile);
00923 outFile << "</InitialSeeds>\n";
00924 outFile << "<FullStateLength>\n" << stateVectorLength << "\n</FullStateLength>\n";
00925 outFile << "<FullState>\n";
00926 writeVector(stateVector, outFile);
00927 outFile << "</FullState>\n";
00928 }
00929 }
00930
00931 void
00932 RandomNumberGeneratorService::writeVector(VUint32 const& v,
00933 std::ofstream& outFile) {
00934 if(v.empty()) return;
00935 size_t numItems = v.size();
00936 for(size_t i = 0; i < numItems; ++i) {
00937 if(i != 0 && i % 10 == 0) outFile << "\n";
00938 outFile << std::setw(13) << v[i];
00939 }
00940 outFile << "\n";
00941 }
00942
00943 std::string RandomNumberGeneratorService::constructSaveFileName() {
00944 char directory[1500];
00945 std::string fullName(getcwd(directory, sizeof(directory)) ? directory : "/PathIsTooBig");
00946 fullName += "/" + saveFileName_;
00947 return fullName;
00948 }
00949
00950 void
00951 RandomNumberGeneratorService::readEventStatesFromTextFile(std::string const& fileName) {
00952 std::string whichStates("<Event>");
00953 readStatesFromFile(fileName, eventCache_, whichStates);
00954 }
00955
00956 void
00957 RandomNumberGeneratorService::readLumiStatesFromTextFile(std::string const& fileName) {
00958 std::string whichStates("<Lumi>");
00959 readStatesFromFile(fileName, lumiCache_, whichStates);
00960 }
00961
00962
00963 void
00964 RandomNumberGeneratorService::readStatesFromFile(std::string const& fileName,
00965 std::vector<RandomEngineState>& cache,
00966 std::string const& whichStates) {
00967 std::ifstream inFile;
00968 inFile.open(fileName.c_str(), std::ifstream::in);
00969 if(!inFile) {
00970 throw Exception(errors::Configuration)
00971 << "Unable to open the file \""
00972 << fileName << "\" to restore the random engine states.\n";
00973 }
00974
00975 std::string text;
00976 inFile >> text;
00977 if(!inFile.good() || text != std::string("<RandomEngineStates>")) {
00978 throw Exception(errors::Configuration)
00979 << "Attempting to read file with random number engine states.\n"
00980 << "File \"" << restoreFileName_
00981 << "\" is ill-structured or otherwise corrupted.\n"
00982 << "Cannot read the file header word.\n";
00983 }
00984 bool saveToCache = false;
00985 while(readEngineState(inFile, cache, whichStates, saveToCache)) {}
00986 }
00987
00988 bool RandomNumberGeneratorService::readEngineState(std::istream& is,
00989 std::vector<RandomEngineState>& cache,
00990 std::string const& whichStates,
00991 bool& saveToCache) {
00992 std::string leading;
00993 std::string trailing;
00994 std::string moduleLabel;
00995 std::vector<uint32_t>::size_type seedVectorSize;
00996 std::vector<uint32_t> seedVector;
00997 std::vector<uint32_t>::size_type stateVectorSize;
00998 std::vector<uint32_t> stateVector;
00999
01000
01001
01002
01003
01004 is >> leading;
01005 if(!is.good()) {
01006 throw Exception(errors::Configuration)
01007 << "File \"" << restoreFileName_
01008 << "\" is ill-structured or otherwise corrupted.\n"
01009 << "Cannot read next field and did not hit the end yet.\n";
01010 }
01011
01012
01013 if(leading == std::string("</RandomEngineStates>")) return false;
01014
01015
01016 if(leading == std::string("</Event>") ||
01017 leading == std::string("</Lumi>")) {
01018 saveToCache = false;
01019 return true;
01020 }
01021
01022
01023 if(leading == std::string("<Event>") ||
01024 leading == std::string("<Lumi>")) {
01025 saveToCache = (leading == whichStates);
01026 return true;
01027 }
01028
01029
01030
01031 is >> moduleLabel >> trailing;
01032 if(!is.good() ||
01033 leading != std::string("<ModuleLabel>") ||
01034 trailing != std::string("</ModuleLabel>")) {
01035 throw Exception(errors::Configuration)
01036 << "File \"" << restoreFileName_
01037 << "\" is ill-structured or otherwise corrupted.\n"
01038 << "Cannot read a module label when restoring random engine states.\n";
01039 }
01040
01041 is >> leading >> seedVectorSize >> trailing;
01042 if(!is.good() ||
01043 leading != std::string("<SeedLength>") ||
01044 trailing != std::string("</SeedLength>")) {
01045 throw Exception(errors::Configuration)
01046 << "File \"" << restoreFileName_
01047 << "\" is ill-structured or otherwise corrupted.\n"
01048 << "Cannot read seed vector length when restoring random engine states.\n";
01049 }
01050
01051 is >> leading;
01052 if(!is.good() ||
01053 leading != std::string("<InitialSeeds>")) {
01054 throw Exception(errors::Configuration)
01055 << "File \"" << restoreFileName_
01056 << "\" is ill-structured or otherwise corrupted.\n"
01057 << "Cannot read beginning of InitialSeeds when restoring random engine states.\n";
01058 }
01059
01060 if(seedVectorSize > maxSeeds) {
01061 throw Exception(errors::Configuration)
01062 << "File \"" << restoreFileName_
01063 << "\" is ill-structured or otherwise corrupted.\n"
01064 << "The number of seeds exceeds 64K.\n";
01065 }
01066
01067 readVector(is, seedVectorSize, seedVector);
01068
01069 is >> trailing;
01070 if(!is.good() ||
01071 trailing != std::string("</InitialSeeds>")) {
01072 throw Exception(errors::Configuration)
01073 << "File \"" << restoreFileName_
01074 << "\" is ill-structured or otherwise corrupted.\n"
01075 << "Cannot read end of InitialSeeds when restoring random engine states.\n";
01076 }
01077
01078 is >> leading >> stateVectorSize >> trailing;
01079 if(!is.good() ||
01080 leading != std::string("<FullStateLength>") ||
01081 trailing != std::string("</FullStateLength>")) {
01082 throw Exception(errors::Configuration)
01083 << "File \"" << restoreFileName_
01084 << "\" is ill-structured or otherwise corrupted.\n"
01085 << "Cannot read state vector length when restoring random engine states.\n";
01086 }
01087
01088 is >> leading;
01089 if(!is.good() ||
01090 leading != std::string("<FullState>")) {
01091 throw Exception(errors::Configuration)
01092 << "File \"" << restoreFileName_
01093 << "\" is ill-structured or otherwise corrupted.\n"
01094 << "Cannot read beginning of FullState when restoring random engine states.\n";
01095 }
01096
01097 if(stateVectorSize > maxStates) {
01098 throw Exception(errors::Configuration)
01099 << "File \"" << restoreFileName_
01100 << "\" is ill-structured or otherwise corrupted.\n"
01101 << "The number of states exceeds 64K.\n";
01102 }
01103
01104 readVector(is, stateVectorSize, stateVector);
01105
01106 is >> trailing;
01107 if(!is.good() ||
01108 trailing != std::string("</FullState>")) {
01109 throw Exception(errors::Configuration)
01110 << "File \"" << restoreFileName_
01111 << "\" is ill-structured or otherwise corrupted.\n"
01112 << "Cannot read end of FullState when restoring random engine states.\n";
01113 }
01114
01115 if(saveToCache) {
01116 RandomEngineState randomEngineState;
01117 randomEngineState.setLabel(moduleLabel);
01118 std::vector<RandomEngineState>::iterator state =
01119 std::lower_bound(cache.begin(), cache.end(), randomEngineState);
01120
01121 if(state != cache.end() && moduleLabel == state->getLabel()) {
01122 if(seedVector.size() != state->getSeed().size() ||
01123 stateVector.size() != state->getState().size()) {
01124 throw Exception(errors::Configuration)
01125 << "File \"" << restoreFileName_
01126 << "\" is ill-structured or otherwise corrupted.\n"
01127 << "Vectors containing engine state are the incorrect size for the type of random engine.\n";
01128 }
01129 state->setSeed(seedVector);
01130 state->setState(stateVector);
01131 }
01132 }
01133 return true;
01134 }
01135
01136 void
01137 RandomNumberGeneratorService::readVector(std::istream& is, unsigned numItems, std::vector<uint32_t>& v) {
01138 v.clear();
01139 v.reserve(numItems);
01140 uint32_t data;
01141 for(unsigned i = 0; i < numItems; ++i) {
01142 is >> data;
01143 if(!is.good()) {
01144 throw Exception(errors::Configuration)
01145 << "File \"" << restoreFileName_
01146 << "\" is ill-structured or otherwise corrupted.\n"
01147 << "Cannot read vector when restoring random engine states.\n";
01148 }
01149 v.push_back(data);
01150 }
01151 }
01152
01153 void
01154 RandomNumberGeneratorService::startNewSequencesForEvents() {
01155
01156 if(childIndex_ == 0U && eventSeedOffset_ == 0U) return;
01157
01158 for(EngineMap::const_iterator iter = engineMap_.begin();
01159 iter != engineMap_.end();
01160 ++iter) {
01161
01162 uint32_t offset1 = childIndex_;
01163 uint32_t offset2 = eventSeedOffset_;
01164
01165 std::string const& moduleLabel = iter->first;
01166 std::string const& engineName = engineNameMap_[moduleLabel];
01167 VUint32& seeds = seedMap_[moduleLabel];
01168
01169 if(engineName == std::string("RanecuEngine")) {
01170 assert(seeds.size() == 2U);
01171
01172 uint32_t mod = maxSeedRanecu + 1U;
01173 offset1 = offset1 % mod;
01174 offset2 = offset2 % mod;
01175 seeds[0] = (seeds[0] + offset1) % mod;
01176 seeds[0] = (seeds[0] + offset2) % mod;
01177 long int seedL[2];
01178 seedL[0] = static_cast<long int>(seeds[0]);
01179 seedL[1] = static_cast<long int>(seeds[1]);
01180 iter->second->setSeeds(seedL,0);
01181 } else {
01182 assert(seeds.size() == 1U);
01183
01184 if(engineName == "HepJamesRandom") {
01185
01186 uint32_t mod = maxSeedHepJames + 1U;
01187 offset1 = offset1 % mod;
01188 offset2 = offset2 % mod;
01189 seeds[0] = (seeds[0] + offset1) % mod;
01190 seeds[0] = (seeds[0] + offset2) % mod;
01191
01192 long int seedL = static_cast<long int>(seeds[0]);
01193 iter->second->setSeed(seedL, 0);
01194 } else {
01195 assert(engineName == "TRandom3");
01196
01197
01198
01199 uint32_t max32 = maxSeedTRandom3;
01200 if((max32 - seeds[0]) >= offset1) {
01201 seeds[0] = seeds[0] + offset1;
01202 } else {
01203 seeds[0] = offset1 - (max32 - seeds[0]) - 1U;
01204 }
01205 if((max32 - seeds[0]) >= offset2) {
01206 seeds[0] = seeds[0] + offset2;
01207 } else {
01208 seeds[0] = offset2 - (max32 - seeds[0]) - 1U;
01209 }
01210 long seedL = static_cast<long>(seeds[0]);
01211
01212
01213
01214
01215
01216
01217
01218
01219 uint32_t seedu32 = static_cast<uint32_t>(seedL);
01220 assert(seeds[0] == seedu32);
01221
01222 iter->second->setSeed(seedL, 0);
01223 }
01224 }
01225 }
01226 }
01227 }
01228 }