00001 #include "FWCore/Framework/interface/Schedule.h"
00002
00003 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
00004 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
00005 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00006 #include "FWCore/Framework/interface/EDProducer.h"
00007 #include "FWCore/Framework/interface/OutputModuleDescription.h"
00008 #include "FWCore/Framework/interface/TriggerNamesService.h"
00009 #include "FWCore/Framework/interface/TriggerReport.h"
00010 #include "FWCore/Framework/src/Factory.h"
00011 #include "FWCore/Framework/interface/OutputModule.h"
00012 #include "FWCore/Framework/src/OutputWorker.h"
00013 #include "FWCore/Framework/src/TriggerResultInserter.h"
00014 #include "FWCore/Framework/src/WorkerInPath.h"
00015 #include "FWCore/Framework/src/WorkerMaker.h"
00016 #include "FWCore/Framework/src/WorkerT.h"
00017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00018 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00020 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00021 #include "FWCore/ParameterSet/interface/Registry.h"
00022 #include "FWCore/Utilities/interface/Algorithms.h"
00023 #include "FWCore/Utilities/interface/ConvertException.h"
00024 #include "FWCore/Utilities/interface/ExceptionCollector.h"
00025 #include "FWCore/Utilities/interface/DictionaryTools.h"
00026
00027 #include "boost/bind.hpp"
00028 #include "boost/ref.hpp"
00029
00030 #include <algorithm>
00031 #include <cassert>
00032 #include <cstdlib>
00033 #include <functional>
00034 #include <iomanip>
00035 #include <list>
00036 #include <map>
00037 #include <exception>
00038
00039 namespace edm {
00040 namespace {
00041
00042
00043
00044
00045
00046 template <typename InputIterator, typename ForwardIterator, typename Func>
00047 void
00048 transform_into(InputIterator begin, InputIterator end,
00049 ForwardIterator out, Func func) {
00050 for (; begin != end; ++begin, ++out) func(*begin, *out);
00051 }
00052
00053
00054
00055
00056
00057
00058 template <typename FROM, typename TO, typename FUNC>
00059 void
00060 fill_summary(FROM const& from, TO& to, FUNC func) {
00061 TO temp(from.size());
00062 transform_into(from.begin(), from.end(), temp.begin(), func);
00063 to.swap(temp);
00064 }
00065
00066
00067
00068
00069
00070
00071 Schedule::WorkerPtr
00072 makeInserter(ParameterSet& proc_pset,
00073 ProductRegistry& preg,
00074 ActionTable const& actions,
00075 boost::shared_ptr<ActivityRegistry> areg,
00076 boost::shared_ptr<ProcessConfiguration> processConfiguration,
00077 Schedule::TrigResPtr trptr) {
00078
00079 ParameterSet* trig_pset = proc_pset.getPSetForUpdate("@trigger_paths");
00080 trig_pset->registerIt();
00081
00082 WorkerParams work_args(proc_pset, trig_pset, preg, processConfiguration, actions);
00083 ModuleDescription md(trig_pset->id(),
00084 "TriggerResultInserter",
00085 "TriggerResults",
00086 processConfiguration.get());
00087
00088 areg->preModuleConstructionSignal_(md);
00089 std::auto_ptr<EDProducer> producer(new TriggerResultInserter(*trig_pset, trptr));
00090 areg->postModuleConstructionSignal_(md);
00091
00092 Schedule::WorkerPtr ptr(new WorkerT<EDProducer>(producer, md, work_args));
00093 ptr->setActivityRegistry(areg);
00094 return ptr;
00095 }
00096
00097 bool binary_search_string(std::vector<std::string> const& v, std::string const& s) {
00098 return std::binary_search(v.begin(), v.end(), s);
00099 }
00100
00101 void
00102 initializeBranchToReadingWorker(ParameterSet const& opts,
00103 ProductRegistry const& preg,
00104 std::multimap<std::string,Worker*>& branchToReadingWorker)
00105 {
00106
00107 auto vBranchesToDeleteEarly = opts.getUntrackedParameter<std::vector<std::string>>("canDeleteEarly",std::vector<std::string>());
00108 if(not vBranchesToDeleteEarly.empty()) {
00109 std::sort(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),std::less<std::string>());
00110 vBranchesToDeleteEarly.erase(std::unique(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end()),
00111 vBranchesToDeleteEarly.end());
00112
00113
00114 auto allBranchNames = preg.allBranchNames();
00115
00116 for(auto & b:allBranchNames) {
00117 b.resize(b.size()-1);
00118 }
00119 std::sort(allBranchNames.begin(),allBranchNames.end(),std::less<std::string>());
00120 std::vector<std::string> temp;
00121 temp.reserve(vBranchesToDeleteEarly.size());
00122
00123 std::set_intersection(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),
00124 allBranchNames.begin(),allBranchNames.end(),
00125 std::back_inserter(temp));
00126 vBranchesToDeleteEarly.swap(temp);
00127 if(temp.size() != vBranchesToDeleteEarly.size()) {
00128 std::vector<std::string> missingProducts;
00129 std::set_difference(temp.begin(),temp.end(),
00130 vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),
00131 std::back_inserter(missingProducts));
00132 LogInfo l("MissingProductsForCanDeleteEarly");
00133 l<<"The following products in the 'canDeleteEarly' list are not available in this job and will be ignored.";
00134 for(auto const& n:missingProducts){
00135 l<<"\n "<<n;
00136 }
00137 }
00138
00139
00140 for(auto const& branch:vBranchesToDeleteEarly) {
00141 branchToReadingWorker.insert(std::make_pair(branch, static_cast<Worker*>(nullptr)));
00142 }
00143 }
00144 }
00145
00146 void
00147 checkAndInsertAlias(std::string const& friendlyClassName,
00148 std::string const& moduleLabel,
00149 std::string const& productInstanceName,
00150 std::string const& processName,
00151 std::string const& alias,
00152 std::string const& instanceAlias,
00153 ProductRegistry const& preg,
00154 std::multimap<BranchKey, BranchKey>& aliasMap,
00155 std::map<BranchKey, BranchKey>& aliasKeys) {
00156 std::string const star("*");
00157
00158 BranchKey key(friendlyClassName, moduleLabel, productInstanceName, processName);
00159 if(preg.productList().find(key) == preg.productList().end()) {
00160
00161
00162 for(auto const& product : preg.productList()) {
00163 if(moduleLabel == product.first.moduleLabel_ && processName == product.first.processName_) {
00164 throw Exception(errors::Configuration, "EDAlias does not match data\n")
00165 << "There are no products of type '" << friendlyClassName << "'\n"
00166 << "with module label '" << moduleLabel << "' and instance name '" << productInstanceName << "'.\n";
00167 }
00168 }
00169 }
00170
00171 std::string const& theInstanceAlias(instanceAlias == star ? productInstanceName : instanceAlias);
00172 BranchKey aliasKey(friendlyClassName, alias, theInstanceAlias, processName);
00173 if(preg.productList().find(aliasKey) != preg.productList().end()) {
00174 throw Exception(errors::Configuration, "EDAlias conflicts with data\n")
00175 << "A product of type '" << friendlyClassName << "'\n"
00176 << "with module label '" << alias << "' and instance name '" << theInstanceAlias << "'\n"
00177 << "already exists.\n";
00178 }
00179 auto iter = aliasKeys.find(aliasKey);
00180 if(iter != aliasKeys.end()) {
00181
00182 if(iter->second != key) {
00183 throw Exception(errors::Configuration, "EDAlias conflict\n")
00184 << "The module label alias '" << alias << "' and product instance alias '" << theInstanceAlias << "'\n"
00185 << "are used for multiple products of type '" << friendlyClassName << "'\n"
00186 << "One has module label '" << moduleLabel << "' and product instance name '" << productInstanceName << "',\n"
00187 << "the other has module label '" << iter->second.moduleLabel_ << "' and product instance name '" << iter->second.productInstanceName_ << "'.\n";
00188 }
00189 } else {
00190 aliasMap.insert(std::make_pair(key, aliasKey));
00191 aliasKeys.insert(std::make_pair(aliasKey, key));
00192 }
00193 }
00194
00195 void
00196 processEDAliases(ParameterSet const& proc_pset, std::string const& processName, ProductRegistry& preg) {
00197 std::vector<std::string> aliases = proc_pset.getParameter<std::vector<std::string> >("@all_aliases");
00198 if(aliases.empty()) {
00199 return;
00200 }
00201 std::string const star("*");
00202 std::string const empty("");
00203 ParameterSetDescription desc;
00204 desc.add<std::string>("type");
00205 desc.add<std::string>("fromProductInstance", star);
00206 desc.add<std::string>("toProductInstance", star);
00207
00208 std::multimap<BranchKey, BranchKey> aliasMap;
00209
00210 std::map<BranchKey, BranchKey> aliasKeys;
00211
00212
00213 for(std::string const& alias : aliases) {
00214 ParameterSet const& aliasPSet = proc_pset.getParameterSet(alias);
00215 std::vector<std::string> vPSetNames = aliasPSet.getParameterNamesForType<VParameterSet>();
00216 for(std::string const& moduleLabel : vPSetNames) {
00217 VParameterSet vPSet = aliasPSet.getParameter<VParameterSet>(moduleLabel);
00218 for(ParameterSet& pset : vPSet) {
00219 desc.validate(pset);
00220 std::string friendlyClassName = pset.getParameter<std::string>("type");
00221 std::string productInstanceName = pset.getParameter<std::string>("fromProductInstance");
00222 std::string instanceAlias = pset.getParameter<std::string>("toProductInstance");
00223 if(productInstanceName == star) {
00224 bool match = false;
00225 BranchKey lowerBound(friendlyClassName, moduleLabel, empty, empty);
00226 for(ProductRegistry::ProductList::const_iterator it = preg.productList().lower_bound(lowerBound);
00227 it != preg.productList().end() && it->first.friendlyClassName_ == friendlyClassName && it->first.moduleLabel_ == moduleLabel;
00228 ++it) {
00229 if(it->first.processName_ != processName) {
00230 continue;
00231 }
00232 match = true;
00233
00234 checkAndInsertAlias(friendlyClassName, moduleLabel, it->first.productInstanceName_, processName, alias, instanceAlias, preg, aliasMap, aliasKeys);
00235 }
00236 if(!match) {
00237
00238
00239 for(auto const& product : preg.productList()) {
00240 if(moduleLabel == product.first.moduleLabel_ && processName == product.first.processName_) {
00241 throw Exception(errors::Configuration, "EDAlias parameter set mismatch\n")
00242 << "There are no products of type '" << friendlyClassName << "'\n"
00243 << "with module label '" << moduleLabel << "'.\n";
00244 }
00245 }
00246 }
00247 } else {
00248 checkAndInsertAlias(friendlyClassName, moduleLabel, productInstanceName, processName, alias, instanceAlias, preg, aliasMap, aliasKeys);
00249 }
00250 }
00251 }
00252 }
00253
00254
00255
00256 for(auto const& aliasEntry : aliasMap) {
00257 ProductRegistry::ProductList::const_iterator it = preg.productList().find(aliasEntry.first);
00258 assert(it != preg.productList().end());
00259 preg.addLabelAlias(it->second, aliasEntry.second.moduleLabel_, aliasEntry.second.productInstanceName_);
00260 }
00261
00262 }
00263 }
00264
00265
00266
00267 typedef std::vector<std::string> vstring;
00268
00269
00270
00271 Schedule::Schedule(ParameterSet& proc_pset,
00272 service::TriggerNamesService& tns,
00273 ProductRegistry& preg,
00274 BranchIDListHelper& branchIDListHelper,
00275 ActionTable const& actions,
00276 boost::shared_ptr<ActivityRegistry> areg,
00277 boost::shared_ptr<ProcessConfiguration> processConfiguration,
00278 const ParameterSet* subProcPSet) :
00279 worker_reg_(areg),
00280 act_table_(&actions),
00281 actReg_(areg),
00282 state_(Ready),
00283 trig_name_list_(tns.getTrigPaths()),
00284 end_path_name_list_(tns.getEndPaths()),
00285 results_(new HLTGlobalStatus(trig_name_list_.size())),
00286 endpath_results_(),
00287 results_inserter_(),
00288 all_workers_(),
00289 all_output_workers_(),
00290 trig_paths_(),
00291 end_paths_(),
00292 wantSummary_(tns.wantSummary()),
00293 total_events_(),
00294 total_passed_(),
00295 stopwatch_(wantSummary_? new RunStopwatch::StopwatchPointer::element_type : static_cast<RunStopwatch::StopwatchPointer::element_type*> (0)),
00296 unscheduled_(new UnscheduledCallProducer),
00297 endpathsAreActive_(true) {
00298
00299 ParameterSet const& opts = proc_pset.getUntrackedParameterSet("options", ParameterSet());
00300 bool hasPath = false;
00301
00302 int trig_bitpos = 0;
00303 vstring labelsOnTriggerPaths;
00304 for (vstring::const_iterator i = trig_name_list_.begin(),
00305 e = trig_name_list_.end();
00306 i != e;
00307 ++i) {
00308 fillTrigPath(proc_pset, preg, processConfiguration, trig_bitpos, *i, results_, &labelsOnTriggerPaths);
00309 ++trig_bitpos;
00310 hasPath = true;
00311 }
00312
00313 if (hasPath) {
00314
00315 results_inserter_ = makeInserter(proc_pset,
00316 preg,
00317 actions, actReg_, processConfiguration, results_);
00318 addToAllWorkers(results_inserter_.get());
00319 }
00320
00321 TrigResPtr epptr(new HLTGlobalStatus(end_path_name_list_.size()));
00322 endpath_results_ = epptr;
00323
00324
00325 vstring::iterator eib(end_path_name_list_.begin()), eie(end_path_name_list_.end());
00326 for (int bitpos = 0; eib != eie; ++eib, ++bitpos) {
00327 fillEndPath(proc_pset, preg, processConfiguration, bitpos, *eib);
00328 }
00329
00330
00331 std::set<std::string> usedWorkerLabels;
00332 for (AllWorkers::iterator itWorker = workersBegin();
00333 itWorker != workersEnd();
00334 ++itWorker) {
00335 usedWorkerLabels.insert((*itWorker)->description().moduleLabel());
00336 }
00337 std::vector<std::string> modulesInConfig(proc_pset.getParameter<std::vector<std::string> >("@all_modules"));
00338 std::set<std::string> modulesInConfigSet(modulesInConfig.begin(), modulesInConfig.end());
00339 std::vector<std::string> unusedLabels;
00340 set_difference(modulesInConfigSet.begin(), modulesInConfigSet.end(),
00341 usedWorkerLabels.begin(), usedWorkerLabels.end(),
00342 back_inserter(unusedLabels));
00343
00344 bool allowUnscheduled = opts.getUntrackedParameter<bool>("allowUnscheduled", false);
00345 std::set<std::string> unscheduledLabels;
00346 std::vector<std::string> shouldBeUsedLabels;
00347 if (!unusedLabels.empty()) {
00348
00349
00350
00351
00352
00353 for (std::vector<std::string>::iterator itLabel = unusedLabels.begin(), itLabelEnd = unusedLabels.end();
00354 itLabel != itLabelEnd;
00355 ++itLabel) {
00356 if (allowUnscheduled) {
00357 bool isTracked;
00358 ParameterSet* modulePSet(proc_pset.getPSetForUpdate(*itLabel, isTracked));
00359 assert(isTracked);
00360 assert(modulePSet != 0);
00361 WorkerParams params(proc_pset, modulePSet, preg,
00362 processConfiguration, *act_table_);
00363 Worker* newWorker(worker_reg_.getWorker(params, *itLabel));
00364 if (dynamic_cast<WorkerT<EDProducer>*>(newWorker) ||
00365 dynamic_cast<WorkerT<EDFilter>*>(newWorker)) {
00366 unscheduledLabels.insert(*itLabel);
00367 unscheduled_->addWorker(newWorker);
00368
00369 addToAllWorkers(newWorker);
00370 } else {
00371
00372 shouldBeUsedLabels.push_back(*itLabel);
00373 }
00374 } else {
00375
00376 shouldBeUsedLabels.push_back(*itLabel);
00377 }
00378 }
00379 if (!shouldBeUsedLabels.empty()) {
00380 std::ostringstream unusedStream;
00381 unusedStream << "'" << shouldBeUsedLabels.front() << "'";
00382 for (std::vector<std::string>::iterator itLabel = shouldBeUsedLabels.begin() + 1,
00383 itLabelEnd = shouldBeUsedLabels.end();
00384 itLabel != itLabelEnd;
00385 ++itLabel) {
00386 unusedStream << ",'" << *itLabel << "'";
00387 }
00388 LogInfo("path")
00389 << "The following module labels are not assigned to any path:\n"
00390 << unusedStream.str()
00391 << "\n";
00392 }
00393 }
00394 if (!unscheduledLabels.empty()) {
00395 for (ProductRegistry::ProductList::const_iterator it = preg.productList().begin(),
00396 itEnd = preg.productList().end();
00397 it != itEnd;
00398 ++it) {
00399 if (it->second.produced() &&
00400 it->second.branchType() == InEvent &&
00401 unscheduledLabels.end() != unscheduledLabels.find(it->second.moduleLabel())) {
00402 it->second.setOnDemand();
00403 }
00404 }
00405 }
00406
00407 std::map<std::string, std::vector<std::pair<std::string, int> > > outputModulePathPositions;
00408 reduceParameterSet(proc_pset, modulesInConfig, modulesInConfigSet, labelsOnTriggerPaths, shouldBeUsedLabels, outputModulePathPositions);
00409
00410 processEDAliases(proc_pset, processConfiguration->processName(), preg);
00411
00412 proc_pset.registerIt();
00413 pset::Registry::instance()->extra().setID(proc_pset.id());
00414 processConfiguration->setParameterSetID(proc_pset.id());
00415
00416 initializeEarlyDelete(opts,preg,subProcPSet);
00417
00418
00419
00420 size_t all_workers_count = all_workers_.size();
00421
00422 for (AllWorkers::iterator i = all_workers_.begin(), e = all_workers_.end();
00423 i != e;
00424 ++i) {
00425
00426
00427
00428 OutputWorker* ow = dynamic_cast<OutputWorker*>(*i);
00429 if (ow) {
00430 all_output_workers_.push_back(ow);
00431 }
00432 }
00433
00434 limitOutput(proc_pset, branchIDListHelper.branchIDLists());
00435
00436 loadMissingDictionaries();
00437 preg.setFrozen();
00438
00439 for (AllOutputWorkers::iterator i = all_output_workers_.begin(), e = all_output_workers_.end();
00440 i != e; ++i) {
00441 (*i)->setEventSelectionInfo(outputModulePathPositions, preg.anyProductProduced());
00442 }
00443
00444
00445
00446 assert (all_workers_count == all_workers_.size());
00447
00448 ProcessConfigurationRegistry::instance()->insertMapped(*processConfiguration);
00449 branchIDListHelper.updateRegistries(preg);
00450 fillProductRegistryTransients(*processConfiguration, preg);
00451 }
00452
00453
00454 void Schedule::initializeEarlyDelete(edm::ParameterSet const& opts, edm::ProductRegistry const& preg,
00455 edm::ParameterSet const* subProcPSet) {
00456
00457
00458 if(subProcPSet) return;
00459
00460
00461
00462 std::multimap<std::string,Worker*> branchToReadingWorker;
00463 initializeBranchToReadingWorker(opts,preg,branchToReadingWorker);
00464
00465
00466 if(branchToReadingWorker.size()==0) {
00467 return;
00468 }
00469 const std::vector<std::string> kEmpty;
00470 std::map<Worker*,unsigned int> reserveSizeForWorker;
00471 unsigned int upperLimitOnReadingWorker =0;
00472 unsigned int upperLimitOnIndicies = 0;
00473 unsigned int nUniqueBranchesToDelete=branchToReadingWorker.size();
00474 for (AllWorkers::iterator i = all_workers_.begin(), e = all_workers_.end();
00475 i != e;
00476 ++i) {
00477 OutputWorker* ow = dynamic_cast<OutputWorker*>(*i);
00478 if (ow) {
00479 if(branchToReadingWorker.size()>0) {
00480
00481
00482 SelectionsArray const&kept = ow->keptProducts();
00483 for( auto const& item: kept[InEvent]) {
00484 auto found = branchToReadingWorker.equal_range(item->branchName());
00485 if(found.first !=found.second) {
00486 --nUniqueBranchesToDelete;
00487 branchToReadingWorker.erase(found.first,found.second);
00488 }
00489 }
00490 }
00491 } else {
00492 if(branchToReadingWorker.size()>0) {
00493
00494 auto pset = pset::Registry::instance()->getMapped((*i)->description().parameterSetID());
00495 if(0!=pset) {
00496 auto branches = pset->getUntrackedParameter<std::vector<std::string>>("mightGet",kEmpty);
00497 if(not branches.empty()) {
00498 ++upperLimitOnReadingWorker;
00499 }
00500 for(auto const& branch:branches){
00501 auto found = branchToReadingWorker.equal_range(branch);
00502 if(found.first != found.second) {
00503 ++upperLimitOnIndicies;
00504 ++reserveSizeForWorker[*i];
00505 if(nullptr == found.first->second) {
00506 found.first->second = *i;
00507 } else {
00508 branchToReadingWorker.insert(make_pair(found.first->first,*i));
00509 }
00510 }
00511 }
00512 }
00513 }
00514 }
00515 }
00516 {
00517 auto it = branchToReadingWorker.begin();
00518 std::vector<std::string> unusedBranches;
00519 while(it !=branchToReadingWorker.end()) {
00520 if(it->second == nullptr) {
00521 unusedBranches.push_back(it->first);
00522
00523 auto temp = it;
00524 ++it;
00525 branchToReadingWorker.erase(temp);
00526 } else {
00527 ++it;
00528 }
00529 }
00530 if(not unusedBranches.empty()) {
00531 LogWarning l("UnusedProductsForCanDeleteEarly");
00532 l<<"The following products in the 'canDeleteEarly' list are not used in this job and will be ignored.\n"
00533 " If possible, remove the producer from the job or add the product to the producer's own 'mightGet' list.";
00534 for(auto const& n:unusedBranches){
00535 l<<"\n "<<n;
00536 }
00537 }
00538 }
00539 if(0!=branchToReadingWorker.size()) {
00540 earlyDeleteHelpers_.reserve(upperLimitOnReadingWorker);
00541 earlyDeleteHelperToBranchIndicies_.resize(upperLimitOnIndicies,0);
00542 earlyDeleteBranchToCount_.reserve(nUniqueBranchesToDelete);
00543 std::map<const Worker*,EarlyDeleteHelper*> alreadySeenWorkers;
00544 std::string lastBranchName;
00545 size_t nextOpenIndex = 0;
00546 unsigned int* beginAddress = &(earlyDeleteHelperToBranchIndicies_.front());
00547 for(auto& branchAndWorker:branchToReadingWorker) {
00548 if(lastBranchName != branchAndWorker.first) {
00549
00550 BranchID bid(branchAndWorker.first+".");
00551 earlyDeleteBranchToCount_.emplace_back(std::make_pair(bid,0U));
00552 lastBranchName = branchAndWorker.first;
00553 }
00554 auto found = alreadySeenWorkers.find(branchAndWorker.second);
00555 if(alreadySeenWorkers.end() == found) {
00556
00557
00558
00559
00560 size_t index = nextOpenIndex;
00561 size_t nIndices = reserveSizeForWorker[branchAndWorker.second];
00562 earlyDeleteHelperToBranchIndicies_[index]=earlyDeleteBranchToCount_.size()-1;
00563 earlyDeleteHelpers_.emplace_back(EarlyDeleteHelper(beginAddress+index,
00564 beginAddress+index+1,
00565 &earlyDeleteBranchToCount_));
00566 branchAndWorker.second->setEarlyDeleteHelper(&(earlyDeleteHelpers_.back()));
00567 alreadySeenWorkers.insert(std::make_pair(branchAndWorker.second,&(earlyDeleteHelpers_.back())));
00568 nextOpenIndex +=nIndices;
00569 } else {
00570 found->second->appendIndex(earlyDeleteBranchToCount_.size()-1);
00571 }
00572 }
00573
00574
00575
00576 auto itLast = earlyDeleteHelpers_.begin();
00577 for(auto it = earlyDeleteHelpers_.begin()+1;it != earlyDeleteHelpers_.end();++it) {
00578 if(itLast->end() != it->begin()) {
00579
00580 unsigned int delta = it->begin()- itLast->end();
00581 it->shiftIndexPointers(delta);
00582
00583 earlyDeleteHelperToBranchIndicies_.erase(earlyDeleteHelperToBranchIndicies_.begin()+
00584 (itLast->end()-beginAddress),
00585 earlyDeleteHelperToBranchIndicies_.begin()+
00586 (it->begin()-beginAddress));
00587 }
00588 itLast = it;
00589 }
00590 earlyDeleteHelperToBranchIndicies_.erase(earlyDeleteHelperToBranchIndicies_.begin()+(itLast->end()-beginAddress),
00591 earlyDeleteHelperToBranchIndicies_.end());
00592
00593
00594 for(auto& p : trig_paths_) {
00595 p.setEarlyDeleteHelpers(alreadySeenWorkers);
00596 }
00597 for(auto& p : end_paths_) {
00598 p.setEarlyDeleteHelpers(alreadySeenWorkers);
00599 }
00600 resetEarlyDelete();
00601 }
00602 }
00603
00604 void Schedule::reduceParameterSet(ParameterSet& proc_pset,
00605 vstring& modulesInConfig,
00606 std::set<std::string> const& modulesInConfigSet,
00607 vstring& labelsOnTriggerPaths,
00608 vstring& shouldBeUsedLabels,
00609 std::map<std::string, std::vector<std::pair<std::string, int> > >& outputModulePathPositions) {
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 vstring labelsToBeDropped;
00623 vstring outputModuleLabels;
00624 std::string edmType;
00625 std::string const moduleEdmType("@module_edm_type");
00626 std::string const outputModule("OutputModule");
00627 std::string const edAnalyzer("EDAnalyzer");
00628 std::string const edFilter("EDFilter");
00629 std::string const edProducer("EDProducer");
00630 sort_all(labelsOnTriggerPaths);
00631 vstring::const_iterator iLabelsOnTriggerPaths = labelsOnTriggerPaths.begin();
00632 vstring::const_iterator endLabelsOnTriggerPaths = labelsOnTriggerPaths.end();
00633 sort_all(shouldBeUsedLabels);
00634 vstring::const_iterator iShouldBeUsedLabels = shouldBeUsedLabels.begin();
00635 vstring::const_iterator endShouldBeUsedLabels = shouldBeUsedLabels.end();
00636
00637 for (std::set<std::string>::const_iterator i = modulesInConfigSet.begin(),
00638 e = modulesInConfigSet.end(); i != e; ++i) {
00639 edmType = proc_pset.getParameterSet(*i).getParameter<std::string>(moduleEdmType);
00640 if (edmType == outputModule) {
00641 labelsToBeDropped.push_back(*i);
00642 outputModuleLabels.push_back(*i);
00643 }
00644 else if (edmType == edAnalyzer) {
00645 while (iLabelsOnTriggerPaths != endLabelsOnTriggerPaths &&
00646 *iLabelsOnTriggerPaths < *i) {
00647 ++iLabelsOnTriggerPaths;
00648 }
00649 if (iLabelsOnTriggerPaths == endLabelsOnTriggerPaths ||
00650 *iLabelsOnTriggerPaths != *i) {
00651 labelsToBeDropped.push_back(*i);
00652 }
00653 }
00654 else if (edmType == edFilter || edmType == edProducer) {
00655 while (iShouldBeUsedLabels != endShouldBeUsedLabels &&
00656 *iShouldBeUsedLabels < *i) {
00657 ++iShouldBeUsedLabels;
00658 }
00659 if (iShouldBeUsedLabels != endShouldBeUsedLabels &&
00660 *iShouldBeUsedLabels == *i) {
00661 labelsToBeDropped.push_back(*i);
00662 }
00663 }
00664 }
00665
00666
00667 for_all(labelsToBeDropped, boost::bind(&ParameterSet::eraseOrSetUntrackedParameterSet, boost::ref(proc_pset), _1));
00668
00669
00670 vstring::iterator endAfterRemove = std::remove_if(modulesInConfig.begin(), modulesInConfig.end(), boost::bind(binary_search_string, boost::ref(labelsToBeDropped), _1));
00671 modulesInConfig.erase(endAfterRemove, modulesInConfig.end());
00672 proc_pset.addParameter<vstring>(std::string("@all_modules"), modulesInConfig);
00673
00674
00675 vstring endPathsToBeDropped;
00676 vstring labels;
00677 for (vstring::iterator iEndPath = end_path_name_list_.begin(), endEndPath = end_path_name_list_.end();
00678 iEndPath != endEndPath;
00679 ++iEndPath) {
00680 labels = proc_pset.getParameter<vstring>(*iEndPath);
00681 vstring::iterator iSave = labels.begin();
00682 vstring::iterator iBegin = labels.begin();
00683
00684 for (vstring::iterator iLabel = labels.begin(), iEnd = labels.end();
00685 iLabel != iEnd; ++iLabel) {
00686 if (binary_search_string(labelsToBeDropped, *iLabel)) {
00687 if (binary_search_string(outputModuleLabels, *iLabel)) {
00688 outputModulePathPositions[*iLabel].push_back(std::pair<std::string, int>(*iEndPath, iSave - iBegin));
00689 }
00690 } else {
00691 if (iSave != iLabel) {
00692 iSave->swap(*iLabel);
00693 }
00694 ++iSave;
00695 }
00696 }
00697 labels.erase(iSave, labels.end());
00698 if (labels.empty()) {
00699
00700 proc_pset.eraseSimpleParameter(*iEndPath);
00701 endPathsToBeDropped.push_back(*iEndPath);
00702 } else {
00703 proc_pset.addParameter<vstring>(*iEndPath, labels);
00704 }
00705 }
00706 sort_all(endPathsToBeDropped);
00707
00708
00709 vstring scheduledPaths = proc_pset.getParameter<vstring>("@paths");
00710 endAfterRemove = std::remove_if(scheduledPaths.begin(), scheduledPaths.end(), boost::bind(binary_search_string, boost::ref(endPathsToBeDropped), _1));
00711 scheduledPaths.erase(endAfterRemove, scheduledPaths.end());
00712 proc_pset.addParameter<vstring>(std::string("@paths"), scheduledPaths);
00713
00714
00715 vstring scheduledEndPaths = proc_pset.getParameter<vstring>("@end_paths");
00716 endAfterRemove = std::remove_if(scheduledEndPaths.begin(), scheduledEndPaths.end(), boost::bind(binary_search_string, boost::ref(endPathsToBeDropped), _1));
00717 scheduledEndPaths.erase(endAfterRemove, scheduledEndPaths.end());
00718 proc_pset.addParameter<vstring>(std::string("@end_paths"), scheduledEndPaths);
00719 }
00720
00721 void
00722 Schedule::limitOutput(ParameterSet const& proc_pset, BranchIDLists const& branchIDLists) {
00723 std::string const output("output");
00724
00725 ParameterSet const& maxEventsPSet = proc_pset.getUntrackedParameterSet("maxEvents", ParameterSet());
00726 int maxEventSpecs = 0;
00727 int maxEventsOut = -1;
00728 ParameterSet const* vMaxEventsOut = 0;
00729 std::vector<std::string> intNamesE = maxEventsPSet.getParameterNamesForType<int>(false);
00730 if (search_all(intNamesE, output)) {
00731 maxEventsOut = maxEventsPSet.getUntrackedParameter<int>(output);
00732 ++maxEventSpecs;
00733 }
00734 std::vector<std::string> psetNamesE;
00735 maxEventsPSet.getParameterSetNames(psetNamesE, false);
00736 if (search_all(psetNamesE, output)) {
00737 vMaxEventsOut = &maxEventsPSet.getUntrackedParameterSet(output);
00738 ++maxEventSpecs;
00739 }
00740
00741 if (maxEventSpecs > 1) {
00742 throw Exception(errors::Configuration) <<
00743 "\nAt most, one form of 'output' may appear in the 'maxEvents' parameter set";
00744 }
00745
00746 for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(), itEnd = all_output_workers_.end();
00747 it != itEnd; ++it) {
00748 OutputModuleDescription desc(branchIDLists, maxEventsOut);
00749 if (vMaxEventsOut != 0 && !vMaxEventsOut->empty()) {
00750 std::string moduleLabel = (*it)->description().moduleLabel();
00751 try {
00752 desc.maxEvents_ = vMaxEventsOut->getUntrackedParameter<int>(moduleLabel);
00753 } catch (Exception const&) {
00754 throw Exception(errors::Configuration) <<
00755 "\nNo entry in 'maxEvents' for output module label '" << moduleLabel << "'.\n";
00756 }
00757 }
00758 (*it)->configure(desc);
00759 }
00760 }
00761
00762 bool Schedule::terminate() const {
00763 if (all_output_workers_.empty()) {
00764 return false;
00765 }
00766 for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(),
00767 itEnd = all_output_workers_.end();
00768 it != itEnd; ++it) {
00769 if (!(*it)->limitReached()) {
00770
00771 return false;
00772 }
00773 }
00774 LogInfo("SuccessfulTermination")
00775 << "The job is terminating successfully because each output module\n"
00776 << "has reached its configured limit.\n";
00777 return true;
00778 }
00779
00780 void Schedule::fillWorkers(ParameterSet& proc_pset,
00781 ProductRegistry& preg,
00782 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00783 std::string const& name,
00784 bool ignoreFilters,
00785 PathWorkers& out,
00786 vstring* labelsOnPaths) {
00787 vstring modnames = proc_pset.getParameter<vstring>(name);
00788 vstring::iterator it(modnames.begin()), ie(modnames.end());
00789 PathWorkers tmpworkers;
00790
00791 for (; it != ie; ++it) {
00792
00793 if (labelsOnPaths) labelsOnPaths->push_back(*it);
00794
00795 WorkerInPath::FilterAction filterAction = WorkerInPath::Normal;
00796 if ((*it)[0] == '!') filterAction = WorkerInPath::Veto;
00797 else if ((*it)[0] == '-') filterAction = WorkerInPath::Ignore;
00798
00799 std::string moduleLabel = *it;
00800 if (filterAction != WorkerInPath::Normal) moduleLabel.erase(0, 1);
00801
00802 bool isTracked;
00803 ParameterSet* modpset = proc_pset.getPSetForUpdate(moduleLabel, isTracked);
00804 if (modpset == 0) {
00805 std::string pathType("endpath");
00806 if (!search_all(end_path_name_list_, name)) {
00807 pathType = std::string("path");
00808 }
00809 throw Exception(errors::Configuration) <<
00810 "The unknown module label \"" << moduleLabel <<
00811 "\" appears in " << pathType << " \"" << name <<
00812 "\"\n please check spelling or remove that label from the path.";
00813 }
00814 assert(isTracked);
00815
00816 WorkerParams params(proc_pset, modpset, preg, processConfiguration, *act_table_);
00817 Worker* worker = worker_reg_.getWorker(params, moduleLabel);
00818 if (ignoreFilters && filterAction != WorkerInPath::Ignore && dynamic_cast<WorkerT<EDFilter>*>(worker)) {
00819
00820
00821 std::vector<std::string> allowed_filters = proc_pset.getUntrackedParameter<vstring>("@filters_on_endpaths");
00822 if (!search_all(allowed_filters, worker->description().moduleName())) {
00823
00824 filterAction = WorkerInPath::Ignore;
00825 LogWarning("FilterOnEndPath")
00826 << "The EDFilter '" << worker->description().moduleName() << "' with module label '" << moduleLabel << "' appears on EndPath '" << name << "'.\n"
00827 << "The return value of the filter will be ignored.\n"
00828 << "To suppress this warning, either remove the filter from the endpath,\n"
00829 << "or explicitly ignore it in the configuration by using cms.ignore().\n";
00830 }
00831 }
00832 WorkerInPath w(worker, filterAction);
00833 tmpworkers.push_back(w);
00834 }
00835
00836 out.swap(tmpworkers);
00837 }
00838
00839 void Schedule::fillTrigPath(ParameterSet& proc_pset,
00840 ProductRegistry& preg,
00841 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00842 int bitpos, std::string const& name, TrigResPtr trptr,
00843 vstring* labelsOnTriggerPaths) {
00844 PathWorkers tmpworkers;
00845 Workers holder;
00846 fillWorkers(proc_pset, preg, processConfiguration, name, false, tmpworkers, labelsOnTriggerPaths);
00847
00848 for (PathWorkers::iterator wi(tmpworkers.begin()),
00849 we(tmpworkers.end()); wi != we; ++wi) {
00850 holder.push_back(wi->getWorker());
00851 }
00852
00853
00854 if (!tmpworkers.empty()) {
00855 Path p(bitpos, name, tmpworkers, trptr, *act_table_, actReg_, false);
00856 if (wantSummary_) {
00857 p.useStopwatch();
00858 }
00859 trig_paths_.push_back(p);
00860 }
00861 for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
00862 }
00863
00864 void Schedule::fillEndPath(ParameterSet& proc_pset,
00865 ProductRegistry& preg,
00866 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00867 int bitpos, std::string const& name) {
00868 PathWorkers tmpworkers;
00869 fillWorkers(proc_pset, preg, processConfiguration, name, true, tmpworkers, 0);
00870 Workers holder;
00871
00872 for (PathWorkers::iterator wi(tmpworkers.begin()), we(tmpworkers.end()); wi != we; ++wi) {
00873 holder.push_back(wi->getWorker());
00874 }
00875
00876 if (!tmpworkers.empty()) {
00877 Path p(bitpos, name, tmpworkers, endpath_results_, *act_table_, actReg_, true);
00878 if (wantSummary_) {
00879 p.useStopwatch();
00880 }
00881 end_paths_.push_back(p);
00882 }
00883 for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
00884 }
00885
00886 void Schedule::endJob(ExceptionCollector & collector) {
00887 bool failure = false;
00888 AllWorkers::iterator ai(workersBegin()), ae(workersEnd());
00889 for (; ai != ae; ++ai) {
00890 try {
00891 try {
00892 (*ai)->endJob();
00893 }
00894 catch (cms::Exception& e) { throw; }
00895 catch (std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00896 catch (std::exception& e) { convertException::stdToEDM(e); }
00897 catch (std::string& s) { convertException::stringToEDM(s); }
00898 catch (char const* c) { convertException::charPtrToEDM(c); }
00899 catch (...) { convertException::unknownToEDM(); }
00900 }
00901 catch (cms::Exception const& ex) {
00902 collector.addException(ex);
00903 failure = true;
00904 }
00905 }
00906 if (failure) {
00907 return;
00908 }
00909
00910 if (wantSummary_ == false) return;
00911
00912 TrigPaths::const_iterator pi, pe;
00913
00914
00915
00916 LogVerbatim("FwkSummary") << "";
00917 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Event Summary ------------";
00918 LogVerbatim("FwkSummary") << "TrigReport"
00919 << " Events total = " << totalEvents()
00920 << " passed = " << totalEventsPassed()
00921 << " failed = " << (totalEventsFailed())
00922 << "";
00923
00924 LogVerbatim("FwkSummary") << "";
00925 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Path Summary ------------";
00926 LogVerbatim("FwkSummary") << "TrigReport "
00927 << std::right << std::setw(10) << "Trig Bit#" << " "
00928 << std::right << std::setw(10) << "Run" << " "
00929 << std::right << std::setw(10) << "Passed" << " "
00930 << std::right << std::setw(10) << "Failed" << " "
00931 << std::right << std::setw(10) << "Error" << " "
00932 << "Name" << "";
00933 pi = trig_paths_.begin();
00934 pe = trig_paths_.end();
00935 for (; pi != pe; ++pi) {
00936 LogVerbatim("FwkSummary") << "TrigReport "
00937 << std::right << std::setw(5) << 1
00938 << std::right << std::setw(5) << pi->bitPosition() << " "
00939 << std::right << std::setw(10) << pi->timesRun() << " "
00940 << std::right << std::setw(10) << pi->timesPassed() << " "
00941 << std::right << std::setw(10) << pi->timesFailed() << " "
00942 << std::right << std::setw(10) << pi->timesExcept() << " "
00943 << pi->name() << "";
00944 }
00945
00946 LogVerbatim("FwkSummary") << "";
00947 LogVerbatim("FwkSummary") << "TrigReport " << "-------End-Path Summary ------------";
00948 LogVerbatim("FwkSummary") << "TrigReport "
00949 << std::right << std::setw(10) << "Trig Bit#" << " "
00950 << std::right << std::setw(10) << "Run" << " "
00951 << std::right << std::setw(10) << "Passed" << " "
00952 << std::right << std::setw(10) << "Failed" << " "
00953 << std::right << std::setw(10) << "Error" << " "
00954 << "Name" << "";
00955 pi = end_paths_.begin();
00956 pe = end_paths_.end();
00957 for (; pi != pe; ++pi) {
00958 LogVerbatim("FwkSummary") << "TrigReport "
00959 << std::right << std::setw(5) << 0
00960 << std::right << std::setw(5) << pi->bitPosition() << " "
00961 << std::right << std::setw(10) << pi->timesRun() << " "
00962 << std::right << std::setw(10) << pi->timesPassed() << " "
00963 << std::right << std::setw(10) << pi->timesFailed() << " "
00964 << std::right << std::setw(10) << pi->timesExcept() << " "
00965 << pi->name() << "";
00966 }
00967
00968 pi = trig_paths_.begin();
00969 pe = trig_paths_.end();
00970 for (; pi != pe; ++pi) {
00971 LogVerbatim("FwkSummary") << "";
00972 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Modules in Path: " << pi->name() << " ------------";
00973 LogVerbatim("FwkSummary") << "TrigReport "
00974 << std::right << std::setw(10) << "Trig Bit#" << " "
00975 << std::right << std::setw(10) << "Visited" << " "
00976 << std::right << std::setw(10) << "Passed" << " "
00977 << std::right << std::setw(10) << "Failed" << " "
00978 << std::right << std::setw(10) << "Error" << " "
00979 << "Name" << "";
00980
00981 for (unsigned int i = 0; i < pi->size(); ++i) {
00982 LogVerbatim("FwkSummary") << "TrigReport "
00983 << std::right << std::setw(5) << 1
00984 << std::right << std::setw(5) << pi->bitPosition() << " "
00985 << std::right << std::setw(10) << pi->timesVisited(i) << " "
00986 << std::right << std::setw(10) << pi->timesPassed(i) << " "
00987 << std::right << std::setw(10) << pi->timesFailed(i) << " "
00988 << std::right << std::setw(10) << pi->timesExcept(i) << " "
00989 << pi->getWorker(i)->description().moduleLabel() << "";
00990 }
00991 }
00992
00993 pi = end_paths_.begin();
00994 pe = end_paths_.end();
00995 for (; pi != pe; ++pi) {
00996 LogVerbatim("FwkSummary") << "";
00997 LogVerbatim("FwkSummary") << "TrigReport " << "------ Modules in End-Path: " << pi->name() << " ------------";
00998 LogVerbatim("FwkSummary") << "TrigReport "
00999 << std::right << std::setw(10) << "Trig Bit#" << " "
01000 << std::right << std::setw(10) << "Visited" << " "
01001 << std::right << std::setw(10) << "Passed" << " "
01002 << std::right << std::setw(10) << "Failed" << " "
01003 << std::right << std::setw(10) << "Error" << " "
01004 << "Name" << "";
01005
01006 for (unsigned int i = 0; i < pi->size(); ++i) {
01007 LogVerbatim("FwkSummary") << "TrigReport "
01008 << std::right << std::setw(5) << 0
01009 << std::right << std::setw(5) << pi->bitPosition() << " "
01010 << std::right << std::setw(10) << pi->timesVisited(i) << " "
01011 << std::right << std::setw(10) << pi->timesPassed(i) << " "
01012 << std::right << std::setw(10) << pi->timesFailed(i) << " "
01013 << std::right << std::setw(10) << pi->timesExcept(i) << " "
01014 << pi->getWorker(i)->description().moduleLabel() << "";
01015 }
01016 }
01017
01018 LogVerbatim("FwkSummary") << "";
01019 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Module Summary ------------";
01020 LogVerbatim("FwkSummary") << "TrigReport "
01021 << std::right << std::setw(10) << "Visited" << " "
01022 << std::right << std::setw(10) << "Run" << " "
01023 << std::right << std::setw(10) << "Passed" << " "
01024 << std::right << std::setw(10) << "Failed" << " "
01025 << std::right << std::setw(10) << "Error" << " "
01026 << "Name" << "";
01027 ai = workersBegin();
01028 ae = workersEnd();
01029 for (; ai != ae; ++ai) {
01030 LogVerbatim("FwkSummary") << "TrigReport "
01031 << std::right << std::setw(10) << (*ai)->timesVisited() << " "
01032 << std::right << std::setw(10) << (*ai)->timesRun() << " "
01033 << std::right << std::setw(10) << (*ai)->timesPassed() << " "
01034 << std::right << std::setw(10) << (*ai)->timesFailed() << " "
01035 << std::right << std::setw(10) << (*ai)->timesExcept() << " "
01036 << (*ai)->description().moduleLabel() << "";
01037
01038 }
01039 LogVerbatim("FwkSummary") << "";
01040
01041
01042
01043 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Event Summary ---[sec]----";
01044 LogVerbatim("FwkSummary") << "TimeReport"
01045 << std::setprecision(6) << std::fixed
01046 << " CPU/event = " << timeCpuReal().first/std::max(1, totalEvents())
01047 << " Real/event = " << timeCpuReal().second/std::max(1, totalEvents())
01048 << "";
01049
01050 LogVerbatim("FwkSummary") << "";
01051 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Path Summary ---[sec]----";
01052 LogVerbatim("FwkSummary") << "TimeReport "
01053 << std::right << std::setw(22) << "per event "
01054 << std::right << std::setw(22) << "per path-run "
01055 << "";
01056 LogVerbatim("FwkSummary") << "TimeReport "
01057 << std::right << std::setw(10) << "CPU" << " "
01058 << std::right << std::setw(10) << "Real" << " "
01059 << std::right << std::setw(10) << "CPU" << " "
01060 << std::right << std::setw(10) << "Real" << " "
01061 << "Name" << "";
01062 pi = trig_paths_.begin();
01063 pe = trig_paths_.end();
01064 for (; pi != pe; ++pi) {
01065 LogVerbatim("FwkSummary") << "TimeReport "
01066 << std::setprecision(6) << std::fixed
01067 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
01068 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
01069 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
01070 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
01071 << pi->name() << "";
01072 }
01073 LogVerbatim("FwkSummary") << "TimeReport "
01074 << std::right << std::setw(10) << "CPU" << " "
01075 << std::right << std::setw(10) << "Real" << " "
01076 << std::right << std::setw(10) << "CPU" << " "
01077 << std::right << std::setw(10) << "Real" << " "
01078 << "Name" << "";
01079 LogVerbatim("FwkSummary") << "TimeReport "
01080 << std::right << std::setw(22) << "per event "
01081 << std::right << std::setw(22) << "per path-run "
01082 << "";
01083
01084 LogVerbatim("FwkSummary") << "";
01085 LogVerbatim("FwkSummary") << "TimeReport " << "-------End-Path Summary ---[sec]----";
01086 LogVerbatim("FwkSummary") << "TimeReport "
01087 << std::right << std::setw(22) << "per event "
01088 << std::right << std::setw(22) << "per endpath-run "
01089 << "";
01090 LogVerbatim("FwkSummary") << "TimeReport "
01091 << std::right << std::setw(10) << "CPU" << " "
01092 << std::right << std::setw(10) << "Real" << " "
01093 << std::right << std::setw(10) << "CPU" << " "
01094 << std::right << std::setw(10) << "Real" << " "
01095 << "Name" << "";
01096 pi = end_paths_.begin();
01097 pe = end_paths_.end();
01098 for (; pi != pe; ++pi) {
01099 LogVerbatim("FwkSummary") << "TimeReport "
01100 << std::setprecision(6) << std::fixed
01101 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
01102 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
01103 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
01104 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
01105 << pi->name() << "";
01106 }
01107 LogVerbatim("FwkSummary") << "TimeReport "
01108 << std::right << std::setw(10) << "CPU" << " "
01109 << std::right << std::setw(10) << "Real" << " "
01110 << std::right << std::setw(10) << "CPU" << " "
01111 << std::right << std::setw(10) << "Real" << " "
01112 << "Name" << "";
01113 LogVerbatim("FwkSummary") << "TimeReport "
01114 << std::right << std::setw(22) << "per event "
01115 << std::right << std::setw(22) << "per endpath-run "
01116 << "";
01117
01118 pi = trig_paths_.begin();
01119 pe = trig_paths_.end();
01120 for (; pi != pe; ++pi) {
01121 LogVerbatim("FwkSummary") << "";
01122 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Modules in Path: " << pi->name() << " ---[sec]----";
01123 LogVerbatim("FwkSummary") << "TimeReport "
01124 << std::right << std::setw(22) << "per event "
01125 << std::right << std::setw(22) << "per module-visit "
01126 << "";
01127 LogVerbatim("FwkSummary") << "TimeReport "
01128 << std::right << std::setw(10) << "CPU" << " "
01129 << std::right << std::setw(10) << "Real" << " "
01130 << std::right << std::setw(10) << "CPU" << " "
01131 << std::right << std::setw(10) << "Real" << " "
01132 << "Name" << "";
01133 for (unsigned int i = 0; i < pi->size(); ++i) {
01134 LogVerbatim("FwkSummary") << "TimeReport "
01135 << std::setprecision(6) << std::fixed
01136 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
01137 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
01138 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
01139 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
01140 << pi->getWorker(i)->description().moduleLabel() << "";
01141 }
01142 }
01143 LogVerbatim("FwkSummary") << "TimeReport "
01144 << std::right << std::setw(10) << "CPU" << " "
01145 << std::right << std::setw(10) << "Real" << " "
01146 << std::right << std::setw(10) << "CPU" << " "
01147 << std::right << std::setw(10) << "Real" << " "
01148 << "Name" << "";
01149 LogVerbatim("FwkSummary") << "TimeReport "
01150 << std::right << std::setw(22) << "per event "
01151 << std::right << std::setw(22) << "per module-visit "
01152 << "";
01153
01154 pi = end_paths_.begin();
01155 pe = end_paths_.end();
01156 for (; pi != pe; ++pi) {
01157 LogVerbatim("FwkSummary") << "";
01158 LogVerbatim("FwkSummary") << "TimeReport " << "------ Modules in End-Path: " << pi->name() << " ---[sec]----";
01159 LogVerbatim("FwkSummary") << "TimeReport "
01160 << std::right << std::setw(22) << "per event "
01161 << std::right << std::setw(22) << "per module-visit "
01162 << "";
01163 LogVerbatim("FwkSummary") << "TimeReport "
01164 << std::right << std::setw(10) << "CPU" << " "
01165 << std::right << std::setw(10) << "Real" << " "
01166 << std::right << std::setw(10) << "CPU" << " "
01167 << std::right << std::setw(10) << "Real" << " "
01168 << "Name" << "";
01169 for (unsigned int i = 0; i < pi->size(); ++i) {
01170 LogVerbatim("FwkSummary") << "TimeReport "
01171 << std::setprecision(6) << std::fixed
01172 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
01173 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
01174 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
01175 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
01176 << pi->getWorker(i)->description().moduleLabel() << "";
01177 }
01178 }
01179 LogVerbatim("FwkSummary") << "TimeReport "
01180 << std::right << std::setw(10) << "CPU" << " "
01181 << std::right << std::setw(10) << "Real" << " "
01182 << std::right << std::setw(10) << "CPU" << " "
01183 << std::right << std::setw(10) << "Real" << " "
01184 << "Name" << "";
01185 LogVerbatim("FwkSummary") << "TimeReport "
01186 << std::right << std::setw(22) << "per event "
01187 << std::right << std::setw(22) << "per module-visit "
01188 << "";
01189
01190 LogVerbatim("FwkSummary") << "";
01191 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Module Summary ---[sec]----";
01192 LogVerbatim("FwkSummary") << "TimeReport "
01193 << std::right << std::setw(22) << "per event "
01194 << std::right << std::setw(22) << "per module-run "
01195 << std::right << std::setw(22) << "per module-visit "
01196 << "";
01197 LogVerbatim("FwkSummary") << "TimeReport "
01198 << std::right << std::setw(10) << "CPU" << " "
01199 << std::right << std::setw(10) << "Real" << " "
01200 << std::right << std::setw(10) << "CPU" << " "
01201 << std::right << std::setw(10) << "Real" << " "
01202 << std::right << std::setw(10) << "CPU" << " "
01203 << std::right << std::setw(10) << "Real" << " "
01204 << "Name" << "";
01205 ai = workersBegin();
01206 ae = workersEnd();
01207 for (; ai != ae; ++ai) {
01208 LogVerbatim("FwkSummary") << "TimeReport "
01209 << std::setprecision(6) << std::fixed
01210 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, totalEvents()) << " "
01211 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, totalEvents()) << " "
01212 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesRun()) << " "
01213 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesRun()) << " "
01214 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesVisited()) << " "
01215 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesVisited()) << " "
01216 << (*ai)->description().moduleLabel() << "";
01217 }
01218 LogVerbatim("FwkSummary") << "TimeReport "
01219 << std::right << std::setw(10) << "CPU" << " "
01220 << std::right << std::setw(10) << "Real" << " "
01221 << std::right << std::setw(10) << "CPU" << " "
01222 << std::right << std::setw(10) << "Real" << " "
01223 << std::right << std::setw(10) << "CPU" << " "
01224 << std::right << std::setw(10) << "Real" << " "
01225 << "Name" << "";
01226 LogVerbatim("FwkSummary") << "TimeReport "
01227 << std::right << std::setw(22) << "per event "
01228 << std::right << std::setw(22) << "per module-run "
01229 << std::right << std::setw(22) << "per module-visit "
01230 << "";
01231
01232 LogVerbatim("FwkSummary") << "";
01233 LogVerbatim("FwkSummary") << "T---Report end!" << "";
01234 LogVerbatim("FwkSummary") << "";
01235 }
01236
01237 void Schedule::closeOutputFiles() {
01238 for_all(all_output_workers_, boost::bind(&OutputWorker::closeFile, _1));
01239 }
01240
01241 void Schedule::openNewOutputFilesIfNeeded() {
01242 for_all(all_output_workers_, boost::bind(&OutputWorker::openNewFileIfNeeded, _1));
01243 }
01244
01245 void Schedule::openOutputFiles(FileBlock& fb) {
01246 for_all(all_output_workers_, boost::bind(&OutputWorker::openFile, _1, boost::cref(fb)));
01247 }
01248
01249 void Schedule::writeRun(RunPrincipal const& rp) {
01250 for_all(all_output_workers_, boost::bind(&OutputWorker::writeRun, _1, boost::cref(rp)));
01251 }
01252
01253 void Schedule::writeLumi(LuminosityBlockPrincipal const& lbp) {
01254 for_all(all_output_workers_, boost::bind(&OutputWorker::writeLumi, _1, boost::cref(lbp)));
01255 }
01256
01257 bool Schedule::shouldWeCloseOutput() const {
01258
01259 return (std::find_if (all_output_workers_.begin(), all_output_workers_.end(),
01260 boost::bind(&OutputWorker::shouldWeCloseFile, _1))
01261 != all_output_workers_.end());
01262 }
01263
01264 void Schedule::respondToOpenInputFile(FileBlock const& fb) {
01265 for_all(all_workers_, boost::bind(&Worker::respondToOpenInputFile, _1, boost::cref(fb)));
01266 }
01267
01268 void Schedule::respondToCloseInputFile(FileBlock const& fb) {
01269 for_all(all_workers_, boost::bind(&Worker::respondToCloseInputFile, _1, boost::cref(fb)));
01270 }
01271
01272 void Schedule::respondToOpenOutputFiles(FileBlock const& fb) {
01273 for_all(all_workers_, boost::bind(&Worker::respondToOpenOutputFiles, _1, boost::cref(fb)));
01274 }
01275
01276 void Schedule::respondToCloseOutputFiles(FileBlock const& fb) {
01277 for_all(all_workers_, boost::bind(&Worker::respondToCloseOutputFiles, _1, boost::cref(fb)));
01278 }
01279
01280 void Schedule::beginJob() {
01281 for_all(all_workers_, boost::bind(&Worker::beginJob, _1));
01282 loadMissingDictionaries();
01283 }
01284
01285 void Schedule::preForkReleaseResources() {
01286 for_all(all_workers_, boost::bind(&Worker::preForkReleaseResources, _1));
01287 }
01288 void Schedule::postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren) {
01289 for_all(all_workers_, boost::bind(&Worker::postForkReacquireResources, _1, iChildIndex, iNumberOfChildren));
01290 }
01291
01292 bool Schedule::changeModule(std::string const& iLabel,
01293 ParameterSet const& iPSet) {
01294 Worker* found = 0;
01295 for (AllWorkers::const_iterator it=all_workers_.begin(), itEnd=all_workers_.end();
01296 it != itEnd; ++it) {
01297 if ((*it)->description().moduleLabel() == iLabel) {
01298 found = *it;
01299 break;
01300 }
01301 }
01302 if (0 == found) {
01303 return false;
01304 }
01305
01306 std::auto_ptr<Maker> wm(MakerPluginFactory::get()->create(found->description().moduleName()));
01307 wm->swapModule(found, iPSet);
01308 found->beginJob();
01309 return true;
01310 }
01311
01312 std::vector<ModuleDescription const*>
01313 Schedule::getAllModuleDescriptions() const {
01314 AllWorkers::const_iterator i(workersBegin());
01315 AllWorkers::const_iterator e(workersEnd());
01316
01317 std::vector<ModuleDescription const*> result;
01318 result.reserve(all_workers_.size());
01319
01320 for (; i != e; ++i) {
01321 ModuleDescription const* p = (*i)->descPtr();
01322 result.push_back(p);
01323 }
01324 return result;
01325 }
01326
01327 void
01328 Schedule::availablePaths(std::vector<std::string>& oLabelsToFill) const {
01329 oLabelsToFill.reserve(trig_paths_.size());
01330 std::transform(trig_paths_.begin(),
01331 trig_paths_.end(),
01332 std::back_inserter(oLabelsToFill),
01333 boost::bind(&Path::name, _1));
01334 }
01335
01336 void
01337 Schedule::modulesInPath(std::string const& iPathLabel,
01338 std::vector<std::string>& oLabelsToFill) const {
01339 TrigPaths::const_iterator itFound =
01340 std::find_if (trig_paths_.begin(),
01341 trig_paths_.end(),
01342 boost::bind(std::equal_to<std::string>(),
01343 iPathLabel,
01344 boost::bind(&Path::name, _1)));
01345 if (itFound!=trig_paths_.end()) {
01346 oLabelsToFill.reserve(itFound->size());
01347 for (size_t i = 0; i < itFound->size(); ++i) {
01348 oLabelsToFill.push_back(itFound->getWorker(i)->description().moduleLabel());
01349 }
01350 }
01351 }
01352
01353 void
01354 Schedule::enableEndPaths(bool active) {
01355 endpathsAreActive_ = active;
01356 }
01357
01358 bool
01359 Schedule::endPathsEnabled() const {
01360 return endpathsAreActive_;
01361 }
01362
01363 void
01364 fillModuleInPathSummary(Path const&, ModuleInPathSummary&) {
01365 }
01366
01367 void
01368 fillModuleInPathSummary(Path const& path,
01369 size_t which,
01370 ModuleInPathSummary& sum) {
01371 sum.timesVisited = path.timesVisited(which);
01372 sum.timesPassed = path.timesPassed(which);
01373 sum.timesFailed = path.timesFailed(which);
01374 sum.timesExcept = path.timesExcept(which);
01375 sum.moduleLabel = path.getWorker(which)->description().moduleLabel();
01376 }
01377
01378 void
01379 fillPathSummary(Path const& path, PathSummary& sum) {
01380 sum.name = path.name();
01381 sum.bitPosition = path.bitPosition();
01382 sum.timesRun = path.timesRun();
01383 sum.timesPassed = path.timesPassed();
01384 sum.timesFailed = path.timesFailed();
01385 sum.timesExcept = path.timesExcept();
01386
01387 Path::size_type sz = path.size();
01388 std::vector<ModuleInPathSummary> temp(sz);
01389 for (size_t i = 0; i != sz; ++i) {
01390 fillModuleInPathSummary(path, i, temp[i]);
01391 }
01392 sum.moduleInPathSummaries.swap(temp);
01393 }
01394
01395 void
01396 fillWorkerSummaryAux(Worker const& w, WorkerSummary& sum) {
01397 sum.timesVisited = w.timesVisited();
01398 sum.timesRun = w.timesRun();
01399 sum.timesPassed = w.timesPassed();
01400 sum.timesFailed = w.timesFailed();
01401 sum.timesExcept = w.timesExcept();
01402 sum.moduleLabel = w.description().moduleLabel();
01403 }
01404
01405 void
01406 fillWorkerSummary(Worker const* pw, WorkerSummary& sum) {
01407 fillWorkerSummaryAux(*pw, sum);
01408 }
01409
01410 void
01411 Schedule::getTriggerReport(TriggerReport& rep) const {
01412 rep.eventSummary.totalEvents = totalEvents();
01413 rep.eventSummary.totalEventsPassed = totalEventsPassed();
01414 rep.eventSummary.totalEventsFailed = totalEventsFailed();
01415
01416 fill_summary(trig_paths_, rep.trigPathSummaries, &fillPathSummary);
01417 fill_summary(end_paths_, rep.endPathSummaries, &fillPathSummary);
01418 fill_summary(all_workers_, rep.workerSummaries, &fillWorkerSummary);
01419 }
01420
01421 void
01422 Schedule::clearCounters() {
01423 total_events_ = total_passed_ = 0;
01424 for_all(trig_paths_, boost::bind(&Path::clearCounters, _1));
01425 for_all(end_paths_, boost::bind(&Path::clearCounters, _1));
01426 for_all(all_workers_, boost::bind(&Worker::clearCounters, _1));
01427 }
01428
01429 void
01430 Schedule::resetAll() {
01431 for_all(all_workers_, boost::bind(&Worker::reset, _1));
01432 results_->reset();
01433 endpath_results_->reset();
01434 }
01435
01436 void
01437 Schedule::addToAllWorkers(Worker* w) {
01438 if (!search_all(all_workers_, w)) {
01439 if (wantSummary_) {
01440 w->useStopwatch();
01441 }
01442 all_workers_.push_back(w);
01443 }
01444 }
01445
01446 void
01447 Schedule::setupOnDemandSystem(EventPrincipal& ep, EventSetup const& es) {
01448
01449 unscheduled_->setEventSetup(es);
01450 ep.setUnscheduledHandler(unscheduled_);
01451 }
01452
01453 void
01454 Schedule::resetEarlyDelete() {
01455
01456 for(auto& count:earlyDeleteBranchToCount_) {
01457 count.second = 0;
01458 }
01459
01460 for(auto& index: earlyDeleteHelperToBranchIndicies_) {
01461 ++(earlyDeleteBranchToCount_[index].second);
01462 }
01463 for(auto& helper: earlyDeleteHelpers_) {
01464 helper.reset();
01465 }
01466 }
01467
01468 }