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