CMS 3D CMS Logo

StallMonitor.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Services
4 // Class : StallMonitor
5 //
6 // Implementation:
7 //
8 // Original Author: Kyle Knoepfel
9 //
10 
27 
28 #include "tbb/concurrent_unordered_map.h"
29 
30 #include <atomic>
31 #include <chrono>
32 #include <iomanip>
33 #include <iostream>
34 #include <sstream>
35 
36 namespace {
37 
38  using duration_t = std::chrono::microseconds;
39  using clock_t = std::chrono::steady_clock;
40  auto now = clock_t::now;
41 
42  inline auto stream_id(edm::StreamContext const& cs) { return cs.streamID().value(); }
43 
44  inline auto module_id(edm::ModuleCallingContext const& mcc) { return mcc.moduleDescription()->id(); }
45 
46  //===============================================================
47  class StallStatistics {
48  public:
49  // c'tor receiving 'std::string const&' type not provided since we
50  // must be able to call (e.g.) std::vector<StallStatistics>(20),
51  // for which a default label is not sensible in this context.
52  StallStatistics() = default;
53 
54  std::string const& label() const { return label_; }
55  unsigned numberOfStalls() const { return stallCounter_; }
56 
57  using rep_t = duration_t::rep;
58 
59  duration_t totalStalledTime() const { return duration_t{totalTime_.load()}; }
60  duration_t maxStalledTime() const { return duration_t{maxTime_.load()}; }
61 
62  // Modifiers
63  void setLabel(std::string const& label) { label_ = label; }
64 
65  void update(duration_t const ms) {
66  ++stallCounter_;
67  auto const thisTime = ms.count();
68  totalTime_ += thisTime;
69  rep_t max{maxTime_};
70  while (thisTime > max && !maxTime_.compare_exchange_strong(max, thisTime))
71  ;
72  }
73 
74  private:
75  std::string label_{};
76  std::atomic<unsigned> stallCounter_{};
77  std::atomic<rep_t> totalTime_{};
78  std::atomic<rep_t> maxTime_{};
79  };
80 
81  //===============================================================
82  // Message-assembly utilities
83  template <typename T>
84  std::enable_if_t<std::is_integral<T>::value> concatenate(std::ostream& os, T const t) {
85  os << ' ' << t;
86  }
87 
88  template <typename H, typename... T>
89  std::enable_if_t<std::is_integral<H>::value> concatenate(std::ostream& os, H const h, T const... t) {
90  os << ' ' << h;
91  concatenate(os, t...);
92  }
93 
94  enum class step : char {
95  preSourceEvent = 'S',
96  postSourceEvent = 's',
97  preEvent = 'E',
98  postModuleEventPrefetching = 'p',
99  preModuleEventAcquire = 'A',
100  postModuleEventAcquire = 'a',
101  preModuleEvent = 'M',
102  preEventReadFromSource = 'R',
103  postEventReadFromSource = 'r',
104  postModuleEvent = 'm',
105  postEvent = 'e'
106  };
107 
108  enum class Phase : short {
109  globalEndRun = -4,
110  streamEndRun = -3,
111  globalEndLumi = -2,
112  streamEndLumi = -1,
113  Event = 0,
114  streamBeginLumi = 1,
115  globalBeginLumi = 2,
116  streamBeginRun = 3,
117  globalBeginRun = 4
118  };
119 
120  std::ostream& operator<<(std::ostream& os, step const s) {
121  os << static_cast<std::underlying_type_t<step>>(s);
122  return os;
123  }
124 
125  std::ostream& operator<<(std::ostream& os, Phase const s) {
126  os << static_cast<std::underlying_type_t<Phase>>(s);
127  return os;
128  }
129 
130  template <step S, typename... ARGS>
131  std::string assembleMessage(ARGS const... args) {
132  std::ostringstream oss;
133  oss << S;
134  concatenate(oss, args...);
135  oss << '\n';
136  return oss.str();
137  }
138 
139  Phase toTransitionImpl(edm::StreamContext const& iContext) {
140  using namespace edm;
141  switch (iContext.transition()) {
142  case StreamContext::Transition::kBeginRun:
143  return Phase::streamBeginRun;
144  case StreamContext::Transition::kBeginLuminosityBlock:
145  return Phase::streamBeginLumi;
146  case StreamContext::Transition::kEvent:
147  return Phase::Event;
148  case StreamContext::Transition::kEndLuminosityBlock:
149  return Phase::streamEndLumi;
150  case StreamContext::Transition::kEndRun:
151  return Phase::streamEndRun;
152  default:
153  break;
154  }
155  assert(false);
156  return Phase::Event;
157  }
158 
159  auto toTransition(edm::StreamContext const& iContext) -> std::underlying_type_t<Phase> {
160  return static_cast<std::underlying_type_t<Phase>>(toTransitionImpl(iContext));
161  }
162 
163  Phase toTransitionImpl(edm::GlobalContext const& iContext) {
164  using namespace edm;
165  switch (iContext.transition()) {
166  case GlobalContext::Transition::kBeginRun:
167  return Phase::globalBeginRun;
168  case GlobalContext::Transition::kBeginLuminosityBlock:
169  return Phase::globalBeginLumi;
170  case GlobalContext::Transition::kEndLuminosityBlock:
171  return Phase::globalEndLumi;
172  case GlobalContext::Transition::kWriteLuminosityBlock:
173  return Phase::globalEndLumi;
174  case GlobalContext::Transition::kEndRun:
175  return Phase::globalEndRun;
176  case GlobalContext::Transition::kWriteRun:
177  return Phase::globalEndRun;
178  default:
179  break;
180  }
181  assert(false);
182  return Phase::Event;
183  }
184  auto toTransition(edm::GlobalContext const& iContext) -> std::underlying_type_t<Phase> {
185  return static_cast<std::underlying_type_t<Phase>>(toTransitionImpl(iContext));
186  }
187 
188 } // namespace
189 
190 namespace edm {
191  namespace service {
192 
193  class StallMonitor {
194  public:
196  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
197 
198  private:
199  void preModuleConstruction(edm::ModuleDescription const&);
200  void postBeginJob();
201  void preSourceEvent(StreamID);
202  void postSourceEvent(StreamID);
203  void preEvent(StreamContext const&);
204  void preModuleEventAcquire(StreamContext const&, ModuleCallingContext const&);
205  void postModuleEventAcquire(StreamContext const&, ModuleCallingContext const&);
206  void preModuleEvent(StreamContext const&, ModuleCallingContext const&);
207  void postModuleEventPrefetching(StreamContext const&, ModuleCallingContext const&);
208  void preEventReadFromSource(StreamContext const&, ModuleCallingContext const&);
209  void postEventReadFromSource(StreamContext const&, ModuleCallingContext const&);
210  void postModuleEvent(StreamContext const&, ModuleCallingContext const&);
211  void postEvent(StreamContext const&);
212  void preModuleStreamTransition(StreamContext const&, ModuleCallingContext const&);
213  void postModuleStreamTransition(StreamContext const&, ModuleCallingContext const&);
214  void preModuleGlobalTransition(GlobalContext const&, ModuleCallingContext const&);
215  void postModuleGlobalTransition(GlobalContext const&, ModuleCallingContext const&);
216  void postEndJob();
217 
219  bool const validFile_; // Separate data member from file to improve efficiency.
220  duration_t const stallThreshold_;
221  decltype(now()) beginTime_{};
222 
223  // There can be multiple modules per stream. Therefore, we need
224  // the combination of StreamID and ModuleID to correctly track
225  // stalling information. We use tbb::concurrent_unordered_map
226  // for this purpose.
227  using StreamID_value = decltype(std::declval<StreamID>().value());
228  using ModuleID = decltype(std::declval<ModuleDescription>().id());
229  tbb::concurrent_unordered_map<std::pair<StreamID_value, ModuleID>, std::pair<decltype(beginTime_), bool>>
230  stallStart_{};
231 
232  std::vector<std::string> moduleLabels_{};
233  std::vector<StallStatistics> moduleStats_{};
234  unsigned int numStreams_;
235  };
236 
237  } // namespace service
238 
239 } // namespace edm
240 
241 namespace {
242  constexpr char const* filename_default{""};
243  constexpr double threshold_default{0.1}; //default threashold in seconds
244  std::string const space{" "};
245 } // namespace
246 
248 using namespace std::chrono;
249 
250 StallMonitor::StallMonitor(ParameterSet const& iPS, ActivityRegistry& iRegistry)
251  : file_{iPS.getUntrackedParameter<std::string>("fileName", filename_default)},
252  validFile_{file_},
253  stallThreshold_{
254  std::chrono::round<duration_t>(duration<double>(iPS.getUntrackedParameter<double>("stallThreshold")))} {
255  iRegistry.watchPreModuleConstruction(this, &StallMonitor::preModuleConstruction);
256  iRegistry.watchPostBeginJob(this, &StallMonitor::postBeginJob);
257  iRegistry.watchPostModuleEventPrefetching(this, &StallMonitor::postModuleEventPrefetching);
258  iRegistry.watchPreModuleEventAcquire(this, &StallMonitor::preModuleEventAcquire);
259  iRegistry.watchPreModuleEvent(this, &StallMonitor::preModuleEvent);
260  iRegistry.watchPostEndJob(this, &StallMonitor::postEndJob);
261 
262  if (validFile_) {
263  // Only enable the following callbacks if writing to a file.
264  iRegistry.watchPreSourceEvent(this, &StallMonitor::preSourceEvent);
265  iRegistry.watchPostSourceEvent(this, &StallMonitor::postSourceEvent);
266  iRegistry.watchPreEvent(this, &StallMonitor::preEvent);
267  iRegistry.watchPostModuleEventAcquire(this, &StallMonitor::postModuleEventAcquire);
268  iRegistry.watchPreEventReadFromSource(this, &StallMonitor::preEventReadFromSource);
269  iRegistry.watchPostEventReadFromSource(this, &StallMonitor::postEventReadFromSource);
270  iRegistry.watchPostModuleEvent(this, &StallMonitor::postModuleEvent);
271  iRegistry.watchPostEvent(this, &StallMonitor::postEvent);
272 
273  iRegistry.watchPreModuleStreamBeginRun(this, &StallMonitor::preModuleStreamTransition);
274  iRegistry.watchPostModuleStreamBeginRun(this, &StallMonitor::postModuleStreamTransition);
275  iRegistry.watchPreModuleStreamEndRun(this, &StallMonitor::preModuleStreamTransition);
276  iRegistry.watchPostModuleStreamEndRun(this, &StallMonitor::postModuleStreamTransition);
277 
278  iRegistry.watchPreModuleStreamBeginLumi(this, &StallMonitor::preModuleStreamTransition);
279  iRegistry.watchPostModuleStreamBeginLumi(this, &StallMonitor::postModuleStreamTransition);
280  iRegistry.watchPreModuleStreamEndLumi(this, &StallMonitor::preModuleStreamTransition);
281  iRegistry.watchPostModuleStreamEndLumi(this, &StallMonitor::postModuleStreamTransition);
282 
283  iRegistry.watchPreModuleGlobalBeginRun(this, &StallMonitor::preModuleGlobalTransition);
284  iRegistry.watchPostModuleGlobalBeginRun(this, &StallMonitor::postModuleGlobalTransition);
285  iRegistry.watchPreModuleGlobalEndRun(this, &StallMonitor::preModuleGlobalTransition);
286  iRegistry.watchPostModuleGlobalEndRun(this, &StallMonitor::postModuleGlobalTransition);
287  iRegistry.watchPreModuleWriteRun(this, &StallMonitor::preModuleGlobalTransition);
288  iRegistry.watchPostModuleWriteRun(this, &StallMonitor::postModuleGlobalTransition);
289 
290  iRegistry.watchPreModuleGlobalBeginLumi(this, &StallMonitor::preModuleGlobalTransition);
291  iRegistry.watchPostModuleGlobalBeginLumi(this, &StallMonitor::postModuleGlobalTransition);
292  iRegistry.watchPreModuleGlobalEndLumi(this, &StallMonitor::preModuleGlobalTransition);
293  iRegistry.watchPostModuleGlobalEndLumi(this, &StallMonitor::postModuleGlobalTransition);
294  iRegistry.watchPreModuleWriteLumi(this, &StallMonitor::preModuleGlobalTransition);
295  iRegistry.watchPostModuleWriteLumi(this, &StallMonitor::postModuleGlobalTransition);
296 
297  iRegistry.preallocateSignal_.connect(
298  [this](service::SystemBounds const& iBounds) { numStreams_ = iBounds.maxNumberOfStreams(); });
299 
300  std::ostringstream oss;
301  oss << "# Transition Symbol\n";
302  oss << "#----------------- ------\n";
303  oss << "# globalBeginRun " << Phase::globalBeginRun << "\n"
304  << "# streamBeginRun " << Phase::streamBeginRun << "\n"
305  << "# globalBeginLumi " << Phase::globalBeginLumi << "\n"
306  << "# streamBeginLumi " << Phase::streamBeginLumi << "\n"
307  << "# Event " << Phase::Event << "\n"
308  << "# streamEndLumi " << Phase::streamEndLumi << "\n"
309  << "# globalEndLumi " << Phase::globalEndLumi << "\n"
310  << "# streamEndRun " << Phase::streamEndRun << "\n"
311  << "# globalEndRun " << Phase::globalEndRun << "\n";
312  oss << "# Step Symbol Entries\n"
313  << "# -------------------------- ------ ------------------------------------------\n"
314  << "# preSourceEvent " << step::preSourceEvent << " <Stream ID> <Time since beginJob (ms)>\n"
315  << "# postSourceEvent " << step::postSourceEvent << " <Stream ID> <Time since beginJob (ms)>\n"
316  << "# preEvent " << step::preEvent
317  << " <Stream ID> <Run#> <LumiBlock#> <Event#> <Time since beginJob (ms)>\n"
318  << "# postModuleEventPrefetching " << step::postModuleEventPrefetching
319  << " <Stream ID> <Module ID> <Time since beginJob (ms)>\n"
320  << "# preModuleEventAcquire " << step::preModuleEventAcquire
321  << " <Stream ID> <Module ID> <Time since beginJob (ms)>\n"
322  << "# postModuleEventAcquire " << step::postModuleEventAcquire
323  << " <Stream ID> <Module ID> <Time since beginJob (ms)>\n"
324  << "# preModuleTransition " << step::preModuleEvent
325  << " <Stream ID> <Module ID> <Transition type> <Time since beginJob (ms)>\n"
326  << "# preEventReadFromSource " << step::preEventReadFromSource
327  << " <Stream ID> <Module ID> <Time since beginJob (ms)>\n"
328  << "# postEventReadFromSource " << step::postEventReadFromSource
329  << " <Stream ID> <Module ID> <Time since beginJob (ms)>\n"
330  << "# postModuleTransition " << step::postModuleEvent
331  << " <Stream ID> <Module ID> <Transition type> <Time since beginJob (ms)>\n"
332  << "# postEvent " << step::postEvent
333  << " <Stream ID> <Run#> <LumiBlock#> <Event#> <Time since beginJob (ms)>\n";
334  file_.write(oss.str());
335  }
336 }
337 
340  desc.addUntracked<std::string>("fileName", filename_default)
341  ->setComment(
342  "Name of file to which detailed timing information should be written.\n"
343  "An empty filename argument (the default) indicates that no extra\n"
344  "information will be written to a dedicated file, but only the summary\n"
345  "including stalling-modules information will be logged.");
346  desc.addUntracked<double>("stallThreshold", threshold_default)
347  ->setComment(
348  "Threshold (in seconds) used to classify modules as stalled.\n"
349  "Microsecond granularity allowed.");
350  descriptions.add("StallMonitor", desc);
351  descriptions.setComment(
352  "This service keeps track of various times in event-processing to determine which modules are stalling.");
353 }
354 
356  // Module labels are dense, so if the module id is greater than the
357  // size of moduleLabels_, grow the vector to the correct index and
358  // assign the last entry to the desired label. Note that with the
359  // current implementation, there is no module with ID '0'. In
360  // principle, the module-information vectors are therefore each one
361  // entry too large. However, since removing the entry at the front
362  // makes for awkward indexing later on, and since the sizes of these
363  // extra entries are on the order of bytes, we will leave them in
364  // and skip over them later when printing out summaries. The
365  // extraneous entries can be identified by their module labels being
366  // empty.
367  auto const mid = md.id();
368  if (mid < moduleLabels_.size()) {
369  moduleLabels_[mid] = md.moduleLabel();
370  } else {
371  moduleLabels_.resize(mid + 1);
372  moduleLabels_.back() = md.moduleLabel();
373  }
374 }
375 
377  // Since a (push,emplace)_back cannot be called for a vector of a
378  // type containing atomics (like 'StallStatistics')--i.e. atomics
379  // have no copy/move-assignment operators, we must specify the size
380  // of the vector at construction time.
381  moduleStats_ = std::vector<StallStatistics>(moduleLabels_.size());
382  for (std::size_t i{}; i < moduleStats_.size(); ++i) {
383  moduleStats_[i].setLabel(moduleLabels_[i]);
384  }
385 
386  if (validFile_) {
387  std::size_t const width{std::to_string(moduleLabels_.size()).size()};
388 
389  OStreamColumn col0{"Module ID", width};
390  std::string const lastCol{"Module label"};
391 
392  std::ostringstream oss;
393  oss << "\n# " << col0 << space << lastCol << '\n';
394  oss << "# " << std::string(col0.width() + space.size() + lastCol.size(), '-') << '\n';
395 
396  for (std::size_t i{}; i < moduleLabels_.size(); ++i) {
397  auto const& label = moduleLabels_[i];
398  if (label.empty())
399  continue; // See comment in filling of moduleLabels_;
400  oss << "#M " << std::setw(width) << std::left << col0(i) << space << std::left << moduleLabels_[i] << '\n';
401  }
402  oss << '\n';
403  file_.write(oss.str());
404  }
405  // Don't need the labels anymore--info. is now part of the
406  // module-statistics objects.
407  moduleLabels_.clear();
408 
409  beginTime_ = now();
410 }
411 
413  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
414  auto msg = assembleMessage<step::preSourceEvent>(sid.value(), t);
415  file_.write(std::move(msg));
416 }
417 
419  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
420  auto msg = assembleMessage<step::postSourceEvent>(sid.value(), t);
421  file_.write(std::move(msg));
422 }
423 
425  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
426  auto const& eid = sc.eventID();
427  auto msg = assembleMessage<step::preEvent>(stream_id(sc), eid.run(), eid.luminosityBlock(), eid.event(), t);
428  file_.write(std::move(msg));
429 }
430 
432  auto const sid = stream_id(sc);
433  auto const mid = module_id(mcc);
434  auto start = stallStart_[std::make_pair(sid, mid)] = std::make_pair(now(), false);
435 
436  if (validFile_) {
437  auto const t = duration_cast<duration_t>(start.first - beginTime_).count();
438  auto msg = assembleMessage<step::postModuleEventPrefetching>(sid, mid, t);
439  file_.write(std::move(msg));
440  }
441 }
442 
444  auto const preModEventAcquire = now();
445  auto const sid = stream_id(sc);
446  auto const mid = module_id(mcc);
447  auto& start = stallStart_[std::make_pair(sid, mid)];
448  auto startT = start.first.time_since_epoch();
449  start.second = true; // record so the preModuleEvent knows that acquire was called
450  if (validFile_) {
451  auto t = duration_cast<duration_t>(preModEventAcquire - beginTime_).count();
452  auto msg = assembleMessage<step::preModuleEventAcquire>(sid, mid, t);
453  file_.write(std::move(msg));
454  }
455  // Check for stalls if prefetch was called
456  if (duration_t::duration::zero() != startT) {
457  auto const preFetch_to_preModEventAcquire = duration_cast<duration_t>(preModEventAcquire - start.first);
458  if (preFetch_to_preModEventAcquire < stallThreshold_)
459  return;
460  moduleStats_[mid].update(preFetch_to_preModEventAcquire);
461  }
462 }
463 
465  auto const postModEventAcquire = duration_cast<duration_t>(now() - beginTime_).count();
466  auto msg = assembleMessage<step::postModuleEventAcquire>(stream_id(sc), module_id(mcc), postModEventAcquire);
467  file_.write(std::move(msg));
468 }
469 
471  auto const preModEvent = now();
472  auto const sid = stream_id(sc);
473  auto const mid = module_id(mcc);
474  auto const& start = stallStart_[std::make_pair(sid, mid)];
475  auto startT = start.first.time_since_epoch();
476  if (validFile_) {
477  auto t = duration_cast<duration_t>(preModEvent - beginTime_).count();
478  auto msg =
479  assembleMessage<step::preModuleEvent>(sid, mid, static_cast<std::underlying_type_t<Phase>>(Phase::Event), t);
480  file_.write(std::move(msg));
481  }
482  // Check for stalls if prefetch was called and we did not already check before acquire
483  if (duration_t::duration::zero() != startT && !start.second) {
484  auto const preFetch_to_preModEvent = duration_cast<duration_t>(preModEvent - start.first);
485  if (preFetch_to_preModEvent < stallThreshold_)
486  return;
487  moduleStats_[mid].update(preFetch_to_preModEvent);
488  }
489 }
490 
492  auto const tNow = now();
493  auto const sid = stream_id(sc);
494  auto const mid = module_id(mcc);
495  auto t = duration_cast<duration_t>(tNow - beginTime_).count();
496  auto msg = assembleMessage<step::preModuleEvent>(sid, mid, toTransition(sc), t);
497  file_.write(std::move(msg));
498 }
499 
501  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
502  auto msg = assembleMessage<step::postModuleEvent>(stream_id(sc), module_id(mcc), toTransition(sc), t);
503  file_.write(std::move(msg));
504 }
505 
507  auto t = duration_cast<duration_t>(now() - beginTime_).count();
508  auto msg = assembleMessage<step::preModuleEvent>(numStreams_, module_id(mcc), toTransition(gc), t);
509  file_.write(std::move(msg));
510 }
511 
513  auto const postModTime = duration_cast<duration_t>(now() - beginTime_).count();
514  auto msg = assembleMessage<step::postModuleEvent>(numStreams_, module_id(mcc), toTransition(gc), postModTime);
515  file_.write(std::move(msg));
516 }
517 
519  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
520  auto msg = assembleMessage<step::preEventReadFromSource>(stream_id(sc), module_id(mcc), t);
521  file_.write(std::move(msg));
522 }
523 
525  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
526  auto msg = assembleMessage<step::postEventReadFromSource>(stream_id(sc), module_id(mcc), t);
527  file_.write(std::move(msg));
528 }
529 
531  auto const postModEvent = duration_cast<duration_t>(now() - beginTime_).count();
532  auto msg = assembleMessage<step::postModuleEvent>(
533  stream_id(sc), module_id(mcc), static_cast<std::underlying_type_t<Phase>>(Phase::Event), postModEvent);
534  file_.write(std::move(msg));
535 }
536 
538  auto const t = duration_cast<duration_t>(now() - beginTime_).count();
539  auto const& eid = sc.eventID();
540  auto msg = assembleMessage<step::postEvent>(stream_id(sc), eid.run(), eid.luminosityBlock(), eid.event(), t);
541  file_.write(std::move(msg));
542 }
543 
545  // Prepare summary
546  std::size_t width{};
547  edm::for_all(moduleStats_, [&width](auto const& stats) {
548  if (stats.numberOfStalls() == 0u)
549  return;
550  width = std::max(width, stats.label().size());
551  });
552 
553  OStreamColumn tag{"StallMonitor>"};
554  OStreamColumn col1{"Module label", width};
555  OStreamColumn col2{"# of stalls"};
556  OStreamColumn col3{"Total stalled time"};
557  OStreamColumn col4{"Max stalled time"};
558 
559  LogAbsolute out{"StallMonitor"};
560  out << '\n';
561  out << tag << space << col1 << space << col2 << space << col3 << space << col4 << '\n';
562 
563  out << tag << space << std::setfill('-') << col1(std::string{}) << space << col2(std::string{}) << space
564  << col3(std::string{}) << space << col4(std::string{}) << '\n';
565 
566  using seconds_d = duration<double>;
567 
568  auto to_seconds_str = [](auto const& duration) {
569  std::ostringstream oss;
570  auto const time = duration_cast<seconds_d>(duration).count();
571  oss << time << " s";
572  return oss.str();
573  };
574 
575  out << std::setfill(' ');
576  for (auto const& stats : moduleStats_) {
577  if (stats.label().empty() || // See comment in filling of moduleLabels_;
578  stats.numberOfStalls() == 0u)
579  continue;
580  out << std::left << tag << space << col1(stats.label()) << space << std::right << col2(stats.numberOfStalls())
581  << space << col3(to_seconds_str(stats.totalStalledTime())) << space
582  << col4(to_seconds_str(stats.maxStalledTime())) << '\n';
583  }
584 }
585 
size
Write out results.
Definition: start.py:1
T getUntrackedParameter(std::string const &, T const &) const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void preModuleEvent(StreamContext const &, ModuleCallingContext const &)
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void preSourceEvent(StreamID)
unique_ptr< ClusterSequence > cs
ThreadSafeOutputFileStream file_
void postEvent(StreamContext const &)
decltype(now()) beginTime_
Phase
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:188
std::string const & moduleLabel() const
void preModuleConstruction(edm::ModuleDescription const &)
void preModuleStreamTransition(StreamContext const &, ModuleCallingContext const &)
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:14
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:35
std::vector< std::string > moduleLabels_
char const * label
Transition transition() const
Definition: StreamContext.h:55
void postModuleEventPrefetching(StreamContext const &, ModuleCallingContext const &)
void preEventReadFromSource(StreamContext const &, ModuleCallingContext const &)
ModuleDescription const * moduleDescription() const
duration_t const stallThreshold_
void preEvent(StreamContext const &)
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:105
rep
Definition: cuy.py:1190
tbb::concurrent_unordered_map< std::pair< StreamID_value, ModuleID >, std::pair< decltype(beginTime_), bool > > stallStart_
StreamID const & streamID() const
Definition: StreamContext.h:54
void preModuleEventAcquire(StreamContext const &, ModuleCallingContext const &)
void setComment(std::string const &value)
void postModuleEventAcquire(StreamContext const &, ModuleCallingContext const &)
unsigned int value() const
Definition: StreamID.h:42
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void postEventReadFromSource(StreamContext const &, ModuleCallingContext const &)
void postModuleGlobalTransition(GlobalContext const &, ModuleCallingContext const &)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
tuple msg
Definition: mps_check.py:279
susybsm::MuonSegment ms
Definition: classes.h:31
double S(const TLorentzVector &, const TLorentzVector &)
Definition: Particle.cc:99
void postModuleStreamTransition(StreamContext const &, ModuleCallingContext const &)
void postSourceEvent(StreamID)
void postModuleEvent(StreamContext const &, ModuleCallingContext const &)
decltype(std::declval< StreamID >().value()) StreamID_value
Transition transition() const
Definition: GlobalContext.h:49
HLT enums.
#define update(a, b)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< StallStatistics > moduleStats_
EventID const & eventID() const
Definition: StreamContext.h:59
step
Definition: StallMonitor.cc:94
decltype(std::declval< ModuleDescription >().id()) ModuleID
long double T
def move(src, dest)
Definition: eostools.py:511
#define constexpr
void preModuleGlobalTransition(GlobalContext const &, ModuleCallingContext const &)
unsigned int id() const