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