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