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