CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Timing.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Services
4 // Class : Timing
5 //
6 // Implementation:
7 //
8 // Original Author: Jim Kowalkowski
9 //
10 // Change Log
11 //
12 // 1 - mf 4/22/08 Facilitate summary output to job report and logs:
13 // In Timing ctor, default for report_summary_ changed to true
14 // In postEndJob, add output to logger
15 //
16 // 2 - 2009/01/14 10:29:00, Natalia Garcia Nebot
17 // Modified the service to add some new measurements to report:
18 // - Average time per event (cpu and wallclock)
19 // - Fastest time per event (cpu and wallclock)
20 // - Slowest time per event (cpu and wallclock)
21 //
22 // 3 - mf 3/18/09 Change use of LogAbsolute to LogImportant
23 // so that users can throttle the messages
24 // for selected destinations. LogImportant
25 // is treated at the same level as LogError, so
26 // by default the behavior will not change, but
27 // there will now be a way to control the verbosity.
28 //
29 // 4 - mf 3/18/09 The per-event output TimeEvent is changed to LogPrint.
30 // The per-module output TimeModule is changed to LogPrint.
31 //
32 // 5 - wmtan 2010/03/16
33 // Fixed the constructor to initialize all data members!
34 // Standardized coding style
35 //
36 
47 
48 #include <iostream>
49 #include <sys/time.h>
50 #include <sys/resource.h>
51 #include <sstream>
52 
53 namespace edm {
54  namespace service {
55 
56  static std::string d2str(double d) {
57  std::stringstream t;
58  t << d;
59  return t.str();
60  }
61 
62  static double getTime() {
63  struct timeval t;
64  if(gettimeofday(&t, 0) < 0)
65  throw cms::Exception("SysCallFailed", "Failed call to gettimeofday");
66  return static_cast<double>(t.tv_sec) + (static_cast<double>(t.tv_usec) * 1E-6);
67  }
68 
69  static double getCPU() {
70  struct rusage usage;
71  getrusage(RUSAGE_SELF, &usage);
72 
73  double totalCPUTime = 0.0;
74  // User code
75  totalCPUTime = (double)usage.ru_utime.tv_sec + (double(usage.ru_utime.tv_usec) * 1E-6);
76  // System functions
77  totalCPUTime += (double)usage.ru_stime.tv_sec + (double(usage.ru_stime.tv_usec) * 1E-6);
78  return totalCPUTime;
79  }
80 
81  Timing::Timing(ParameterSet const& iPS, ActivityRegistry& iRegistry) :
82  curr_event_(),
83  curr_job_time_(0.),
84  curr_job_cpu_(0.),
85  curr_event_time_(0.),
86  curr_event_cpu_(0.),
87  curr_module_time_(0.),
88  total_event_cpu_(0.),
89  summary_only_(iPS.getUntrackedParameter<bool>("summaryOnly")),
90  report_summary_(iPS.getUntrackedParameter<bool>("useJobReport")),
91  max_event_time_(0.),
92  max_event_cpu_(0.),
93  min_event_time_(0.),
94  min_event_cpu_(0.),
95  total_event_count_(0) {
96  iRegistry.watchPostBeginJob(this, &Timing::postBeginJob);
97  iRegistry.watchPostEndJob(this, &Timing::postEndJob);
98 
101 
102  if (not summary_only_) {
103  iRegistry.watchPreModule(this, &Timing::preModule);
104  iRegistry.watchPostModule(this, &Timing::postModule);
105  }
106  }
107 
109  }
110 
113  desc.addUntracked<bool>("summaryOnly", false)->setComment(
114  "If 'true' do not report timing for each event");
115  desc.addUntracked<bool>("useJobReport", true)->setComment(
116  "If 'true' write summary information to JobReport");
117  descriptions.add("Timing", desc);
118  descriptions.setComment(
119  "This service reports the time it takes to run each module in a job.");
120  }
121 
124  curr_job_cpu_ = getCPU();
125  total_event_cpu_ = 0.0;
126 
127  //LogInfo("TimeReport")
128  if (not summary_only_) {
129  LogImportant("TimeReport") // ChangeLog 3
130  << "TimeReport> Report activated" << "\n"
131  << "TimeReport> Report columns headings for events: "
132  << "eventnum runnum timetaken\n"
133  << "TimeReport> Report columns headings for modules: "
134  << "eventnum runnum modulelabel modulename timetakeni\n"
135  << "TimeReport> JobTime=" << curr_job_time_ << " JobCPU=" << curr_job_cpu_ << "\n";
136  }
137  }
138 
140  double total_job_time = getTime() - curr_job_time_;
141  double average_event_time = total_job_time / total_event_count_;
142 
143  double total_job_cpu = getCPU() - curr_job_cpu_;
144  double average_event_cpu = total_event_cpu_ / total_event_count_;
145 
146  //LogAbsolute("FwkJob")
147  //LogAbsolute("TimeReport") // Changelog 1
148  LogImportant("TimeReport") // Changelog 3
149  << "TimeReport> Time report complete in "
150  << total_job_time << " seconds"
151  << "\n"
152  << " Time Summary: \n"
153  << " - Min event: " << min_event_time_ << "\n"
154  << " - Max event: " << max_event_time_ << "\n"
155  << " - Avg event: " << average_event_time << "\n"
156  << " - Total job: " << total_job_time << "\n"
157  << " CPU Summary: \n"
158  << " - Min event: " << min_event_cpu_ << "\n"
159  << " - Max event: " << max_event_cpu_ << "\n"
160  << " - Avg event: " << average_event_cpu << "\n"
161  << " - Total job: " << total_job_cpu << "\n"
162  << " - Total event: " << total_event_cpu_ << "\n";
163 
164  if (report_summary_) {
165  Service<JobReport> reportSvc;
166 // std::map<std::string, double> reportData;
167  std::map<std::string, std::string> reportData;
168 
169  reportData.insert(std::make_pair("MinEventTime", d2str(min_event_time_)));
170  reportData.insert(std::make_pair("MaxEventTime", d2str(max_event_time_)));
171  reportData.insert(std::make_pair("AvgEventTime", d2str(average_event_time)));
172  reportData.insert(std::make_pair("TotalJobTime", d2str(total_job_time)));
173  reportData.insert(std::make_pair("MinEventCPU", d2str(min_event_cpu_)));
174  reportData.insert(std::make_pair("MaxEventCPU", d2str(max_event_cpu_)));
175  reportData.insert(std::make_pair("AvgEventCPU", d2str(average_event_cpu)));
176  reportData.insert(std::make_pair("TotalJobCPU", d2str(total_job_cpu)));
177  reportData.insert(std::make_pair("TotalEventCPU", d2str(total_event_cpu_)));
178 
179  reportSvc->reportPerformanceSummary("Timing", reportData);
180 // reportSvc->reportTimingInfo(reportData);
181  }
182  }
183 
184  void Timing::preEventProcessing(EventID const& iID, Timestamp const& iTime) {
185  curr_event_ = iID;
188  }
189 
193 
195 
196  if (not summary_only_) {
197  LogPrint("TimeEvent") // ChangeLog 3
198  << "TimeEvent> "
199  << curr_event_.event() << " "
200  << curr_event_.run() << " "
201  << curr_event_time_ << " "
202  << curr_event_cpu_ << " "
203  << total_event_cpu_;
204  }
205  if (total_event_count_ == 0) {
210  }
211 
217  }
218 
221  }
222 
224  double t = getTime() - curr_module_time_;
225  //LogInfo("TimeModule")
226  if (not summary_only_) {
227  LogPrint("TimeModule") << "TimeModule> " // ChangeLog 4
228  << curr_event_.event() << " "
229  << curr_event_.run() << " "
230  << desc.moduleLabel() << " "
231  << desc.moduleName() << " "
232  << t;
233  }
234 
235  }
236  }
237 }
238 
RunNumber_t run() const
Definition: EventID.h:42
EventNumber_t event() const
Definition: EventID.h:44
double curr_job_time_
Definition: Timing.h:53
double max_event_time_
Definition: Timing.h:65
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool report_summary_
Definition: Timing.h:60
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
double curr_event_cpu_
Definition: Timing.h:56
void watchPostModule(PostModule::slot_type const &iSlot)
void watchPreProcessEvent(PreProcessEvent::slot_type const &iSlot)
static double getCPU()
Definition: Timing.cc:69
std::string const & moduleName() const
double curr_job_cpu_
Definition: Timing.h:54
void preModule(ModuleDescription const &)
Definition: Timing.cc:219
std::string const & moduleLabel() const
void watchPreModule(PreModule::slot_type const &iSlot)
EventID curr_event_
Definition: Timing.h:52
void watchPostProcessEvent(PostProcessEvent::slot_type const &iSlot)
double curr_module_time_
Definition: Timing.h:57
Timing(ParameterSet const &, ActivityRegistry &)
Definition: Timing.cc:81
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: Timing.cc:111
void postModule(ModuleDescription const &)
Definition: Timing.cc:223
double max_event_cpu_
Definition: Timing.h:66
double total_event_cpu_
Definition: Timing.h:58
void setComment(std::string const &value)
int total_event_count_
Definition: Timing.h:69
static std::string d2str(double d)
Definition: Memory.cc:57
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double min_event_cpu_
Definition: Timing.h:68
static double getTime()
void preEventProcessing(EventID const &, Timestamp const &)
Definition: Timing.cc:184
void postEventProcessing(Event const &, EventSetup const &)
Definition: Timing.cc:190
double min_event_time_
Definition: Timing.h:67
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
double curr_event_time_
Definition: Timing.h:55