CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Schedule.cc
Go to the documentation of this file.
2 
25 
26 #include "boost/bind.hpp"
27 #include "boost/ref.hpp"
28 
29 #include <algorithm>
30 #include <cassert>
31 #include <cstdlib>
32 #include <functional>
33 #include <iomanip>
34 #include <list>
35 #include <exception>
36 
37 namespace edm {
38  namespace {
39 
40  // Function template to transform each element in the input range to
41  // a value placed into the output range. The supplied function
42  // should take a const_reference to the 'input', and write to a
43  // reference to the 'output'.
44  template <typename InputIterator, typename ForwardIterator, typename Func>
45  void
46  transform_into(InputIterator begin, InputIterator end,
47  ForwardIterator out, Func func) {
48  for (; begin != end; ++begin, ++out) func(*begin, *out);
49  }
50 
51  // Function template that takes a sequence 'from', a sequence
52  // 'to', and a callable object 'func'. It and applies
53  // transform_into to fill the 'to' sequence with the values
54  // calcuated by the callable object, taking care to fill the
55  // outupt only if all calls succeed.
56  template <typename FROM, typename TO, typename FUNC>
57  void
58  fill_summary(FROM const& from, TO& to, FUNC func) {
59  TO temp(from.size());
60  transform_into(from.begin(), from.end(), temp.begin(), func);
61  to.swap(temp);
62  }
63 
64  // -----------------------------
65 
66  // Here we make the trigger results inserter directly. This should
67  // probably be a utility in the WorkerRegistry or elsewhere.
68 
70  makeInserter(ParameterSet& proc_pset,
71  ProductRegistry& preg,
72  ActionTable const& actions,
73  boost::shared_ptr<ActivityRegistry> areg,
74  boost::shared_ptr<ProcessConfiguration> processConfiguration,
75  Schedule::TrigResPtr trptr) {
76 
77  ParameterSet* trig_pset = proc_pset.getPSetForUpdate("@trigger_paths");
78  trig_pset->registerIt();
79 
80  WorkerParams work_args(proc_pset, trig_pset, preg, processConfiguration, actions);
81  ModuleDescription md(trig_pset->id(),
82  "TriggerResultInserter",
83  "TriggerResults",
84  processConfiguration.get());
85 
86  areg->preModuleConstructionSignal_(md);
87  std::auto_ptr<EDProducer> producer(new TriggerResultInserter(*trig_pset, trptr));
88  areg->postModuleConstructionSignal_(md);
89 
90  Schedule::WorkerPtr ptr(new WorkerT<EDProducer>(producer, md, work_args));
91  ptr->setActivityRegistry(areg);
92  return ptr;
93  }
94 
95  bool binary_search_string(std::vector<std::string> const& v, std::string const& s) {
96  return std::binary_search(v.begin(), v.end(), s);
97  }
98 
99  void
100  initializeBranchToReadingWorker(ParameterSet const& opts,
101  ProductRegistry const& preg,
102  std::multimap<std::string,Worker*>& branchToReadingWorker)
103  {
104  // See if any data has been marked to be deleted early (removing any duplicates)
105  auto vBranchesToDeleteEarly = opts.getUntrackedParameter<std::vector<std::string>>("canDeleteEarly",std::vector<std::string>());
106  if(not vBranchesToDeleteEarly.empty()) {
107  std::sort(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),std::less<std::string>());
108  vBranchesToDeleteEarly.erase(std::unique(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end()),
109  vBranchesToDeleteEarly.end());
110 
111  // Are the requested items in the product registry?
112  auto allBranchNames = preg.allBranchNames();
113  //the branch names all end with a period, which we do not want to compare with
114  for(auto & b:allBranchNames) {
115  b.resize(b.size()-1);
116  }
117  std::sort(allBranchNames.begin(),allBranchNames.end(),std::less<std::string>());
118  std::vector<std::string> temp;
119  temp.reserve(vBranchesToDeleteEarly.size());
120 
121  std::set_intersection(vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),
122  allBranchNames.begin(),allBranchNames.end(),
123  std::back_inserter(temp));
124  vBranchesToDeleteEarly.swap(temp);
125  if(temp.size() != vBranchesToDeleteEarly.size()) {
126  std::vector<std::string> missingProducts;
127  std::set_difference(temp.begin(),temp.end(),
128  vBranchesToDeleteEarly.begin(),vBranchesToDeleteEarly.end(),
129  std::back_inserter(missingProducts));
130  LogInfo l("MissingProductsForCanDeleteEarly");
131  l<<"The following products in the 'canDeleteEarly' list are not available in this job and will be ignored.";
132  for(auto const& n:missingProducts){
133  l<<"\n "<<n;
134  }
135  }
136  //set placeholder for the branch, we will remove the nullptr if a
137  // module actually wants the branch.
138  for(auto const& branch:vBranchesToDeleteEarly) {
139  branchToReadingWorker.insert(make_pair(branch,nullptr));
140  }
141  }
142  }
143  }
144 
145  // -----------------------------
146 
147  typedef std::vector<std::string> vstring;
148 
149  // -----------------------------
150 
153  ProductRegistry& preg,
154  ActionTable const& actions,
155  boost::shared_ptr<ActivityRegistry> areg,
156  boost::shared_ptr<ProcessConfiguration> processConfiguration,
157  const ParameterSet* subProcPSet) :
158  worker_reg_(areg),
159  act_table_(&actions),
160  actReg_(areg),
161  state_(Ready),
162  trig_name_list_(tns.getTrigPaths()),
163  end_path_name_list_(tns.getEndPaths()),
164  results_(new HLTGlobalStatus(trig_name_list_.size())),
165  endpath_results_(), // delay!
166  results_inserter_(),
167  all_workers_(),
168  all_output_workers_(),
169  trig_paths_(),
170  end_paths_(),
171  wantSummary_(tns.wantSummary()),
172  total_events_(),
173  total_passed_(),
174  stopwatch_(wantSummary_? new RunStopwatch::StopwatchPointer::element_type : static_cast<RunStopwatch::StopwatchPointer::element_type*> (0)),
175  unscheduled_(new UnscheduledCallProducer),
176  endpathsAreActive_(true) {
177 
178  ParameterSet const& opts = proc_pset.getUntrackedParameterSet("options", ParameterSet());
179  bool hasPath = false;
180 
181  int trig_bitpos = 0;
182  vstring labelsOnTriggerPaths;
183  for (vstring::const_iterator i = trig_name_list_.begin(),
184  e = trig_name_list_.end();
185  i != e;
186  ++i) {
187  fillTrigPath(proc_pset, preg, processConfiguration, trig_bitpos, *i, results_, &labelsOnTriggerPaths);
188  ++trig_bitpos;
189  hasPath = true;
190  }
191 
192  if (hasPath) {
193  // the results inserter stands alone
194  results_inserter_ = makeInserter(proc_pset,
195  preg,
196  actions, actReg_, processConfiguration, results_);
198  }
199 
201  endpath_results_ = epptr;
202 
203  // fill normal endpaths
204  vstring::iterator eib(end_path_name_list_.begin()), eie(end_path_name_list_.end());
205  for (int bitpos = 0; eib != eie; ++eib, ++bitpos) {
206  fillEndPath(proc_pset, preg, processConfiguration, bitpos, *eib);
207  }
208 
209  //See if all modules were used
210  std::set<std::string> usedWorkerLabels;
211  for (AllWorkers::iterator itWorker = workersBegin();
212  itWorker != workersEnd();
213  ++itWorker) {
214  usedWorkerLabels.insert((*itWorker)->description().moduleLabel());
215  }
216  std::vector<std::string> modulesInConfig(proc_pset.getParameter<std::vector<std::string> >("@all_modules"));
217  std::set<std::string> modulesInConfigSet(modulesInConfig.begin(), modulesInConfig.end());
218  std::vector<std::string> unusedLabels;
219  set_difference(modulesInConfigSet.begin(), modulesInConfigSet.end(),
220  usedWorkerLabels.begin(), usedWorkerLabels.end(),
221  back_inserter(unusedLabels));
222  //does the configuration say we should allow on demand?
223  bool allowUnscheduled = opts.getUntrackedParameter<bool>("allowUnscheduled", false);
224  std::set<std::string> unscheduledLabels;
225  std::vector<std::string> shouldBeUsedLabels;
226  if (!unusedLabels.empty()) {
227  //Need to
228  // 1) create worker
229  // 2) if it is a WorkerT<EDProducer>, add it to our list
230  // 3) hand list to our delayed reader
231 
232  for (std::vector<std::string>::iterator itLabel = unusedLabels.begin(), itLabelEnd = unusedLabels.end();
233  itLabel != itLabelEnd;
234  ++itLabel) {
235  if (allowUnscheduled) {
236  bool isTracked;
237  ParameterSet* modulePSet(proc_pset.getPSetForUpdate(*itLabel, isTracked));
238  assert(isTracked);
239  assert(modulePSet != 0);
240  WorkerParams params(proc_pset, modulePSet, preg,
241  processConfiguration, *act_table_);
242  Worker* newWorker(worker_reg_.getWorker(params, *itLabel));
243  if (dynamic_cast<WorkerT<EDProducer>*>(newWorker) ||
244  dynamic_cast<WorkerT<EDFilter>*>(newWorker)) {
245  unscheduledLabels.insert(*itLabel);
246  unscheduled_->addWorker(newWorker);
247  //add to list so it gets reset each new event
248  addToAllWorkers(newWorker);
249  } else {
250  //not a producer so should be marked as not used
251  shouldBeUsedLabels.push_back(*itLabel);
252  }
253  } else {
254  //everthing is marked are unused so no 'on demand' allowed
255  shouldBeUsedLabels.push_back(*itLabel);
256  }
257  }
258  if (!shouldBeUsedLabels.empty()) {
259  std::ostringstream unusedStream;
260  unusedStream << "'" << shouldBeUsedLabels.front() << "'";
261  for (std::vector<std::string>::iterator itLabel = shouldBeUsedLabels.begin() + 1,
262  itLabelEnd = shouldBeUsedLabels.end();
263  itLabel != itLabelEnd;
264  ++itLabel) {
265  unusedStream << ",'" << *itLabel << "'";
266  }
267  LogInfo("path")
268  << "The following module labels are not assigned to any path:\n"
269  << unusedStream.str()
270  << "\n";
271  }
272  }
273  if (!unscheduledLabels.empty()) {
274  for (ProductRegistry::ProductList::const_iterator it = preg.productList().begin(),
275  itEnd = preg.productList().end();
276  it != itEnd;
277  ++it) {
278  if (it->second.produced() &&
279  it->second.branchType() == InEvent &&
280  unscheduledLabels.end() != unscheduledLabels.find(it->second.moduleLabel())) {
281  it->second.setOnDemand();
282  }
283  }
284  }
285 
286  std::map<std::string, std::vector<std::pair<std::string, int> > > outputModulePathPositions;
287  reduceParameterSet(proc_pset, modulesInConfig, modulesInConfigSet, labelsOnTriggerPaths, shouldBeUsedLabels, outputModulePathPositions);
288 
289  proc_pset.registerIt();
290  pset::Registry::instance()->extra().setID(proc_pset.id());
291  processConfiguration->setParameterSetID(proc_pset.id());
292 
293  initializeEarlyDelete(opts,preg,subProcPSet);
294 
295  // This is used for a little sanity-check to make sure no code
296  // modifications alter the number of workers at a later date.
297  size_t all_workers_count = all_workers_.size();
298 
299  for (AllWorkers::iterator i = all_workers_.begin(), e = all_workers_.end();
300  i != e;
301  ++i) {
302 
303  // All the workers should be in all_workers_ by this point. Thus
304  // we can now fill all_output_workers_.
305  OutputWorker* ow = dynamic_cast<OutputWorker*>(*i);
306  if (ow) {
307  all_output_workers_.push_back(ow);
308  }
309  }
310  // Now that the output workers are filled in, set any output limits.
311  limitOutput(proc_pset);
312 
314  preg.setFrozen();
315 
316  for (AllOutputWorkers::iterator i = all_output_workers_.begin(), e = all_output_workers_.end();
317  i != e; ++i) {
318  (*i)->setEventSelectionInfo(outputModulePathPositions, preg.anyProductProduced());
319  }
320 
321  // Sanity check: make sure nobody has added a worker after we've
322  // already relied on all_workers_ being full.
323  assert (all_workers_count == all_workers_.size());
324 
325  ProcessConfigurationRegistry::instance()->insertMapped(*processConfiguration);
327  fillProductRegistryTransients(*processConfiguration, preg);
328  } // Schedule::Schedule
329 
330 
332  edm::ParameterSet const* subProcPSet) {
333  //for now, if have a subProcess, don't allow early delete
334  // In the future we should use the SubProcess's 'keep list' to decide what can be kept
335  if(subProcPSet) return;
336 
337  //see if 'canDeleteEarly' was set and if so setup the list with those products actually
338  // registered for this job
339  std::multimap<std::string,Worker*> branchToReadingWorker;
340  initializeBranchToReadingWorker(opts,preg,branchToReadingWorker);
341 
342  //If no delete early items have been specified we don't have to do anything
343  if(branchToReadingWorker.size()==0) {
344  return;
345  }
346  const std::vector<std::string> kEmpty;
347  std::map<Worker*,unsigned int> reserveSizeForWorker;
348  unsigned int upperLimitOnReadingWorker =0;
349  unsigned int upperLimitOnIndicies = 0;
350  unsigned int nUniqueBranchesToDelete=branchToReadingWorker.size();
351  for (AllWorkers::iterator i = all_workers_.begin(), e = all_workers_.end();
352  i != e;
353  ++i) {
354  OutputWorker* ow = dynamic_cast<OutputWorker*>(*i);
355  if (ow) {
356  if(branchToReadingWorker.size()>0) {
357  //If an OutputModule needs a product, we can't delete it early
358  // so we should remove it from our list
359  SelectionsArray const&kept = ow->keptProducts();
360  for( auto const& item: kept[InEvent]) {
361  auto found = branchToReadingWorker.equal_range(item->branchName());
362  if(found.first !=found.second) {
363  --nUniqueBranchesToDelete;
364  branchToReadingWorker.erase(found.first,found.second);
365  }
366  }
367  }
368  } else {
369  if(branchToReadingWorker.size()>0) {
370  //determine if this module could read a branch we want to delete early
371  auto pset = pset::Registry::instance()->getMapped((*i)->description().parameterSetID());
372  if(0!=pset) {
373  auto branches = pset->getUntrackedParameter<std::vector<std::string>>("mightGet",kEmpty);
374  if(not branches.empty()) {
375  ++upperLimitOnReadingWorker;
376  }
377  for(auto const& branch:branches){
378  auto found = branchToReadingWorker.equal_range(branch);
379  if(found.first != found.second) {
380  ++upperLimitOnIndicies;
381  ++reserveSizeForWorker[*i];
382  if(nullptr == found.first->second) {
383  found.first->second = *i;
384  } else {
385  branchToReadingWorker.insert(make_pair(found.first->first,*i));
386  }
387  }
388  }
389  }
390  }
391  }
392  }
393  {
394  auto it = branchToReadingWorker.begin();
395  std::vector<std::string> unusedBranches;
396  while(it !=branchToReadingWorker.end()) {
397  if(it->second == nullptr) {
398  unusedBranches.push_back(it->first);
399  //erasing the object invalidates the iterator so must advance it first
400  auto temp = it;
401  ++it;
402  branchToReadingWorker.erase(temp);
403  } else {
404  ++it;
405  }
406  }
407  if(not unusedBranches.empty()) {
408  LogWarning l("UnusedProductsForCanDeleteEarly");
409  l<<"The following products in the 'canDeleteEarly' list are not used in this job and will be ignored.\n"
410  " If possible, remove the producer from the job or add the product to the producer's own 'mightGet' list.";
411  for(auto const& n:unusedBranches){
412  l<<"\n "<<n;
413  }
414  }
415  }
416  if(0!=branchToReadingWorker.size()) {
417  earlyDeleteHelpers_.reserve(upperLimitOnReadingWorker);
418  earlyDeleteHelperToBranchIndicies_.resize(upperLimitOnIndicies,0);
419  earlyDeleteBranchToCount_.reserve(nUniqueBranchesToDelete);
420  std::map<const Worker*,EarlyDeleteHelper*> alreadySeenWorkers;
421  std::string lastBranchName;
422  size_t nextOpenIndex = 0;
423  unsigned int* beginAddress = &(earlyDeleteHelperToBranchIndicies_.front());
424  for(auto& branchAndWorker:branchToReadingWorker) {
425  if(lastBranchName != branchAndWorker.first) {
426  //have to put back the period we removed earlier in order to get the proper name
427  BranchID bid(branchAndWorker.first+".");
428  earlyDeleteBranchToCount_.emplace_back(std::make_pair(bid,0U));
429  lastBranchName = branchAndWorker.first;
430  }
431  auto found = alreadySeenWorkers.find(branchAndWorker.second);
432  if(alreadySeenWorkers.end() == found) {
433  //NOTE: we will set aside enough space in earlyDeleteHelperToBranchIndicies_ to accommodate
434  // all the branches that might be read by this worker. However, initially we will only tell the
435  // EarlyDeleteHelper about the first one. As additional branches are added via 'appendIndex' the
436  // EarlyDeleteHelper will automatically advance its internal end pointer.
437  size_t index = nextOpenIndex;
438  size_t nIndices = reserveSizeForWorker[branchAndWorker.second];
440  earlyDeleteHelpers_.emplace_back(EarlyDeleteHelper(beginAddress+index,
441  beginAddress+index+1,
443  branchAndWorker.second->setEarlyDeleteHelper(&(earlyDeleteHelpers_.back()));
444  alreadySeenWorkers.insert(std::make_pair(branchAndWorker.second,&(earlyDeleteHelpers_.back())));
445  nextOpenIndex +=nIndices;
446  } else {
447  found->second->appendIndex(earlyDeleteBranchToCount_.size()-1);
448  }
449  }
450 
451  //Now we can compactify the earlyDeleteHelperToBranchIndicies_ since we may have over estimated the
452  // space needed for each module
453  auto itLast = earlyDeleteHelpers_.begin();
454  for(auto it = earlyDeleteHelpers_.begin()+1;it != earlyDeleteHelpers_.end();++it) {
455  if(itLast->end() != it->begin()) {
456  //figure the offset for next Worker since it hasn't been moved yet so it has the original address
457  unsigned int delta = it->begin()- itLast->end();
458  it->shiftIndexPointers(delta);
459 
461  (itLast->end()-beginAddress),
463  (it->begin()-beginAddress));
464  }
465  itLast = it;
466  }
467  earlyDeleteHelperToBranchIndicies_.erase(earlyDeleteHelperToBranchIndicies_.begin()+(itLast->end()-beginAddress),
469 
470  //now tell the paths about the deleters
471  for(auto& p : trig_paths_) {
472  p.setEarlyDeleteHelpers(alreadySeenWorkers);
473  }
474  for(auto& p : end_paths_) {
475  p.setEarlyDeleteHelpers(alreadySeenWorkers);
476  }
478  }
479  }
480 
482  vstring& modulesInConfig,
483  std::set<std::string> const& modulesInConfigSet,
484  vstring& labelsOnTriggerPaths,
485  vstring& shouldBeUsedLabels,
486  std::map<std::string, std::vector<std::pair<std::string, int> > >& outputModulePathPositions) {
487 
488  // Before calculating the ParameterSetID of the top level ParameterSet or
489  // saving it in the registry drop from the top level ParameterSet all
490  // OutputModules and EDAnalyzers not on trigger paths. If unscheduled
491  // production is not enabled also drop all the EDFilters and EDProducers
492  // that are not scheduled. Drop the ParameterSet used to configure the module
493  // itself. Also drop the other traces of these labels in the top level
494  // ParameterSet: Remove that labels from @all_modules and from all the
495  // end paths. If this makes any end paths empty, then remove the end path
496  // name from @end_paths, and @paths.
497 
498  // First make a list of labels to drop
499  vstring labelsToBeDropped;
500  vstring outputModuleLabels;
501  std::string edmType;
502  std::string const moduleEdmType("@module_edm_type");
503  std::string const outputModule("OutputModule");
504  std::string const edAnalyzer("EDAnalyzer");
505  std::string const edFilter("EDFilter");
506  std::string const edProducer("EDProducer");
507  sort_all(labelsOnTriggerPaths);
508  vstring::const_iterator iLabelsOnTriggerPaths = labelsOnTriggerPaths.begin();
509  vstring::const_iterator endLabelsOnTriggerPaths = labelsOnTriggerPaths.end();
510  sort_all(shouldBeUsedLabels);
511  vstring::const_iterator iShouldBeUsedLabels = shouldBeUsedLabels.begin();
512  vstring::const_iterator endShouldBeUsedLabels = shouldBeUsedLabels.end();
513 
514  for (std::set<std::string>::const_iterator i = modulesInConfigSet.begin(),
515  e = modulesInConfigSet.end(); i != e; ++i) {
516  edmType = proc_pset.getParameterSet(*i).getParameter<std::string>(moduleEdmType);
517  if (edmType == outputModule) {
518  labelsToBeDropped.push_back(*i);
519  outputModuleLabels.push_back(*i);
520  }
521  else if (edmType == edAnalyzer) {
522  while (iLabelsOnTriggerPaths != endLabelsOnTriggerPaths &&
523  *iLabelsOnTriggerPaths < *i) {
524  ++iLabelsOnTriggerPaths;
525  }
526  if (iLabelsOnTriggerPaths == endLabelsOnTriggerPaths ||
527  *iLabelsOnTriggerPaths != *i) {
528  labelsToBeDropped.push_back(*i);
529  }
530  }
531  else if (edmType == edFilter || edmType == edProducer) {
532  while (iShouldBeUsedLabels != endShouldBeUsedLabels &&
533  *iShouldBeUsedLabels < *i) {
534  ++iShouldBeUsedLabels;
535  }
536  if (iShouldBeUsedLabels != endShouldBeUsedLabels &&
537  *iShouldBeUsedLabels == *i) {
538  labelsToBeDropped.push_back(*i);
539  }
540  }
541  }
542 
543  // drop the parameter sets used to configure the modules
544  for_all(labelsToBeDropped, boost::bind(&ParameterSet::eraseOrSetUntrackedParameterSet, boost::ref(proc_pset), _1));
545 
546  // drop the labels from @all_modules
547  vstring::iterator endAfterRemove = std::remove_if(modulesInConfig.begin(), modulesInConfig.end(), boost::bind(binary_search_string, boost::ref(labelsToBeDropped), _1));
548  modulesInConfig.erase(endAfterRemove, modulesInConfig.end());
549  proc_pset.addParameter<vstring>(std::string("@all_modules"), modulesInConfig);
550 
551  // drop the labels from all end paths
552  vstring endPathsToBeDropped;
553  vstring labels;
554  for (vstring::iterator iEndPath = end_path_name_list_.begin(), endEndPath = end_path_name_list_.end();
555  iEndPath != endEndPath;
556  ++iEndPath) {
557  labels = proc_pset.getParameter<vstring>(*iEndPath);
558  vstring::iterator iSave = labels.begin();
559  vstring::iterator iBegin = labels.begin();
560 
561  for (vstring::iterator iLabel = labels.begin(), iEnd = labels.end();
562  iLabel != iEnd; ++iLabel) {
563  if (binary_search_string(labelsToBeDropped, *iLabel)) {
564  if (binary_search_string(outputModuleLabels, *iLabel)) {
565  outputModulePathPositions[*iLabel].push_back(std::pair<std::string, int>(*iEndPath, iSave - iBegin));
566  }
567  } else {
568  if (iSave != iLabel) {
569  iSave->swap(*iLabel);
570  }
571  ++iSave;
572  }
573  }
574  labels.erase(iSave, labels.end());
575  if (labels.empty()) {
576  // remove empty end paths and save their names
577  proc_pset.eraseSimpleParameter(*iEndPath);
578  endPathsToBeDropped.push_back(*iEndPath);
579  } else {
580  proc_pset.addParameter<vstring>(*iEndPath, labels);
581  }
582  }
583  sort_all(endPathsToBeDropped);
584 
585  // remove empty end paths from @paths
586  vstring scheduledPaths = proc_pset.getParameter<vstring>("@paths");
587  endAfterRemove = std::remove_if(scheduledPaths.begin(), scheduledPaths.end(), boost::bind(binary_search_string, boost::ref(endPathsToBeDropped), _1));
588  scheduledPaths.erase(endAfterRemove, scheduledPaths.end());
589  proc_pset.addParameter<vstring>(std::string("@paths"), scheduledPaths);
590 
591  // remove empty end paths from @end_paths
592  vstring scheduledEndPaths = proc_pset.getParameter<vstring>("@end_paths");
593  endAfterRemove = std::remove_if(scheduledEndPaths.begin(), scheduledEndPaths.end(), boost::bind(binary_search_string, boost::ref(endPathsToBeDropped), _1));
594  scheduledEndPaths.erase(endAfterRemove, scheduledEndPaths.end());
595  proc_pset.addParameter<vstring>(std::string("@end_paths"), scheduledEndPaths);
596  }
597 
598  void
600  std::string const output("output");
601 
602  ParameterSet const& maxEventsPSet = proc_pset.getUntrackedParameterSet("maxEvents", ParameterSet());
603  int maxEventSpecs = 0;
604  int maxEventsOut = -1;
605  ParameterSet const* vMaxEventsOut = 0;
606  std::vector<std::string> intNamesE = maxEventsPSet.getParameterNamesForType<int>(false);
607  if (search_all(intNamesE, output)) {
608  maxEventsOut = maxEventsPSet.getUntrackedParameter<int>(output);
609  ++maxEventSpecs;
610  }
611  std::vector<std::string> psetNamesE;
612  maxEventsPSet.getParameterSetNames(psetNamesE, false);
613  if (search_all(psetNamesE, output)) {
614  vMaxEventsOut = &maxEventsPSet.getUntrackedParameterSet(output);
615  ++maxEventSpecs;
616  }
617 
618  if (maxEventSpecs > 1) {
620  "\nAt most, one form of 'output' may appear in the 'maxEvents' parameter set";
621  }
622 
623  if (maxEventSpecs == 0) {
624  return;
625  }
626 
627  for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(), itEnd = all_output_workers_.end();
628  it != itEnd; ++it) {
629  OutputModuleDescription desc(maxEventsOut);
630  if (vMaxEventsOut != 0 && !vMaxEventsOut->empty()) {
631  std::string moduleLabel = (*it)->description().moduleLabel();
632  try {
633  desc.maxEvents_ = vMaxEventsOut->getUntrackedParameter<int>(moduleLabel);
634  } catch (Exception const&) {
636  "\nNo entry in 'maxEvents' for output module label '" << moduleLabel << "'.\n";
637  }
638  }
639  (*it)->configure(desc);
640  }
641  }
642 
643  bool Schedule::terminate() const {
644  if (all_output_workers_.empty()) {
645  return false;
646  }
647  for (AllOutputWorkers::const_iterator it = all_output_workers_.begin(),
648  itEnd = all_output_workers_.end();
649  it != itEnd; ++it) {
650  if (!(*it)->limitReached()) {
651  // Found an output module that has not reached output event count.
652  return false;
653  }
654  }
655  LogInfo("SuccessfulTermination")
656  << "The job is terminating successfully because each output module\n"
657  << "has reached its configured limit.\n";
658  return true;
659  }
660 
662  ProductRegistry& preg,
663  boost::shared_ptr<ProcessConfiguration const> processConfiguration,
664  std::string const& name,
665  bool ignoreFilters,
666  PathWorkers& out,
667  vstring* labelsOnPaths) {
668  vstring modnames = proc_pset.getParameter<vstring>(name);
669  vstring::iterator it(modnames.begin()), ie(modnames.end());
670  PathWorkers tmpworkers;
671 
672  for (; it != ie; ++it) {
673 
674  if (labelsOnPaths) labelsOnPaths->push_back(*it);
675 
677  if ((*it)[0] == '!') filterAction = WorkerInPath::Veto;
678  else if ((*it)[0] == '-') filterAction = WorkerInPath::Ignore;
679 
680  std::string moduleLabel = *it;
681  if (filterAction != WorkerInPath::Normal) moduleLabel.erase(0, 1);
682 
683  bool isTracked;
684  ParameterSet* modpset = proc_pset.getPSetForUpdate(moduleLabel, isTracked);
685  if (modpset == 0) {
686  std::string pathType("endpath");
687  if (!search_all(end_path_name_list_, name)) {
688  pathType = std::string("path");
689  }
691  "The unknown module label \"" << moduleLabel <<
692  "\" appears in " << pathType << " \"" << name <<
693  "\"\n please check spelling or remove that label from the path.";
694  }
695  assert(isTracked);
696 
697  WorkerParams params(proc_pset, modpset, preg, processConfiguration, *act_table_);
698  Worker* worker = worker_reg_.getWorker(params, moduleLabel);
699  if (ignoreFilters && filterAction != WorkerInPath::Ignore && dynamic_cast<WorkerT<EDFilter>*>(worker)) {
700  // We have a filter on an end path, and the filter is not explicitly ignored.
701  // See if the filter is allowed.
702  std::vector<std::string> allowed_filters = proc_pset.getUntrackedParameter<vstring>("@filters_on_endpaths");
703  if (!search_all(allowed_filters, worker->description().moduleName())) {
704  // Filter is not allowed. Ignore the result, and issue a warning.
705  filterAction = WorkerInPath::Ignore;
706  LogWarning("FilterOnEndPath")
707  << "The EDFilter '" << worker->description().moduleName() << "' with module label '" << moduleLabel << "' appears on EndPath '" << name << "'.\n"
708  << "The return value of the filter will be ignored.\n"
709  << "To suppress this warning, either remove the filter from the endpath,\n"
710  << "or explicitly ignore it in the configuration by using cms.ignore().\n";
711  }
712  }
713  WorkerInPath w(worker, filterAction);
714  tmpworkers.push_back(w);
715  }
716 
717  out.swap(tmpworkers);
718  }
719 
721  ProductRegistry& preg,
722  boost::shared_ptr<ProcessConfiguration const> processConfiguration,
723  int bitpos, std::string const& name, TrigResPtr trptr,
724  vstring* labelsOnTriggerPaths) {
725  PathWorkers tmpworkers;
726  Workers holder;
727  fillWorkers(proc_pset, preg, processConfiguration, name, false, tmpworkers, labelsOnTriggerPaths);
728 
729  for (PathWorkers::iterator wi(tmpworkers.begin()),
730  we(tmpworkers.end()); wi != we; ++wi) {
731  holder.push_back(wi->getWorker());
732  }
733 
734  // an empty path will cause an extra bit that is not used
735  if (!tmpworkers.empty()) {
736  Path p(bitpos, name, tmpworkers, trptr, *act_table_, actReg_, false);
737  if (wantSummary_) {
738  p.useStopwatch();
739  }
740  trig_paths_.push_back(p);
741  }
742  for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
743  }
744 
746  ProductRegistry& preg,
747  boost::shared_ptr<ProcessConfiguration const> processConfiguration,
748  int bitpos, std::string const& name) {
749  PathWorkers tmpworkers;
750  fillWorkers(proc_pset, preg, processConfiguration, name, true, tmpworkers, 0);
751  Workers holder;
752 
753  for (PathWorkers::iterator wi(tmpworkers.begin()), we(tmpworkers.end()); wi != we; ++wi) {
754  holder.push_back(wi->getWorker());
755  }
756 
757  if (!tmpworkers.empty()) {
758  Path p(bitpos, name, tmpworkers, endpath_results_, *act_table_, actReg_, true);
759  if (wantSummary_) {
760  p.useStopwatch();
761  }
762  end_paths_.push_back(p);
763  }
764  for_all(holder, boost::bind(&Schedule::addToAllWorkers, this, _1));
765  }
766 
768  bool failure = false;
769  AllWorkers::iterator ai(workersBegin()), ae(workersEnd());
770  for (; ai != ae; ++ai) {
771  try {
772  try {
773  (*ai)->endJob();
774  }
775  catch (cms::Exception& e) { throw; }
776  catch (std::bad_alloc& bda) { convertException::badAllocToEDM(); }
777  catch (std::exception& e) { convertException::stdToEDM(e); }
778  catch (std::string& s) { convertException::stringToEDM(s); }
779  catch (char const* c) { convertException::charPtrToEDM(c); }
780  catch (...) { convertException::unknownToEDM(); }
781  }
782  catch (cms::Exception const& ex) {
783  collector.addException(ex);
784  failure = true;
785  }
786  }
787  if (failure) {
788  return;
789  }
790 
791  if (wantSummary_ == false) return;
792 
793  TrigPaths::const_iterator pi, pe;
794 
795  // The trigger report (pass/fail etc.):
796 
797  LogVerbatim("FwkSummary") << "";
798  LogVerbatim("FwkSummary") << "TrigReport " << "---------- Event Summary ------------";
799  LogVerbatim("FwkSummary") << "TrigReport"
800  << " Events total = " << totalEvents()
801  << " passed = " << totalEventsPassed()
802  << " failed = " << (totalEventsFailed())
803  << "";
804 
805  LogVerbatim("FwkSummary") << "";
806  LogVerbatim("FwkSummary") << "TrigReport " << "---------- Path Summary ------------";
807  LogVerbatim("FwkSummary") << "TrigReport "
808  << std::right << std::setw(10) << "Trig Bit#" << " "
809  << std::right << std::setw(10) << "Run" << " "
810  << std::right << std::setw(10) << "Passed" << " "
811  << std::right << std::setw(10) << "Failed" << " "
812  << std::right << std::setw(10) << "Error" << " "
813  << "Name" << "";
814  pi = trig_paths_.begin();
815  pe = trig_paths_.end();
816  for (; pi != pe; ++pi) {
817  LogVerbatim("FwkSummary") << "TrigReport "
818  << std::right << std::setw(5) << 1
819  << std::right << std::setw(5) << pi->bitPosition() << " "
820  << std::right << std::setw(10) << pi->timesRun() << " "
821  << std::right << std::setw(10) << pi->timesPassed() << " "
822  << std::right << std::setw(10) << pi->timesFailed() << " "
823  << std::right << std::setw(10) << pi->timesExcept() << " "
824  << pi->name() << "";
825  }
826 
827  LogVerbatim("FwkSummary") << "";
828  LogVerbatim("FwkSummary") << "TrigReport " << "-------End-Path Summary ------------";
829  LogVerbatim("FwkSummary") << "TrigReport "
830  << std::right << std::setw(10) << "Trig Bit#" << " "
831  << std::right << std::setw(10) << "Run" << " "
832  << std::right << std::setw(10) << "Passed" << " "
833  << std::right << std::setw(10) << "Failed" << " "
834  << std::right << std::setw(10) << "Error" << " "
835  << "Name" << "";
836  pi = end_paths_.begin();
837  pe = end_paths_.end();
838  for (; pi != pe; ++pi) {
839  LogVerbatim("FwkSummary") << "TrigReport "
840  << std::right << std::setw(5) << 0
841  << std::right << std::setw(5) << pi->bitPosition() << " "
842  << std::right << std::setw(10) << pi->timesRun() << " "
843  << std::right << std::setw(10) << pi->timesPassed() << " "
844  << std::right << std::setw(10) << pi->timesFailed() << " "
845  << std::right << std::setw(10) << pi->timesExcept() << " "
846  << pi->name() << "";
847  }
848 
849  pi = trig_paths_.begin();
850  pe = trig_paths_.end();
851  for (; pi != pe; ++pi) {
852  LogVerbatim("FwkSummary") << "";
853  LogVerbatim("FwkSummary") << "TrigReport " << "---------- Modules in Path: " << pi->name() << " ------------";
854  LogVerbatim("FwkSummary") << "TrigReport "
855  << std::right << std::setw(10) << "Trig Bit#" << " "
856  << std::right << std::setw(10) << "Visited" << " "
857  << std::right << std::setw(10) << "Passed" << " "
858  << std::right << std::setw(10) << "Failed" << " "
859  << std::right << std::setw(10) << "Error" << " "
860  << "Name" << "";
861 
862  for (unsigned int i = 0; i < pi->size(); ++i) {
863  LogVerbatim("FwkSummary") << "TrigReport "
864  << std::right << std::setw(5) << 1
865  << std::right << std::setw(5) << pi->bitPosition() << " "
866  << std::right << std::setw(10) << pi->timesVisited(i) << " "
867  << std::right << std::setw(10) << pi->timesPassed(i) << " "
868  << std::right << std::setw(10) << pi->timesFailed(i) << " "
869  << std::right << std::setw(10) << pi->timesExcept(i) << " "
870  << pi->getWorker(i)->description().moduleLabel() << "";
871  }
872  }
873 
874  pi = end_paths_.begin();
875  pe = end_paths_.end();
876  for (; pi != pe; ++pi) {
877  LogVerbatim("FwkSummary") << "";
878  LogVerbatim("FwkSummary") << "TrigReport " << "------ Modules in End-Path: " << pi->name() << " ------------";
879  LogVerbatim("FwkSummary") << "TrigReport "
880  << std::right << std::setw(10) << "Trig Bit#" << " "
881  << std::right << std::setw(10) << "Visited" << " "
882  << std::right << std::setw(10) << "Passed" << " "
883  << std::right << std::setw(10) << "Failed" << " "
884  << std::right << std::setw(10) << "Error" << " "
885  << "Name" << "";
886 
887  for (unsigned int i = 0; i < pi->size(); ++i) {
888  LogVerbatim("FwkSummary") << "TrigReport "
889  << std::right << std::setw(5) << 0
890  << std::right << std::setw(5) << pi->bitPosition() << " "
891  << std::right << std::setw(10) << pi->timesVisited(i) << " "
892  << std::right << std::setw(10) << pi->timesPassed(i) << " "
893  << std::right << std::setw(10) << pi->timesFailed(i) << " "
894  << std::right << std::setw(10) << pi->timesExcept(i) << " "
895  << pi->getWorker(i)->description().moduleLabel() << "";
896  }
897  }
898 
899  LogVerbatim("FwkSummary") << "";
900  LogVerbatim("FwkSummary") << "TrigReport " << "---------- Module Summary ------------";
901  LogVerbatim("FwkSummary") << "TrigReport "
902  << std::right << std::setw(10) << "Visited" << " "
903  << std::right << std::setw(10) << "Run" << " "
904  << std::right << std::setw(10) << "Passed" << " "
905  << std::right << std::setw(10) << "Failed" << " "
906  << std::right << std::setw(10) << "Error" << " "
907  << "Name" << "";
908  ai = workersBegin();
909  ae = workersEnd();
910  for (; ai != ae; ++ai) {
911  LogVerbatim("FwkSummary") << "TrigReport "
912  << std::right << std::setw(10) << (*ai)->timesVisited() << " "
913  << std::right << std::setw(10) << (*ai)->timesRun() << " "
914  << std::right << std::setw(10) << (*ai)->timesPassed() << " "
915  << std::right << std::setw(10) << (*ai)->timesFailed() << " "
916  << std::right << std::setw(10) << (*ai)->timesExcept() << " "
917  << (*ai)->description().moduleLabel() << "";
918 
919  }
920  LogVerbatim("FwkSummary") << "";
921 
922  // The timing report (CPU and Real Time):
923 
924  LogVerbatim("FwkSummary") << "TimeReport " << "---------- Event Summary ---[sec]----";
925  LogVerbatim("FwkSummary") << "TimeReport"
926  << std::setprecision(6) << std::fixed
927  << " CPU/event = " << timeCpuReal().first/std::max(1, totalEvents())
928  << " Real/event = " << timeCpuReal().second/std::max(1, totalEvents())
929  << "";
930 
931  LogVerbatim("FwkSummary") << "";
932  LogVerbatim("FwkSummary") << "TimeReport " << "---------- Path Summary ---[sec]----";
933  LogVerbatim("FwkSummary") << "TimeReport "
934  << std::right << std::setw(22) << "per event "
935  << std::right << std::setw(22) << "per path-run "
936  << "";
937  LogVerbatim("FwkSummary") << "TimeReport "
938  << std::right << std::setw(10) << "CPU" << " "
939  << std::right << std::setw(10) << "Real" << " "
940  << std::right << std::setw(10) << "CPU" << " "
941  << std::right << std::setw(10) << "Real" << " "
942  << "Name" << "";
943  pi = trig_paths_.begin();
944  pe = trig_paths_.end();
945  for (; pi != pe; ++pi) {
946  LogVerbatim("FwkSummary") << "TimeReport "
947  << std::setprecision(6) << std::fixed
948  << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
949  << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
950  << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
951  << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
952  << pi->name() << "";
953  }
954  LogVerbatim("FwkSummary") << "TimeReport "
955  << std::right << std::setw(10) << "CPU" << " "
956  << std::right << std::setw(10) << "Real" << " "
957  << std::right << std::setw(10) << "CPU" << " "
958  << std::right << std::setw(10) << "Real" << " "
959  << "Name" << "";
960  LogVerbatim("FwkSummary") << "TimeReport "
961  << std::right << std::setw(22) << "per event "
962  << std::right << std::setw(22) << "per path-run "
963  << "";
964 
965  LogVerbatim("FwkSummary") << "";
966  LogVerbatim("FwkSummary") << "TimeReport " << "-------End-Path Summary ---[sec]----";
967  LogVerbatim("FwkSummary") << "TimeReport "
968  << std::right << std::setw(22) << "per event "
969  << std::right << std::setw(22) << "per endpath-run "
970  << "";
971  LogVerbatim("FwkSummary") << "TimeReport "
972  << std::right << std::setw(10) << "CPU" << " "
973  << std::right << std::setw(10) << "Real" << " "
974  << std::right << std::setw(10) << "CPU" << " "
975  << std::right << std::setw(10) << "Real" << " "
976  << "Name" << "";
977  pi = end_paths_.begin();
978  pe = end_paths_.end();
979  for (; pi != pe; ++pi) {
980  LogVerbatim("FwkSummary") << "TimeReport "
981  << std::setprecision(6) << std::fixed
982  << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, totalEvents()) << " "
983  << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, totalEvents()) << " "
984  << std::right << std::setw(10) << pi->timeCpuReal().first/std::max(1, pi->timesRun()) << " "
985  << std::right << std::setw(10) << pi->timeCpuReal().second/std::max(1, pi->timesRun()) << " "
986  << pi->name() << "";
987  }
988  LogVerbatim("FwkSummary") << "TimeReport "
989  << std::right << std::setw(10) << "CPU" << " "
990  << std::right << std::setw(10) << "Real" << " "
991  << std::right << std::setw(10) << "CPU" << " "
992  << std::right << std::setw(10) << "Real" << " "
993  << "Name" << "";
994  LogVerbatim("FwkSummary") << "TimeReport "
995  << std::right << std::setw(22) << "per event "
996  << std::right << std::setw(22) << "per endpath-run "
997  << "";
998 
999  pi = trig_paths_.begin();
1000  pe = trig_paths_.end();
1001  for (; pi != pe; ++pi) {
1002  LogVerbatim("FwkSummary") << "";
1003  LogVerbatim("FwkSummary") << "TimeReport " << "---------- Modules in Path: " << pi->name() << " ---[sec]----";
1004  LogVerbatim("FwkSummary") << "TimeReport "
1005  << std::right << std::setw(22) << "per event "
1006  << std::right << std::setw(22) << "per module-visit "
1007  << "";
1008  LogVerbatim("FwkSummary") << "TimeReport "
1009  << std::right << std::setw(10) << "CPU" << " "
1010  << std::right << std::setw(10) << "Real" << " "
1011  << std::right << std::setw(10) << "CPU" << " "
1012  << std::right << std::setw(10) << "Real" << " "
1013  << "Name" << "";
1014  for (unsigned int i = 0; i < pi->size(); ++i) {
1015  LogVerbatim("FwkSummary") << "TimeReport "
1016  << std::setprecision(6) << std::fixed
1017  << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
1018  << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
1019  << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
1020  << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
1021  << pi->getWorker(i)->description().moduleLabel() << "";
1022  }
1023  }
1024  LogVerbatim("FwkSummary") << "TimeReport "
1025  << std::right << std::setw(10) << "CPU" << " "
1026  << std::right << std::setw(10) << "Real" << " "
1027  << std::right << std::setw(10) << "CPU" << " "
1028  << std::right << std::setw(10) << "Real" << " "
1029  << "Name" << "";
1030  LogVerbatim("FwkSummary") << "TimeReport "
1031  << std::right << std::setw(22) << "per event "
1032  << std::right << std::setw(22) << "per module-visit "
1033  << "";
1034 
1035  pi = end_paths_.begin();
1036  pe = end_paths_.end();
1037  for (; pi != pe; ++pi) {
1038  LogVerbatim("FwkSummary") << "";
1039  LogVerbatim("FwkSummary") << "TimeReport " << "------ Modules in End-Path: " << pi->name() << " ---[sec]----";
1040  LogVerbatim("FwkSummary") << "TimeReport "
1041  << std::right << std::setw(22) << "per event "
1042  << std::right << std::setw(22) << "per module-visit "
1043  << "";
1044  LogVerbatim("FwkSummary") << "TimeReport "
1045  << std::right << std::setw(10) << "CPU" << " "
1046  << std::right << std::setw(10) << "Real" << " "
1047  << std::right << std::setw(10) << "CPU" << " "
1048  << std::right << std::setw(10) << "Real" << " "
1049  << "Name" << "";
1050  for (unsigned int i = 0; i < pi->size(); ++i) {
1051  LogVerbatim("FwkSummary") << "TimeReport "
1052  << std::setprecision(6) << std::fixed
1053  << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, totalEvents()) << " "
1054  << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, totalEvents()) << " "
1055  << std::right << std::setw(10) << pi->timeCpuReal(i).first/std::max(1, pi->timesVisited(i)) << " "
1056  << std::right << std::setw(10) << pi->timeCpuReal(i).second/std::max(1, pi->timesVisited(i)) << " "
1057  << pi->getWorker(i)->description().moduleLabel() << "";
1058  }
1059  }
1060  LogVerbatim("FwkSummary") << "TimeReport "
1061  << std::right << std::setw(10) << "CPU" << " "
1062  << std::right << std::setw(10) << "Real" << " "
1063  << std::right << std::setw(10) << "CPU" << " "
1064  << std::right << std::setw(10) << "Real" << " "
1065  << "Name" << "";
1066  LogVerbatim("FwkSummary") << "TimeReport "
1067  << std::right << std::setw(22) << "per event "
1068  << std::right << std::setw(22) << "per module-visit "
1069  << "";
1070 
1071  LogVerbatim("FwkSummary") << "";
1072  LogVerbatim("FwkSummary") << "TimeReport " << "---------- Module Summary ---[sec]----";
1073  LogVerbatim("FwkSummary") << "TimeReport "
1074  << std::right << std::setw(22) << "per event "
1075  << std::right << std::setw(22) << "per module-run "
1076  << std::right << std::setw(22) << "per module-visit "
1077  << "";
1078  LogVerbatim("FwkSummary") << "TimeReport "
1079  << std::right << std::setw(10) << "CPU" << " "
1080  << std::right << std::setw(10) << "Real" << " "
1081  << std::right << std::setw(10) << "CPU" << " "
1082  << std::right << std::setw(10) << "Real" << " "
1083  << std::right << std::setw(10) << "CPU" << " "
1084  << std::right << std::setw(10) << "Real" << " "
1085  << "Name" << "";
1086  ai = workersBegin();
1087  ae = workersEnd();
1088  for (; ai != ae; ++ai) {
1089  LogVerbatim("FwkSummary") << "TimeReport "
1090  << std::setprecision(6) << std::fixed
1091  << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, totalEvents()) << " "
1092  << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, totalEvents()) << " "
1093  << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesRun()) << " "
1094  << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesRun()) << " "
1095  << std::right << std::setw(10) << (*ai)->timeCpuReal().first/std::max(1, (*ai)->timesVisited()) << " "
1096  << std::right << std::setw(10) << (*ai)->timeCpuReal().second/std::max(1, (*ai)->timesVisited()) << " "
1097  << (*ai)->description().moduleLabel() << "";
1098  }
1099  LogVerbatim("FwkSummary") << "TimeReport "
1100  << std::right << std::setw(10) << "CPU" << " "
1101  << std::right << std::setw(10) << "Real" << " "
1102  << std::right << std::setw(10) << "CPU" << " "
1103  << std::right << std::setw(10) << "Real" << " "
1104  << std::right << std::setw(10) << "CPU" << " "
1105  << std::right << std::setw(10) << "Real" << " "
1106  << "Name" << "";
1107  LogVerbatim("FwkSummary") << "TimeReport "
1108  << std::right << std::setw(22) << "per event "
1109  << std::right << std::setw(22) << "per module-run "
1110  << std::right << std::setw(22) << "per module-visit "
1111  << "";
1112 
1113  LogVerbatim("FwkSummary") << "";
1114  LogVerbatim("FwkSummary") << "T---Report end!" << "";
1115  LogVerbatim("FwkSummary") << "";
1116  }
1117 
1120  }
1121 
1124  }
1125 
1127  for_all(all_output_workers_, boost::bind(&OutputWorker::openFile, _1, boost::cref(fb)));
1128  }
1129 
1131  for_all(all_output_workers_, boost::bind(&OutputWorker::writeRun, _1, boost::cref(rp)));
1132  }
1133 
1135  for_all(all_output_workers_, boost::bind(&OutputWorker::writeLumi, _1, boost::cref(lbp)));
1136  }
1137 
1139  // Return true iff at least one output module returns true.
1140  return (std::find_if (all_output_workers_.begin(), all_output_workers_.end(),
1141  boost::bind(&OutputWorker::shouldWeCloseFile, _1))
1142  != all_output_workers_.end());
1143  }
1144 
1146  for_all(all_workers_, boost::bind(&Worker::respondToOpenInputFile, _1, boost::cref(fb)));
1147  }
1148 
1150  for_all(all_workers_, boost::bind(&Worker::respondToCloseInputFile, _1, boost::cref(fb)));
1151  }
1152 
1154  for_all(all_workers_, boost::bind(&Worker::respondToOpenOutputFiles, _1, boost::cref(fb)));
1155  }
1156 
1158  for_all(all_workers_, boost::bind(&Worker::respondToCloseOutputFiles, _1, boost::cref(fb)));
1159  }
1160 
1162  for_all(all_workers_, boost::bind(&Worker::beginJob, _1));
1164  }
1165 
1168  }
1169  void Schedule::postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren) {
1170  for_all(all_workers_, boost::bind(&Worker::postForkReacquireResources, _1, iChildIndex, iNumberOfChildren));
1171  }
1172 
1173  bool Schedule::changeModule(std::string const& iLabel,
1174  ParameterSet const& iPSet) {
1175  Worker* found = 0;
1176  for (AllWorkers::const_iterator it=all_workers_.begin(), itEnd=all_workers_.end();
1177  it != itEnd; ++it) {
1178  if ((*it)->description().moduleLabel() == iLabel) {
1179  found = *it;
1180  break;
1181  }
1182  }
1183  if (0 == found) {
1184  return false;
1185  }
1186 
1187  std::auto_ptr<Maker> wm(MakerPluginFactory::get()->create(found->description().moduleName()));
1188  wm->swapModule(found, iPSet);
1189  found->beginJob();
1190  return true;
1191  }
1192 
1193  std::vector<ModuleDescription const*>
1195  AllWorkers::const_iterator i(workersBegin());
1196  AllWorkers::const_iterator e(workersEnd());
1197 
1198  std::vector<ModuleDescription const*> result;
1199  result.reserve(all_workers_.size());
1200 
1201  for (; i != e; ++i) {
1202  ModuleDescription const* p = (*i)->descPtr();
1203  result.push_back(p);
1204  }
1205  return result;
1206  }
1207 
1208  void
1209  Schedule::availablePaths(std::vector<std::string>& oLabelsToFill) const {
1210  oLabelsToFill.reserve(trig_paths_.size());
1211  std::transform(trig_paths_.begin(),
1212  trig_paths_.end(),
1213  std::back_inserter(oLabelsToFill),
1214  boost::bind(&Path::name, _1));
1215  }
1216 
1217  void
1218  Schedule::modulesInPath(std::string const& iPathLabel,
1219  std::vector<std::string>& oLabelsToFill) const {
1220  TrigPaths::const_iterator itFound =
1221  std::find_if (trig_paths_.begin(),
1222  trig_paths_.end(),
1223  boost::bind(std::equal_to<std::string>(),
1224  iPathLabel,
1225  boost::bind(&Path::name, _1)));
1226  if (itFound!=trig_paths_.end()) {
1227  oLabelsToFill.reserve(itFound->size());
1228  for (size_t i = 0; i < itFound->size(); ++i) {
1229  oLabelsToFill.push_back(itFound->getWorker(i)->description().moduleLabel());
1230  }
1231  }
1232  }
1233 
1234  void
1236  endpathsAreActive_ = active;
1237  }
1238 
1239  bool
1241  return endpathsAreActive_;
1242  }
1243 
1244  void
1246  }
1247 
1248  void
1250  size_t which,
1251  ModuleInPathSummary& sum) {
1252  sum.timesVisited = path.timesVisited(which);
1253  sum.timesPassed = path.timesPassed(which);
1254  sum.timesFailed = path.timesFailed(which);
1255  sum.timesExcept = path.timesExcept(which);
1256  sum.moduleLabel = path.getWorker(which)->description().moduleLabel();
1257  }
1258 
1259  void
1261  sum.name = path.name();
1262  sum.bitPosition = path.bitPosition();
1263  sum.timesRun = path.timesRun();
1264  sum.timesPassed = path.timesPassed();
1265  sum.timesFailed = path.timesFailed();
1266  sum.timesExcept = path.timesExcept();
1267 
1268  Path::size_type sz = path.size();
1269  std::vector<ModuleInPathSummary> temp(sz);
1270  for (size_t i = 0; i != sz; ++i) {
1271  fillModuleInPathSummary(path, i, temp[i]);
1272  }
1273  sum.moduleInPathSummaries.swap(temp);
1274  }
1275 
1276  void
1278  sum.timesVisited = w.timesVisited();
1279  sum.timesRun = w.timesRun();
1280  sum.timesPassed = w.timesPassed();
1281  sum.timesFailed = w.timesFailed();
1282  sum.timesExcept = w.timesExcept();
1283  sum.moduleLabel = w.description().moduleLabel();
1284  }
1285 
1286  void
1288  fillWorkerSummaryAux(*pw, sum);
1289  }
1290 
1291  void
1296 
1297  fill_summary(trig_paths_, rep.trigPathSummaries, &fillPathSummary);
1298  fill_summary(end_paths_, rep.endPathSummaries, &fillPathSummary);
1299  fill_summary(all_workers_, rep.workerSummaries, &fillWorkerSummary);
1300  }
1301 
1302  void
1305  for_all(trig_paths_, boost::bind(&Path::clearCounters, _1));
1306  for_all(end_paths_, boost::bind(&Path::clearCounters, _1));
1307  for_all(all_workers_, boost::bind(&Worker::clearCounters, _1));
1308  }
1309 
1310  void
1312  for_all(all_workers_, boost::bind(&Worker::reset, _1));
1313  results_->reset();
1314  endpath_results_->reset();
1315  }
1316 
1317  void
1319  if (!search_all(all_workers_, w)) {
1320  if (wantSummary_) {
1321  w->useStopwatch();
1322  }
1323  all_workers_.push_back(w);
1324  }
1325  }
1326 
1327  void
1329  // NOTE: who owns the productdescrption? Just copied by value
1330  unscheduled_->setEventSetup(es);
1332  }
1333 
1334  void
1336  //must be sure we have cleared the count first
1337  for(auto& count:earlyDeleteBranchToCount_) {
1338  count.second = 0;
1339  }
1340  //now reset based on how many helpers use that branch
1342  ++(earlyDeleteBranchToCount_[index].second);
1343  }
1344  for(auto& helper: earlyDeleteHelpers_) {
1345  helper.reset();
1346  }
1347  }
1348 
1349 }
dbl * delta
Definition: mlp_gen.cc:36
T getParameter(std::string const &) const
bool empty() const
Definition: ParameterSet.h:219
std::vector< PathSummary > endPathSummaries
Definition: TriggerReport.h:65
void initializeEarlyDelete(edm::ParameterSet const &opts, edm::ProductRegistry const &preg, edm::ParameterSet const *subProcPSet)
Definition: Schedule.cc:331
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
void addException(cms::Exception const &exception)
int timesRun() const
Definition: Path.h:73
std::pair< double, double > timeCpuReal() const
Definition: Schedule.h:167
void fillWorkerSummary(Worker const *pw, WorkerSummary &sum)
Definition: Schedule.cc:1287
int bitPosition() const
Definition: Path.h:57
ModuleDescription const & description() const
Definition: Worker.h:73
roAction_t actions[nactions]
Definition: GenABIO.cc:200
void availablePaths(std::vector< std::string > &oLabelsToFill) const
adds to oLabelsToFill the labels for all paths in the process
Definition: Schedule.cc:1209
void fillWorkerSummaryAux(Worker const &w, WorkerSummary &sum)
Definition: Schedule.cc:1277
void limitOutput(ParameterSet const &proc_pset)
Definition: Schedule.cc:599
AllOutputWorkers all_output_workers_
Definition: Schedule.h:303
WorkerPtr results_inserter_
Definition: Schedule.h:301
bool endPathsEnabled() const
Definition: Schedule.cc:1240
void respondToCloseInputFile(FileBlock const &fb)
Definition: Schedule.cc:1149
void resetEarlyDelete()
Definition: Schedule.cc:1335
std::vector< std::string > vstring
Definition: Schedule.cc:147
bool changeModule(std::string const &iLabel, ParameterSet const &iPSet)
Definition: Schedule.cc:1173
void writeLumi(LuminosityBlockPrincipal const &lbp)
Definition: Schedule.cc:1134
std::vector< EarlyDeleteHelper > earlyDeleteHelpers_
Definition: Schedule.h:320
WorkerRegistry worker_reg_
Definition: Schedule.h:290
ParameterSetID id() const
WorkersInPath::size_type size_type
Definition: Path.h:44
int timesPassed() const
Definition: Worker.h:93
std::vector< WorkerInPath > PathWorkers
Definition: Schedule.h:114
TrigPaths trig_paths_
Definition: Schedule.h:304
void respondToOpenOutputFiles(FileBlock const &fb)
Definition: Worker.h:62
void enableEndPaths(bool active)
Definition: Schedule.cc:1235
void clearCounters()
Definition: Worker.h:85
std::string const & moduleName() const
static ThreadSafeRegistry * instance()
TrigResPtr endpath_results_
Definition: Schedule.h:299
int timesExcept() const
Definition: Path.h:76
size_type size() const
Definition: Path.h:80
std::vector< WorkerSummary > workerSummaries
Definition: TriggerReport.h:66
int total_passed_
Definition: Schedule.h:324
std::string const & moduleLabel() const
boost::shared_ptr< HLTGlobalStatus > TrigResPtr
Definition: Schedule.h:107
bool shouldWeCloseFile() const
Definition: OutputWorker.cc:27
void fillProductRegistryTransients(std::vector< ProcessConfiguration > const &pcVec, ProductRegistry const &preg, bool okToRegister=false)
void writeLumi(LuminosityBlockPrincipal const &lbp)
Definition: OutputWorker.cc:47
int totalEventsFailed() const
Definition: Schedule.h:201
void resetAll()
Definition: Schedule.cc:1311
void fillEndPath(ParameterSet &proc_pset, ProductRegistry &preg, boost::shared_ptr< ProcessConfiguration const > processConfiguration, int bitpos, std::string const &name)
Definition: Schedule.cc:745
const Double_t pi
void eraseOrSetUntrackedParameterSet(std::string const &name)
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:16
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:195
std::string moduleLabel
Definition: TriggerReport.h:57
void openFile(FileBlock const &fb)
Definition: OutputWorker.cc:37
ProductList const & productList() const
int totalEventsPassed() const
Definition: Schedule.h:195
int timesExcept() const
Definition: Worker.h:95
list path
Definition: scaleCards.py:51
bool getMapped(key_type const &k, value_type &result) const
std::vector< PathSummary > trigPathSummaries
Definition: TriggerReport.h:64
void reset()
Definition: Worker.h:68
EventSummary eventSummary
Definition: TriggerReport.h:63
const T & max(const T &a, const T &b)
int timesVisited() const
Definition: Worker.h:92
ParameterSet const & getUntrackedParameterSet(std::string const &name, ParameterSet const &defaultValue) const
void reduceParameterSet(ParameterSet &proc_pset, vstring &modulesInConfig, std::set< std::string > const &modulesInConfigSet, vstring &labelsOnTriggerPaths, vstring &shouldBeUsedLabels, std::map< std::string, std::vector< std::pair< std::string, int > > > &outputModulePathPositions)
Definition: Schedule.cc:481
boost::array< Selections, NumBranchTypes > SelectionsArray
Definition: Selections.h:12
int totalEvents() const
Definition: Schedule.h:189
SelectionsArray const & keptProducts() const
Definition: OutputWorker.cc:57
std::string name
Definition: TriggerReport.h:45
void stdToEDM(std::exception const &e)
Definition: Path.h:39
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:145
void clearCounters()
Clear all the counters in the trigger report.
Definition: Schedule.cc:1303
tuple result
Definition: query.py:137
void useStopwatch()
Definition: Worker.cc:116
int timesPassed() const
Definition: Path.h:74
int timesRun() const
Definition: Worker.h:91
void respondToCloseOutputFiles(FileBlock const &fb)
Definition: Schedule.cc:1157
std::vector< std::string > vstring
Definition: Schedule.h:104
#define end
Definition: vmac.h:38
bool terminate() const
Return whether each output module has reached its maximum count.
Definition: Schedule.cc:643
void eraseSimpleParameter(std::string const &name)
void respondToOpenInputFile(FileBlock const &fb)
Definition: Schedule.cc:1145
vstring trig_name_list_
Definition: Schedule.h:295
ActionTable const * act_table_
Definition: Schedule.h:291
std::vector< Worker * > Workers
Definition: Schedule.h:112
AllWorkers::const_iterator workersBegin() const
Definition: Schedule.h:229
void postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren)
Definition: Worker.h:66
void getTriggerReport(TriggerReport &rep) const
Definition: Schedule.cc:1292
void setFrozen(bool initializeLookupInfo=true) const
tuple out
Definition: dbtoconf.py:99
Schedule(ParameterSet &proc_pset, service::TriggerNamesService &tns, ProductRegistry &pregistry, ActionTable const &actions, boost::shared_ptr< ActivityRegistry > areg, boost::shared_ptr< ProcessConfiguration > processConfiguration, const ParameterSet *subProcPSet)
Definition: Schedule.cc:151
static std::string from(" from ")
boost::shared_ptr< Worker > WorkerPtr
Definition: Schedule.h:108
void respondToOpenOutputFiles(FileBlock const &fb)
Definition: Schedule.cc:1153
void respondToCloseOutputFiles(FileBlock const &fb)
Definition: Worker.h:63
void charPtrToEDM(char const *c)
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:120
void stringToEDM(std::string &s)
ParameterSet const & getParameterSet(std::string const &) const
volatile bool endpathsAreActive_
Definition: Schedule.h:329
void respondToOpenInputFile(FileBlock const &fb)
Definition: Worker.h:60
TrigResPtr results_
Definition: Schedule.h:298
void useStopwatch()
Definition: Path.cc:149
bool search_all(ForwardSequence const &s, Datum const &d)
Definition: Algorithms.h:46
void fillModuleInPathSummary(Path const &, ModuleInPathSummary &)
Definition: Schedule.cc:1245
int timesVisited(size_type i) const
Definition: Path.h:81
double b
Definition: hdecay.h:120
int total_events_
Definition: Schedule.h:323
void loadMissingDictionaries()
Definition: ReflexTools.cc:231
void modulesInPath(std::string const &iPathLabel, std::vector< std::string > &oLabelsToFill) const
adds to oLabelsToFill in execution order the labels of all modules in path iPathLabel ...
Definition: Schedule.cc:1218
int timesFailed() const
Definition: Worker.h:94
TrigPaths end_paths_
Definition: Schedule.h:305
bool anyProductProduced() const
void respondToCloseInputFile(FileBlock const &fb)
Definition: Worker.h:61
void fillPathSummary(Path const &path, PathSummary &sum)
Definition: Schedule.cc:1260
void preForkReleaseResources()
Definition: Worker.h:65
bool wantSummary_
Definition: Schedule.h:322
std::string const & name() const
Definition: Path.h:58
#define begin
Definition: vmac.h:31
void postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren)
Definition: Schedule.cc:1169
static void updateRegistries(ProductRegistry const &reg)
author Stefano ARGIRO author Bill Tanenbaum
std::vector< unsigned int > earlyDeleteHelperToBranchIndicies_
Definition: Schedule.h:317
std::vector< ModuleDescription const * > getAllModuleDescriptions() const
Definition: Schedule.cc:1194
Worker const * getWorker(size_type i) const
Definition: Path.h:85
void fillTrigPath(ParameterSet &proc_pset, ProductRegistry &preg, boost::shared_ptr< ProcessConfiguration const > processConfiguration, int bitpos, std::string const &name, TrigResPtr, vstring *labelsOnTriggerPaths)
Definition: Schedule.cc:720
void beginJob()
Definition: Worker.cc:72
Worker * getWorker(WorkerParams const &p, std::string const &moduleLabel)
Retrieve the particular instance of the worker.
void openNewFileIfNeeded()
Definition: OutputWorker.cc:32
void setUnscheduledHandler(boost::shared_ptr< UnscheduledHandler > iHandler)
std::vector< ModuleInPathSummary > moduleInPathSummaries
Definition: TriggerReport.h:46
void openNewOutputFilesIfNeeded()
Definition: Schedule.cc:1122
size_t getParameterSetNames(std::vector< std::string > &output, bool trackiness=true) const
void preForkReleaseResources()
Definition: Schedule.cc:1166
void openOutputFiles(FileBlock &fb)
Definition: Schedule.cc:1126
void writeRun(RunPrincipal const &rp)
Definition: Schedule.cc:1130
bool insertMapped(value_type const &v)
std::vector< std::pair< BranchID, unsigned int > > earlyDeleteBranchToCount_
Definition: Schedule.h:310
void endJob(ExceptionCollector &collector)
Definition: Schedule.cc:767
ParameterSet const & registerIt()
bool shouldWeCloseOutput() const
Definition: Schedule.cc:1138
void setupOnDemandSystem(EventPrincipal &principal, EventSetup const &es)
Definition: Schedule.cc:1328
void beginJob()
Definition: Schedule.cc:1161
SurfaceDeformation * create(int type, const std::vector< double > &params)
tuple size
Write out results.
mathSSE::Vec4< T > v
void writeRun(RunPrincipal const &rp)
Definition: OutputWorker.cc:42
void fillWorkers(ParameterSet &proc_pset, ProductRegistry &preg, boost::shared_ptr< ProcessConfiguration const > processConfiguration, std::string const &name, bool ignoreFilters, PathWorkers &out, vstring *labelsOnPaths)
Definition: Schedule.cc:661
T get(const Candidate &c)
Definition: component.h:56
vstring end_path_name_list_
Definition: Schedule.h:296
void closeOutputFiles()
Definition: Schedule.cc:1118
void clearCounters()
Definition: Path.cc:143
T w() const
AllWorkers::const_iterator workersEnd() const
Definition: Schedule.h:233
int timesFailed() const
Definition: Path.h:75
void addToAllWorkers(Worker *w)
Definition: Schedule.cc:1318
boost::shared_ptr< ActivityRegistry > actReg_
Definition: Schedule.h:292
ParameterSet * getPSetForUpdate(std::string const &name, bool &isTracked)
AllWorkers all_workers_
Definition: Schedule.h:302
boost::shared_ptr< UnscheduledCallProducer > unscheduled_
Definition: Schedule.h:327