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/src/OutputWorker.h"
00012 #include "FWCore/Framework/src/TriggerResultInserter.h"
00013 #include "FWCore/Framework/src/WorkerInPath.h"
00014 #include "FWCore/Framework/src/WorkerMaker.h"
00015 #include "FWCore/Framework/src/WorkerT.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00018 #include "FWCore/ParameterSet/interface/Registry.h"
00019 #include "FWCore/Utilities/interface/ConvertException.h"
00020 #include "FWCore/Utilities/interface/ExceptionCollector.h"
00021 #include "FWCore/Utilities/interface/ReflexTools.h"
00022
00023 #include "boost/bind.hpp"
00024 #include "boost/ref.hpp"
00025
00026 #include <algorithm>
00027 #include <cassert>
00028 #include <cstdlib>
00029 #include <functional>
00030 #include <iomanip>
00031 #include <list>
00032 #include <exception>
00033
00034 namespace edm {
00035 namespace {
00036
00037
00038
00039
00040
00041 template <typename InputIterator, typename ForwardIterator, typename Func>
00042 void
00043 transform_into(InputIterator begin, InputIterator end,
00044 ForwardIterator out, Func func) {
00045 for (; begin != end; ++begin, ++out) func(*begin, *out);
00046 }
00047
00048
00049
00050
00051
00052
00053 template <typename FROM, typename TO, typename FUNC>
00054 void
00055 fill_summary(FROM const& from, TO& to, FUNC func) {
00056 TO temp(from.size());
00057 transform_into(from.begin(), from.end(), temp.begin(), func);
00058 to.swap(temp);
00059 }
00060
00061
00062
00063
00064
00065
00066 Schedule::WorkerPtr
00067 makeInserter(ParameterSet& proc_pset,
00068 ProductRegistry& preg,
00069 ActionTable const& actions,
00070 boost::shared_ptr<ActivityRegistry> areg,
00071 boost::shared_ptr<ProcessConfiguration> processConfiguration,
00072 Schedule::TrigResPtr trptr) {
00073
00074 ParameterSet* trig_pset = proc_pset.getPSetForUpdate("@trigger_paths");
00075 trig_pset->registerIt();
00076
00077 WorkerParams work_args(proc_pset, trig_pset, preg, processConfiguration, actions);
00078 ModuleDescription md(trig_pset->id(),
00079 "TriggerResultInserter",
00080 "TriggerResults",
00081 processConfiguration.get());
00082
00083 areg->preModuleConstructionSignal_(md);
00084 std::auto_ptr<EDProducer> producer(new TriggerResultInserter(*trig_pset, trptr));
00085 areg->postModuleConstructionSignal_(md);
00086
00087 Schedule::WorkerPtr ptr(new WorkerT<EDProducer>(producer, md, work_args));
00088 ptr->setActivityRegistry(areg);
00089 return ptr;
00090 }
00091 }
00092
00093
00094
00095 typedef std::vector<std::string> vstring;
00096
00097
00098
00099 Schedule::Schedule(ParameterSet& proc_pset,
00100 service::TriggerNamesService& tns,
00101 ProductRegistry& preg,
00102 ActionTable const& actions,
00103 boost::shared_ptr<ActivityRegistry> areg,
00104 boost::shared_ptr<ProcessConfiguration> processConfiguration) :
00105 worker_reg_(areg),
00106 act_table_(&actions),
00107 actReg_(areg),
00108 state_(Ready),
00109 trig_name_list_(tns.getTrigPaths()),
00110 end_path_name_list_(tns.getEndPaths()),
00111 results_(new HLTGlobalStatus(trig_name_list_.size())),
00112 endpath_results_(),
00113 results_inserter_(),
00114 all_workers_(),
00115 all_output_workers_(),
00116 trig_paths_(),
00117 end_paths_(),
00118 wantSummary_(tns.wantSummary()),
00119 total_events_(),
00120 total_passed_(),
00121 stopwatch_(wantSummary_? new RunStopwatch::StopwatchPointer::element_type : static_cast<RunStopwatch::StopwatchPointer::element_type*> (0)),
00122 unscheduled_(new UnscheduledCallProducer),
00123 endpathsAreActive_(true),
00124 printedFirstException_(false) {
00125
00126 ParameterSet const& opts = proc_pset.getUntrackedParameterSet("options", ParameterSet());
00127 bool hasPath = false;
00128
00129 int trig_bitpos = 0;
00130 for (vstring::const_iterator i = trig_name_list_.begin(),
00131 e = trig_name_list_.end();
00132 i != e;
00133 ++i) {
00134 fillTrigPath(proc_pset, preg, processConfiguration, trig_bitpos, *i, results_);
00135 ++trig_bitpos;
00136 hasPath = true;
00137 }
00138
00139 if (hasPath) {
00140
00141 results_inserter_ = makeInserter(proc_pset,
00142 preg,
00143 actions, actReg_, processConfiguration, results_);
00144 addToAllWorkers(results_inserter_.get());
00145 }
00146
00147 TrigResPtr epptr(new HLTGlobalStatus(end_path_name_list_.size()));
00148 endpath_results_ = epptr;
00149
00150
00151 vstring::iterator eib(end_path_name_list_.begin()), eie(end_path_name_list_.end());
00152 for (int bitpos = 0; eib != eie; ++eib, ++bitpos) {
00153 fillEndPath(proc_pset, preg, processConfiguration, bitpos, *eib);
00154 }
00155
00156
00157 std::set<std::string> usedWorkerLabels;
00158 for (AllWorkers::iterator itWorker = workersBegin();
00159 itWorker != workersEnd();
00160 ++itWorker) {
00161 usedWorkerLabels.insert((*itWorker)->description().moduleLabel());
00162 }
00163 std::vector<std::string> modulesInConfig(proc_pset.getParameter<std::vector<std::string> >("@all_modules"));
00164 std::set<std::string> modulesInConfigSet(modulesInConfig.begin(), modulesInConfig.end());
00165 std::vector<std::string> unusedLabels;
00166 set_difference(modulesInConfigSet.begin(), modulesInConfigSet.end(),
00167 usedWorkerLabels.begin(), usedWorkerLabels.end(),
00168 back_inserter(unusedLabels));
00169
00170 bool allowUnscheduled = opts.getUntrackedParameter<bool>("allowUnscheduled", false);
00171 std::set<std::string> unscheduledLabels;
00172 if (!unusedLabels.empty()) {
00173
00174
00175
00176
00177 std::vector<std::string> shouldBeUsedLabels;
00178
00179 for (std::vector<std::string>::iterator itLabel = unusedLabels.begin(), itLabelEnd = unusedLabels.end();
00180 itLabel != itLabelEnd;
00181 ++itLabel) {
00182 if (allowUnscheduled) {
00183 bool isTracked;
00184 ParameterSet* modulePSet(proc_pset.getPSetForUpdate(*itLabel, isTracked));
00185 assert(isTracked);
00186 assert(modulePSet != 0);
00187 WorkerParams params(proc_pset, modulePSet, preg,
00188 processConfiguration, *act_table_);
00189 Worker* newWorker(worker_reg_.getWorker(params, *itLabel));
00190 if (dynamic_cast<WorkerT<EDProducer>*>(newWorker) ||
00191 dynamic_cast<WorkerT<EDFilter>*>(newWorker)) {
00192 unscheduledLabels.insert(*itLabel);
00193 unscheduled_->addWorker(newWorker);
00194
00195 addToAllWorkers(newWorker);
00196 } else {
00197
00198 shouldBeUsedLabels.push_back(*itLabel);
00199 }
00200 } else {
00201
00202 shouldBeUsedLabels.push_back(*itLabel);
00203 }
00204 }
00205 if (!shouldBeUsedLabels.empty()) {
00206 std::ostringstream unusedStream;
00207 unusedStream << "'" << shouldBeUsedLabels.front() << "'";
00208 for (std::vector<std::string>::iterator itLabel = shouldBeUsedLabels.begin() + 1,
00209 itLabelEnd = shouldBeUsedLabels.end();
00210 itLabel != itLabelEnd;
00211 ++itLabel) {
00212 unusedStream << ",'" << *itLabel << "'";
00213 }
00214 LogInfo("path")
00215 << "The following module labels are not assigned to any path:\n"
00216 << unusedStream.str()
00217 << "\n";
00218 }
00219 }
00220 if (!unscheduledLabels.empty()) {
00221 for (ProductRegistry::ProductList::const_iterator it = preg.productList().begin(),
00222 itEnd = preg.productList().end();
00223 it != itEnd;
00224 ++it) {
00225 if (it->second.produced() &&
00226 it->second.branchType() == InEvent &&
00227 unscheduledLabels.end() != unscheduledLabels.find(it->second.moduleLabel())) {
00228 it->second.setOnDemand();
00229 }
00230 }
00231 }
00232
00233 proc_pset.registerIt();
00234 pset::Registry::instance()->extra().setID(proc_pset.id());
00235 processConfiguration->setParameterSetID(proc_pset.id());
00236
00237
00238
00239 size_t all_workers_count = all_workers_.size();
00240
00241 for (AllWorkers::iterator i = all_workers_.begin(), e = all_workers_.end();
00242 i != e;
00243 ++i) {
00244
00245
00246
00247 OutputWorker* ow = dynamic_cast<OutputWorker*>(*i);
00248 if (ow) all_output_workers_.push_back(ow);
00249 }
00250
00251
00252 limitOutput(proc_pset);
00253
00254 loadMissingDictionaries();
00255 preg.setFrozen();
00256
00257
00258
00259 assert (all_workers_count == all_workers_.size());
00260
00261 ProcessConfigurationRegistry::instance()->insertMapped(*processConfiguration);
00262 BranchIDListHelper::updateRegistries(preg);
00263 fillProductRegistryTransients(*processConfiguration, preg);
00264 }
00265
00266 void
00267 Schedule::limitOutput(ParameterSet const& proc_pset) {
00268 std::string const output("output");
00269
00270 ParameterSet const& maxEventsPSet = proc_pset.getUntrackedParameterSet("maxEvents", ParameterSet());
00271 int maxEventSpecs = 0;
00272 int maxEventsOut = -1;
00273 ParameterSet const* vMaxEventsOut = 0;
00274 std::vector<std::string> intNamesE = maxEventsPSet.getParameterNamesForType<int>(false);
00275 if (search_all(intNamesE, output)) {
00276 maxEventsOut = maxEventsPSet.getUntrackedParameter<int>(output);
00277 ++maxEventSpecs;
00278 }
00279 std::vector<std::string> psetNamesE;
00280 maxEventsPSet.getParameterSetNames(psetNamesE, false);
00281 if (search_all(psetNamesE, output)) {
00282 vMaxEventsOut = &maxEventsPSet.getUntrackedParameterSet(output);
00283 ++maxEventSpecs;
00284 }
00285
00286 if (maxEventSpecs > 1) {
00287 throw Exception(errors::Configuration) <<
00288 "\nAt most, one form of 'output' may appear in the 'maxEvents' parameter set";
00289 }
00290
00291 if (maxEventSpecs == 0) {
00292 return;
00293 }
00294
00295 for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(), itEnd = all_output_workers_.end();
00296 it != itEnd; ++it) {
00297 OutputModuleDescription desc(maxEventsOut);
00298 if (vMaxEventsOut != 0 && !vMaxEventsOut->empty()) {
00299 std::string moduleLabel = (*it)->description().moduleLabel();
00300 try {
00301 desc.maxEvents_ = vMaxEventsOut->getUntrackedParameter<int>(moduleLabel);
00302 } catch (Exception const&) {
00303 throw Exception(errors::Configuration) <<
00304 "\nNo entry in 'maxEvents' for output module label '" << moduleLabel << "'.\n";
00305 }
00306 }
00307 (*it)->configure(desc);
00308 }
00309 }
00310
00311 bool const Schedule::terminate() const {
00312 if (all_output_workers_.empty()) {
00313 return false;
00314 }
00315 for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(),
00316 itEnd = all_output_workers_.end();
00317 it != itEnd; ++it) {
00318 if (!(*it)->limitReached()) {
00319
00320 return false;
00321 }
00322 }
00323 LogInfo("SuccessfulTermination")
00324 << "The job is terminating successfully because each output module\n"
00325 << "has reached its configured limit.\n";
00326 return true;
00327 }
00328
00329 void Schedule::fillWorkers(ParameterSet& proc_pset,
00330 ProductRegistry& preg,
00331 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00332 std::string const& name,
00333 bool ignoreFilters,
00334 PathWorkers& out) {
00335 vstring modnames = proc_pset.getParameter<vstring>(name);
00336 vstring::iterator it(modnames.begin()), ie(modnames.end());
00337 PathWorkers tmpworkers;
00338
00339 for (; it != ie; ++it) {
00340
00341 WorkerInPath::FilterAction filterAction = WorkerInPath::Normal;
00342 if ((*it)[0] == '!') filterAction = WorkerInPath::Veto;
00343 else if ((*it)[0] == '-') filterAction = WorkerInPath::Ignore;
00344
00345 std::string moduleLabel = *it;
00346 if (filterAction != WorkerInPath::Normal) moduleLabel.erase(0, 1);
00347
00348 bool isTracked;
00349 ParameterSet* modpset = proc_pset.getPSetForUpdate(moduleLabel, isTracked);
00350 if (modpset == 0) {
00351 std::string pathType("endpath");
00352 if (!search_all(end_path_name_list_, name)) {
00353 pathType = std::string("path");
00354 }
00355 throw Exception(errors::Configuration) <<
00356 "The unknown module label \"" << moduleLabel <<
00357 "\" appears in " << pathType << " \"" << name <<
00358 "\"\n please check spelling or remove that label from the path.";
00359 }
00360 assert(isTracked);
00361
00362 WorkerParams params(proc_pset, modpset, preg, processConfiguration, *act_table_);
00363 Worker* worker = worker_reg_.getWorker(params, moduleLabel);
00364 if (ignoreFilters && filterAction != WorkerInPath::Ignore && dynamic_cast<WorkerT<EDFilter>*>(worker)) {
00365
00366
00367 std::vector<std::string> allowed_filters = proc_pset.getUntrackedParameter<vstring>("@filters_on_endpaths");
00368 if (!search_all(allowed_filters, worker->description().moduleName())) {
00369
00370 filterAction = WorkerInPath::Ignore;
00371 LogWarning("FilterOnEndPath")
00372 << "The EDFilter '" << worker->description().moduleName() << "' with module label '" << moduleLabel << "' appears on EndPath '" << name << "'.\n"
00373 << "The return value of the filter will be ignored.\n"
00374 << "To suppress this warning, either remove the filter from the endpath,\n"
00375 << "or explicitly ignore it in the configuration by using cms.ignore().\n";
00376 }
00377 }
00378 WorkerInPath w(worker, filterAction);
00379 tmpworkers.push_back(w);
00380 }
00381
00382 out.swap(tmpworkers);
00383 }
00384
00385 void Schedule::fillTrigPath(ParameterSet& proc_pset,
00386 ProductRegistry& preg,
00387 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00388 int bitpos, std::string const& name, TrigResPtr trptr) {
00389 PathWorkers tmpworkers;
00390 Workers holder;
00391 fillWorkers(proc_pset, preg, processConfiguration, name, false, tmpworkers);
00392
00393 for (PathWorkers::iterator wi(tmpworkers.begin()),
00394 we(tmpworkers.end()); wi != we; ++wi) {
00395 holder.push_back(wi->getWorker());
00396 }
00397
00398
00399 if (!tmpworkers.empty()) {
00400 Path p(bitpos, name, tmpworkers, trptr, *act_table_, actReg_, false);
00401 if (wantSummary_) {
00402 p.useStopwatch();
00403 }
00404 trig_paths_.push_back(p);
00405 }
00406 for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
00407 }
00408
00409 void Schedule::fillEndPath(ParameterSet& proc_pset,
00410 ProductRegistry& preg,
00411 boost::shared_ptr<ProcessConfiguration const> processConfiguration,
00412 int bitpos, std::string const& name) {
00413 PathWorkers tmpworkers;
00414 fillWorkers(proc_pset, preg, processConfiguration, name, true, tmpworkers);
00415 Workers holder;
00416
00417 for (PathWorkers::iterator wi(tmpworkers.begin()), we(tmpworkers.end()); wi != we; ++wi) {
00418 holder.push_back(wi->getWorker());
00419 }
00420
00421 if (!tmpworkers.empty()) {
00422 Path p(bitpos, name, tmpworkers, endpath_results_, *act_table_, actReg_, true);
00423 if (wantSummary_) {
00424 p.useStopwatch();
00425 }
00426 end_paths_.push_back(p);
00427 }
00428 for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
00429 }
00430
00431 void Schedule::endJob(ExceptionCollector & collector) {
00432 bool failure = false;
00433 AllWorkers::iterator ai(workersBegin()), ae(workersEnd());
00434 for (; ai != ae; ++ai) {
00435 try {
00436 try {
00437 (*ai)->endJob();
00438 }
00439 catch (cms::Exception& e) { throw; }
00440 catch (std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00441 catch (std::exception& e) { convertException::stdToEDM(e); }
00442 catch (std::string& s) { convertException::stringToEDM(s); }
00443 catch (char const* c) { convertException::charPtrToEDM(c); }
00444 catch (...) { convertException::unknownToEDM(); }
00445 }
00446 catch (cms::Exception const& ex) {
00447 collector.addException(ex);
00448 failure = true;
00449 }
00450 }
00451 if (failure) {
00452 return;
00453 }
00454
00455 if (wantSummary_ == false) return;
00456
00457 TrigPaths::const_iterator pi, pe;
00458
00459
00460
00461 LogVerbatim("FwkSummary") << "";
00462 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Event Summary ------------";
00463 LogVerbatim("FwkSummary") << "TrigReport"
00464 << " Events total = " << totalEvents()
00465 << " passed = " << totalEventsPassed()
00466 << " failed = " << (totalEventsFailed())
00467 << "";
00468
00469 LogVerbatim("FwkSummary") << "";
00470 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Path Summary ------------";
00471 LogVerbatim("FwkSummary") << "TrigReport "
00472 << std::right << std::setw(10) << "Trig Bit#" << " "
00473 << std::right << std::setw(10) << "Run" << " "
00474 << std::right << std::setw(10) << "Passed" << " "
00475 << std::right << std::setw(10) << "Failed" << " "
00476 << std::right << std::setw(10) << "Error" << " "
00477 << "Name" << "";
00478 pi = trig_paths_.begin();
00479 pe = trig_paths_.end();
00480 for (; pi != pe; ++pi) {
00481 LogVerbatim("FwkSummary") << "TrigReport "
00482 << std::right << std::setw(5) << 1
00483 << std::right << std::setw(5) << pi->bitPosition() << " "
00484 << std::right << std::setw(10) << pi->timesRun() << " "
00485 << std::right << std::setw(10) << pi->timesPassed() << " "
00486 << std::right << std::setw(10) << pi->timesFailed() << " "
00487 << std::right << std::setw(10) << pi->timesExcept() << " "
00488 << pi->name() << "";
00489 }
00490
00491 LogVerbatim("FwkSummary") << "";
00492 LogVerbatim("FwkSummary") << "TrigReport " << "-------End-Path Summary ------------";
00493 LogVerbatim("FwkSummary") << "TrigReport "
00494 << std::right << std::setw(10) << "Trig Bit#" << " "
00495 << std::right << std::setw(10) << "Run" << " "
00496 << std::right << std::setw(10) << "Passed" << " "
00497 << std::right << std::setw(10) << "Failed" << " "
00498 << std::right << std::setw(10) << "Error" << " "
00499 << "Name" << "";
00500 pi = end_paths_.begin();
00501 pe = end_paths_.end();
00502 for (; pi != pe; ++pi) {
00503 LogVerbatim("FwkSummary") << "TrigReport "
00504 << std::right << std::setw(5) << 0
00505 << std::right << std::setw(5) << pi->bitPosition() << " "
00506 << std::right << std::setw(10) << pi->timesRun() << " "
00507 << std::right << std::setw(10) << pi->timesPassed() << " "
00508 << std::right << std::setw(10) << pi->timesFailed() << " "
00509 << std::right << std::setw(10) << pi->timesExcept() << " "
00510 << pi->name() << "";
00511 }
00512
00513 pi = trig_paths_.begin();
00514 pe = trig_paths_.end();
00515 for (; pi != pe; ++pi) {
00516 LogVerbatim("FwkSummary") << "";
00517 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Modules in Path: " << pi->name() << " ------------";
00518 LogVerbatim("FwkSummary") << "TrigReport "
00519 << std::right << std::setw(10) << "Trig Bit#" << " "
00520 << std::right << std::setw(10) << "Visited" << " "
00521 << std::right << std::setw(10) << "Passed" << " "
00522 << std::right << std::setw(10) << "Failed" << " "
00523 << std::right << std::setw(10) << "Error" << " "
00524 << "Name" << "";
00525
00526 for (unsigned int i = 0; i < pi->size(); ++i) {
00527 LogVerbatim("FwkSummary") << "TrigReport "
00528 << std::right << std::setw(5) << 1
00529 << std::right << std::setw(5) << pi->bitPosition() << " "
00530 << std::right << std::setw(10) << pi->timesVisited(i) << " "
00531 << std::right << std::setw(10) << pi->timesPassed(i) << " "
00532 << std::right << std::setw(10) << pi->timesFailed(i) << " "
00533 << std::right << std::setw(10) << pi->timesExcept(i) << " "
00534 << pi->getWorker(i)->description().moduleLabel() << "";
00535 }
00536 }
00537
00538 pi = end_paths_.begin();
00539 pe = end_paths_.end();
00540 for (; pi != pe; ++pi) {
00541 LogVerbatim("FwkSummary") << "";
00542 LogVerbatim("FwkSummary") << "TrigReport " << "------ Modules in End-Path: " << pi->name() << " ------------";
00543 LogVerbatim("FwkSummary") << "TrigReport "
00544 << std::right << std::setw(10) << "Trig Bit#" << " "
00545 << std::right << std::setw(10) << "Visited" << " "
00546 << std::right << std::setw(10) << "Passed" << " "
00547 << std::right << std::setw(10) << "Failed" << " "
00548 << std::right << std::setw(10) << "Error" << " "
00549 << "Name" << "";
00550
00551 for (unsigned int i = 0; i < pi->size(); ++i) {
00552 LogVerbatim("FwkSummary") << "TrigReport "
00553 << std::right << std::setw(5) << 0
00554 << std::right << std::setw(5) << pi->bitPosition() << " "
00555 << std::right << std::setw(10) << pi->timesVisited(i) << " "
00556 << std::right << std::setw(10) << pi->timesPassed(i) << " "
00557 << std::right << std::setw(10) << pi->timesFailed(i) << " "
00558 << std::right << std::setw(10) << pi->timesExcept(i) << " "
00559 << pi->getWorker(i)->description().moduleLabel() << "";
00560 }
00561 }
00562
00563 LogVerbatim("FwkSummary") << "";
00564 LogVerbatim("FwkSummary") << "TrigReport " << "---------- Module Summary ------------";
00565 LogVerbatim("FwkSummary") << "TrigReport "
00566 << std::right << std::setw(10) << "Visited" << " "
00567 << std::right << std::setw(10) << "Run" << " "
00568 << std::right << std::setw(10) << "Passed" << " "
00569 << std::right << std::setw(10) << "Failed" << " "
00570 << std::right << std::setw(10) << "Error" << " "
00571 << "Name" << "";
00572 ai = workersBegin();
00573 ae = workersEnd();
00574 for (; ai != ae; ++ai) {
00575 LogVerbatim("FwkSummary") << "TrigReport "
00576 << std::right << std::setw(10) << (*ai)->timesVisited() << " "
00577 << std::right << std::setw(10) << (*ai)->timesRun() << " "
00578 << std::right << std::setw(10) << (*ai)->timesPassed() << " "
00579 << std::right << std::setw(10) << (*ai)->timesFailed() << " "
00580 << std::right << std::setw(10) << (*ai)->timesExcept() << " "
00581 << (*ai)->description().moduleLabel() << "";
00582
00583 }
00584 LogVerbatim("FwkSummary") << "";
00585
00586
00587
00588 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Event Summary ---[sec]----";
00589 LogVerbatim("FwkSummary") << "TimeReport"
00590 << std::setprecision(6) << std::fixed
00591 << " CPU/event = " << timeCpuReal().first/std::max(1, totalEvents())
00592 << " Real/event = " << timeCpuReal().second/std::max(1, totalEvents())
00593 << "";
00594
00595 LogVerbatim("FwkSummary") << "";
00596 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Path Summary ---[sec]----";
00597 LogVerbatim("FwkSummary") << "TimeReport "
00598 << std::right << std::setw(22) << "per event "
00599 << std::right << std::setw(22) << "per path-run "
00600 << "";
00601 LogVerbatim("FwkSummary") << "TimeReport "
00602 << std::right << std::setw(10) << "CPU" << " "
00603 << std::right << std::setw(10) << "Real" << " "
00604 << std::right << std::setw(10) << "CPU" << " "
00605 << std::right << std::setw(10) << "Real" << " "
00606 << "Name" << "";
00607 pi = trig_paths_.begin();
00608 pe = trig_paths_.end();
00609 for (; pi != pe; ++pi) {
00610 LogVerbatim("FwkSummary") << "TimeReport "
00611 << std::setprecision(6) << std::fixed
00612 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
00613 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
00614 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
00615 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
00616 << pi->name() << "";
00617 }
00618 LogVerbatim("FwkSummary") << "TimeReport "
00619 << std::right << std::setw(10) << "CPU" << " "
00620 << std::right << std::setw(10) << "Real" << " "
00621 << std::right << std::setw(10) << "CPU" << " "
00622 << std::right << std::setw(10) << "Real" << " "
00623 << "Name" << "";
00624 LogVerbatim("FwkSummary") << "TimeReport "
00625 << std::right << std::setw(22) << "per event "
00626 << std::right << std::setw(22) << "per path-run "
00627 << "";
00628
00629 LogVerbatim("FwkSummary") << "";
00630 LogVerbatim("FwkSummary") << "TimeReport " << "-------End-Path Summary ---[sec]----";
00631 LogVerbatim("FwkSummary") << "TimeReport "
00632 << std::right << std::setw(22) << "per event "
00633 << std::right << std::setw(22) << "per endpath-run "
00634 << "";
00635 LogVerbatim("FwkSummary") << "TimeReport "
00636 << std::right << std::setw(10) << "CPU" << " "
00637 << std::right << std::setw(10) << "Real" << " "
00638 << std::right << std::setw(10) << "CPU" << " "
00639 << std::right << std::setw(10) << "Real" << " "
00640 << "Name" << "";
00641 pi = end_paths_.begin();
00642 pe = end_paths_.end();
00643 for (; pi != pe; ++pi) {
00644 LogVerbatim("FwkSummary") << "TimeReport "
00645 << std::setprecision(6) << std::fixed
00646 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
00647 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
00648 << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
00649 << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
00650 << pi->name() << "";
00651 }
00652 LogVerbatim("FwkSummary") << "TimeReport "
00653 << std::right << std::setw(10) << "CPU" << " "
00654 << std::right << std::setw(10) << "Real" << " "
00655 << std::right << std::setw(10) << "CPU" << " "
00656 << std::right << std::setw(10) << "Real" << " "
00657 << "Name" << "";
00658 LogVerbatim("FwkSummary") << "TimeReport "
00659 << std::right << std::setw(22) << "per event "
00660 << std::right << std::setw(22) << "per endpath-run "
00661 << "";
00662
00663 pi = trig_paths_.begin();
00664 pe = trig_paths_.end();
00665 for (; pi != pe; ++pi) {
00666 LogVerbatim("FwkSummary") << "";
00667 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Modules in Path: " << pi->name() << " ---[sec]----";
00668 LogVerbatim("FwkSummary") << "TimeReport "
00669 << std::right << std::setw(22) << "per event "
00670 << std::right << std::setw(22) << "per module-visit "
00671 << "";
00672 LogVerbatim("FwkSummary") << "TimeReport "
00673 << std::right << std::setw(10) << "CPU" << " "
00674 << std::right << std::setw(10) << "Real" << " "
00675 << std::right << std::setw(10) << "CPU" << " "
00676 << std::right << std::setw(10) << "Real" << " "
00677 << "Name" << "";
00678 for (unsigned int i = 0; i < pi->size(); ++i) {
00679 LogVerbatim("FwkSummary") << "TimeReport "
00680 << std::setprecision(6) << std::fixed
00681 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
00682 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
00683 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
00684 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
00685 << pi->getWorker(i)->description().moduleLabel() << "";
00686 }
00687 }
00688 LogVerbatim("FwkSummary") << "TimeReport "
00689 << std::right << std::setw(10) << "CPU" << " "
00690 << std::right << std::setw(10) << "Real" << " "
00691 << std::right << std::setw(10) << "CPU" << " "
00692 << std::right << std::setw(10) << "Real" << " "
00693 << "Name" << "";
00694 LogVerbatim("FwkSummary") << "TimeReport "
00695 << std::right << std::setw(22) << "per event "
00696 << std::right << std::setw(22) << "per module-visit "
00697 << "";
00698
00699 pi = end_paths_.begin();
00700 pe = end_paths_.end();
00701 for (; pi != pe; ++pi) {
00702 LogVerbatim("FwkSummary") << "";
00703 LogVerbatim("FwkSummary") << "TimeReport " << "------ Modules in End-Path: " << pi->name() << " ---[sec]----";
00704 LogVerbatim("FwkSummary") << "TimeReport "
00705 << std::right << std::setw(22) << "per event "
00706 << std::right << std::setw(22) << "per module-visit "
00707 << "";
00708 LogVerbatim("FwkSummary") << "TimeReport "
00709 << std::right << std::setw(10) << "CPU" << " "
00710 << std::right << std::setw(10) << "Real" << " "
00711 << std::right << std::setw(10) << "CPU" << " "
00712 << std::right << std::setw(10) << "Real" << " "
00713 << "Name" << "";
00714 for (unsigned int i = 0; i < pi->size(); ++i) {
00715 LogVerbatim("FwkSummary") << "TimeReport "
00716 << std::setprecision(6) << std::fixed
00717 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
00718 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
00719 << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
00720 << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
00721 << pi->getWorker(i)->description().moduleLabel() << "";
00722 }
00723 }
00724 LogVerbatim("FwkSummary") << "TimeReport "
00725 << std::right << std::setw(10) << "CPU" << " "
00726 << std::right << std::setw(10) << "Real" << " "
00727 << std::right << std::setw(10) << "CPU" << " "
00728 << std::right << std::setw(10) << "Real" << " "
00729 << "Name" << "";
00730 LogVerbatim("FwkSummary") << "TimeReport "
00731 << std::right << std::setw(22) << "per event "
00732 << std::right << std::setw(22) << "per module-visit "
00733 << "";
00734
00735 LogVerbatim("FwkSummary") << "";
00736 LogVerbatim("FwkSummary") << "TimeReport " << "---------- Module Summary ---[sec]----";
00737 LogVerbatim("FwkSummary") << "TimeReport "
00738 << std::right << std::setw(22) << "per event "
00739 << std::right << std::setw(22) << "per module-run "
00740 << std::right << std::setw(22) << "per module-visit "
00741 << "";
00742 LogVerbatim("FwkSummary") << "TimeReport "
00743 << std::right << std::setw(10) << "CPU" << " "
00744 << std::right << std::setw(10) << "Real" << " "
00745 << std::right << std::setw(10) << "CPU" << " "
00746 << std::right << std::setw(10) << "Real" << " "
00747 << std::right << std::setw(10) << "CPU" << " "
00748 << std::right << std::setw(10) << "Real" << " "
00749 << "Name" << "";
00750 ai = workersBegin();
00751 ae = workersEnd();
00752 for (; ai != ae; ++ai) {
00753 LogVerbatim("FwkSummary") << "TimeReport "
00754 << std::setprecision(6) << std::fixed
00755 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, totalEvents()) << " "
00756 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, totalEvents()) << " "
00757 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesRun()) << " "
00758 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesRun()) << " "
00759 << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesVisited()) << " "
00760 << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesVisited()) << " "
00761 << (*ai)->description().moduleLabel() << "";
00762 }
00763 LogVerbatim("FwkSummary") << "TimeReport "
00764 << std::right << std::setw(10) << "CPU" << " "
00765 << std::right << std::setw(10) << "Real" << " "
00766 << std::right << std::setw(10) << "CPU" << " "
00767 << std::right << std::setw(10) << "Real" << " "
00768 << std::right << std::setw(10) << "CPU" << " "
00769 << std::right << std::setw(10) << "Real" << " "
00770 << "Name" << "";
00771 LogVerbatim("FwkSummary") << "TimeReport "
00772 << std::right << std::setw(22) << "per event "
00773 << std::right << std::setw(22) << "per module-run "
00774 << std::right << std::setw(22) << "per module-visit "
00775 << "";
00776
00777 LogVerbatim("FwkSummary") << "";
00778 LogVerbatim("FwkSummary") << "T---Report end!" << "";
00779 LogVerbatim("FwkSummary") << "";
00780 }
00781
00782 void Schedule::closeOutputFiles() {
00783 for_all(all_output_workers_, boost::bind(&OutputWorker::closeFile, _1));
00784 }
00785
00786 void Schedule::openNewOutputFilesIfNeeded() {
00787 for_all(all_output_workers_, boost::bind(&OutputWorker::openNewFileIfNeeded, _1));
00788 }
00789
00790 void Schedule::openOutputFiles(FileBlock& fb) {
00791 for_all(all_output_workers_, boost::bind(&OutputWorker::openFile, _1, boost::cref(fb)));
00792 }
00793
00794 void Schedule::writeRun(RunPrincipal const& rp) {
00795 for_all(all_output_workers_, boost::bind(&OutputWorker::writeRun, _1, boost::cref(rp)));
00796 }
00797
00798 void Schedule::writeLumi(LuminosityBlockPrincipal const& lbp) {
00799 for_all(all_output_workers_, boost::bind(&OutputWorker::writeLumi, _1, boost::cref(lbp)));
00800 }
00801
00802 bool Schedule::shouldWeCloseOutput() const {
00803
00804 return (std::find_if (all_output_workers_.begin(), all_output_workers_.end(),
00805 boost::bind(&OutputWorker::shouldWeCloseFile, _1))
00806 != all_output_workers_.end());
00807 }
00808
00809 void Schedule::respondToOpenInputFile(FileBlock const& fb) {
00810 for_all(all_workers_, boost::bind(&Worker::respondToOpenInputFile, _1, boost::cref(fb)));
00811 }
00812
00813 void Schedule::respondToCloseInputFile(FileBlock const& fb) {
00814 for_all(all_workers_, boost::bind(&Worker::respondToCloseInputFile, _1, boost::cref(fb)));
00815 }
00816
00817 void Schedule::respondToOpenOutputFiles(FileBlock const& fb) {
00818 for_all(all_workers_, boost::bind(&Worker::respondToOpenOutputFiles, _1, boost::cref(fb)));
00819 }
00820
00821 void Schedule::respondToCloseOutputFiles(FileBlock const& fb) {
00822 for_all(all_workers_, boost::bind(&Worker::respondToCloseOutputFiles, _1, boost::cref(fb)));
00823 }
00824
00825 void Schedule::beginJob() {
00826 for_all(all_workers_, boost::bind(&Worker::beginJob, _1));
00827 loadMissingDictionaries();
00828 }
00829
00830 void Schedule::preForkReleaseResources() {
00831 for_all(all_workers_, boost::bind(&Worker::preForkReleaseResources, _1));
00832 }
00833 void Schedule::postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren) {
00834 for_all(all_workers_, boost::bind(&Worker::postForkReacquireResources, _1, iChildIndex, iNumberOfChildren));
00835 }
00836
00837 bool Schedule::changeModule(std::string const& iLabel,
00838 ParameterSet const& iPSet) {
00839 Worker* found = 0;
00840 for (AllWorkers::const_iterator it=all_workers_.begin(), itEnd=all_workers_.end();
00841 it != itEnd; ++it) {
00842 if ((*it)->description().moduleLabel() == iLabel) {
00843 found = *it;
00844 break;
00845 }
00846 }
00847 if (0 == found) {
00848 return false;
00849 }
00850
00851 std::auto_ptr<Maker> wm(MakerPluginFactory::get()->create(found->description().moduleName()));
00852 wm->swapModule(found, iPSet);
00853 found->beginJob();
00854 return true;
00855 }
00856
00857 std::vector<ModuleDescription const*>
00858 Schedule::getAllModuleDescriptions() const {
00859 AllWorkers::const_iterator i(workersBegin());
00860 AllWorkers::const_iterator e(workersEnd());
00861
00862 std::vector<ModuleDescription const*> result;
00863 result.reserve(all_workers_.size());
00864
00865 for (; i != e; ++i) {
00866 ModuleDescription const* p = (*i)->descPtr();
00867 result.push_back(p);
00868 }
00869 return result;
00870 }
00871
00872 void
00873 Schedule::availablePaths(std::vector<std::string>& oLabelsToFill) const {
00874 oLabelsToFill.reserve(trig_paths_.size());
00875 std::transform(trig_paths_.begin(),
00876 trig_paths_.end(),
00877 std::back_inserter(oLabelsToFill),
00878 boost::bind(&Path::name, _1));
00879 }
00880
00881 void
00882 Schedule::modulesInPath(std::string const& iPathLabel,
00883 std::vector<std::string>& oLabelsToFill) const {
00884 TrigPaths::const_iterator itFound =
00885 std::find_if (trig_paths_.begin(),
00886 trig_paths_.end(),
00887 boost::bind(std::equal_to<std::string>(),
00888 iPathLabel,
00889 boost::bind(&Path::name, _1)));
00890 if (itFound!=trig_paths_.end()) {
00891 oLabelsToFill.reserve(itFound->size());
00892 for (size_t i = 0; i < itFound->size(); ++i) {
00893 oLabelsToFill.push_back(itFound->getWorker(i)->description().moduleLabel());
00894 }
00895 }
00896 }
00897
00898 void
00899 Schedule::enableEndPaths(bool active) {
00900 endpathsAreActive_ = active;
00901 }
00902
00903 bool
00904 Schedule::endPathsEnabled() const {
00905 return endpathsAreActive_;
00906 }
00907
00908 void
00909 fillModuleInPathSummary(Path const&, ModuleInPathSummary&) {
00910 }
00911
00912 void
00913 fillModuleInPathSummary(Path const& path,
00914 size_t which,
00915 ModuleInPathSummary& sum) {
00916 sum.timesVisited = path.timesVisited(which);
00917 sum.timesPassed = path.timesPassed(which);
00918 sum.timesFailed = path.timesFailed(which);
00919 sum.timesExcept = path.timesExcept(which);
00920 sum.moduleLabel = path.getWorker(which)->description().moduleLabel();
00921 }
00922
00923 void
00924 fillPathSummary(Path const& path, PathSummary& sum) {
00925 sum.name = path.name();
00926 sum.bitPosition = path.bitPosition();
00927 sum.timesRun = path.timesRun();
00928 sum.timesPassed = path.timesPassed();
00929 sum.timesFailed = path.timesFailed();
00930 sum.timesExcept = path.timesExcept();
00931
00932 Path::size_type sz = path.size();
00933 std::vector<ModuleInPathSummary> temp(sz);
00934 for (size_t i = 0; i != sz; ++i) {
00935 fillModuleInPathSummary(path, i, temp[i]);
00936 }
00937 sum.moduleInPathSummaries.swap(temp);
00938 }
00939
00940 void
00941 fillWorkerSummaryAux(Worker const& w, WorkerSummary& sum) {
00942 sum.timesVisited = w.timesVisited();
00943 sum.timesRun = w.timesRun();
00944 sum.timesPassed = w.timesPassed();
00945 sum.timesFailed = w.timesFailed();
00946 sum.timesExcept = w.timesExcept();
00947 sum.moduleLabel = w.description().moduleLabel();
00948 }
00949
00950 void
00951 fillWorkerSummary(Worker const* pw, WorkerSummary& sum) {
00952 fillWorkerSummaryAux(*pw, sum);
00953 }
00954
00955 void
00956 Schedule::getTriggerReport(TriggerReport& rep) const {
00957 rep.eventSummary.totalEvents = totalEvents();
00958 rep.eventSummary.totalEventsPassed = totalEventsPassed();
00959 rep.eventSummary.totalEventsFailed = totalEventsFailed();
00960
00961 fill_summary(trig_paths_, rep.trigPathSummaries, &fillPathSummary);
00962 fill_summary(end_paths_, rep.endPathSummaries, &fillPathSummary);
00963 fill_summary(all_workers_, rep.workerSummaries, &fillWorkerSummary);
00964 }
00965
00966 void
00967 Schedule::clearCounters() {
00968 total_events_ = total_passed_ = 0;
00969 for_all(trig_paths_, boost::bind(&Path::clearCounters, _1));
00970 for_all(end_paths_, boost::bind(&Path::clearCounters, _1));
00971 for_all(all_workers_, boost::bind(&Worker::clearCounters, _1));
00972 }
00973
00974 void
00975 Schedule::resetAll() {
00976 for_all(all_workers_, boost::bind(&Worker::reset, _1));
00977 results_->reset();
00978 endpath_results_->reset();
00979 }
00980
00981 void
00982 Schedule::addToAllWorkers(Worker* w) {
00983 if (!search_all(all_workers_, w)) {
00984 if (wantSummary_) {
00985 w->useStopwatch();
00986 }
00987 all_workers_.push_back(w);
00988 }
00989 }
00990
00991 void
00992 Schedule::setupOnDemandSystem(EventPrincipal& ep, EventSetup const& es) {
00993
00994 unscheduled_->setEventSetup(es);
00995 ep.setUnscheduledHandler(unscheduled_);
00996 }
00997 }